至少有两种方法可以实现这一点:
1) 使用JsonDeserializer的Gson
在您的代码中进行小更改:
Type listType = new TypeToken<List<Scorefactor>>() {}.getType();
List<Scorefactor> scorefactors = new GsonBuilder()
.registerTypeAdapter(ZonedDateTime.class, GsonHelper.ZDT_DESERIALIZER)
.create()
.fromJson(output, listType);
助手类
class GsonHelper {
public static final JsonDeserializer<ZonedDateTime> ZDT_DESERIALIZER = new JsonDeserializer<ZonedDateTime>() {
@Override
public ZonedDateTime deserialize(final JsonElement json, final Type typeOfT, final JsonDeserializationContext context) throws JsonParseException {
JsonPrimitive jsonPrimitive = json.getAsJsonPrimitive();
try {
if(jsonPrimitive.isString()){
return ZonedDateTime.parse(jsonPrimitive.getAsString(), DateTimeFormatter.ISO_ZONED_DATE_TIME);
}
if(jsonPrimitive.isNumber()){
return ZonedDateTime.ofInstant(Instant.ofEpochMilli(jsonPrimitive.getAsLong()), ZoneId.systemDefault());
}
} catch(RuntimeException e){
throw new JsonParseException("Unable to parse ZonedDateTime", e);
}
throw new JsonParseException("Unable to parse ZonedDateTime");
}
};
}
2) 使用MessageBodyReader和XMLAdapter
客户端实现的更改:
ClientConfig config = new DefaultClientConfig();
config.getFeatures().put(JSONConfiguration.FEATURE_POJO_MAPPING, Boolean.TRUE);
Client client = Client.create(config);
List<Scorefactor> result = client.resource("http://localhost:8080/adap/api/getScoreFactor"")
.accept("application/json")
.get(ClientResponse.class)
.getEntity(new GenericType<List<Scorefactor>>(){});
System.out.println(result);
您可能需要导入jersey-json来实现此功能。
<dependency>
<groupId>com.sun.jersey</groupId>
<artifactId>jersey-bundle</artifactId>
<version>1.19.1</version>
</dependency>
<dependency>
<groupId>com.sun.jersey</groupId>
<artifactId>jersey-json</artifactId>
<version>1.19.1</version>
</dependency>
顺便问一下,为什么你使用1.*版本?
您的得分因素。
@XmlRootElement
@XmlAccessorType(XmlAccessType.FIELD)
public class Scorefactor implements Serializable {
@Column(name = "lastmodifieddate")
@XmlElement(name = "lastmodifieddate")
@XmlJavaTypeAdapter(ZonedDateTimeToStringXmlAdapter.class)
private ZonedDateTime lastmodifieddate;
ZonedDateTime从/到字符串(推荐)
public class ZonedDateTimeToStringXmlAdapter extends XmlAdapter<String, ZonedDateTime> {
@Override
public ZonedDateTime unmarshal(final String v) throws DateTimeParseException {
return ZonedDateTime.parse(v);
}
@Override
public String marshal(final ZonedDateTime v) throws Exception {
return v.toString();
}
}
从 Long 转换为 ZonedDateTime
public class ZonedDateTimeToLongXmlAdapter extends XmlAdapter<Long, ZonedDateTime> {
@Override
public ZonedDateTime unmarshal(final Long v) throws DateTimeParseException {
return ZonedDateTime.ofInstant(Instant.ofEpochMilli(v.longValue()), ZoneId.systemDefault());
}
@Override
public Long marshal(final ZonedDateTime v) throws Exception {
return Long.valueOf(v.toInstant().toEpochMilli());
}
}
您也可以构建自己的MessageBodyReader/MessageBodyWriter,或使用其他实现,如Moxy。
我建议使用Jersey 2.*。
希望这些对您有所帮助。祝您拥有愉快的一天。