我在建模服务器响应时遇到问题,其中一些看起来像这样:
{
"_links":{
"self":{
"href":"http:\/\/example.com"
}
},
"_embedded":{
"category":{
<...data...>
}
}
}
或
{
"_links":{
"self":{
"href":"http:\/\/example.com"
}
},
"_embedded":{
"episodes":[
<...list_data...>
]
}
}
似乎&#34; _embedded&#34; property只有一个JSON对象,该对象只有一个属性(用不同的名称命名)和实际数据。
我想创建一些通用的POJO类来支持这类响应,例如:
public abstract class EmbeddedResponse<T> {
@JsonProperty("_embedded")
private T embedded;
public T getEmbedded() {
return embedded;
}
... <other_members> ...
}
public class CategoriesResponse extends EmbeddedResponse<List<Category>> {
}
调用&#39; getEmbedded()&#39;将返回类别列表(或剧集或任何内容)。
我现在正在使用自定义反序列化,但是没有太大的成功,我想保持代码库最小化。
答案 0 :(得分:0)
解决方案,抽象POJO类:
public class EmbeddedResponse<T> {
@JsonProperty("_embedded")
@JsonDeserialize( using = EmbeddedResponseDeserializer.class )
private T embedded;
public T getEmbedded() {
return embedded;
}
}
POJO的实际回复:
public class CategoriesResponse extends EmbeddedResponse<List<Category>> {
}
有问题的JSON的反序列化器:
public class EmbeddedResponseDeserializer extends JsonDeserializer<Object> implements ContextualDeserializer {
private JavaType javaType;
@Override
public Object deserialize( JsonParser jsonParser, DeserializationContext ctxt ) throws IOException {
ObjectCodec objectCodec = jsonParser.getCodec();
JsonNode node = objectCodec.readTree(jsonParser);
// Get first it might require correction
String fieldName = node.fieldNames().next();
JsonNode skippedNode = node.get( fieldName );
return objectCodec.readValue( skippedNode.traverse(), javaType );
}
@Override
public JsonDeserializer<?> createContextual( DeserializationContext ctxt, BeanProperty property ) throws JsonMappingException {
javaType = property.getType();
return this;
}
}
可能需要更多的tweek,但此时此解决方案正在运行
答案 1 :(得分:-1)
在建模对象时,我会使用Java 8 Optional对象。通过这种方式,您可以获得灵活的模型和良好的编程模型。使用ifPresent-method。
因此,根类可以按照以下方式建模:
public class Response {
private Embedded embedded;
private Links links;
@JsonCreator
public Response(
@JsonProperty("_links") final Links links,
@JsonProperty("_embedded") final Embedded embedded) {
this.links = links;
this.embedded = embedded;
}
public Embedded embedded() {
return embedded;
}
public Links links() {
return links;
}
}
定义嵌入内容的对象(即类别或剧集)可以这样建模:
public class Embedded {
private final Category category;
private final List<Episode> episodes;
@JsonCreator
public Embedded(
@JsonProperty("episodes") final List<Episode> episodes,
@JsonProperty("category") final Category category) {
this.episodes = episodes;
this.category = category;
}
public Optional<Category> category() {
return Optional.ofNullable(category);
}
public Optional<List<Episode>> episodes() {
return Optional.ofNullable(episodes);
}
}
对这些对象进行编程时,可以使用以下模式:
final InputStream resource = ...; // retrieve a stream somehow
// Map the stream to the response object
final Response response = new ObjectMapper().readValue(resource, Response.class);
// Use the Optional-style for processing category data
response.embedded().category().ifPresent(category -> {
// do category stuff with the Category-object
});
// Once more, use the Optional-style - this time for processing episodes data
response.embedded().episodes().ifPresent(episodes -> {
// do episodes stuff with the List of Episodes
});