考虑一个类型为“服装”的json:
{
"id":"123",
"version":2,
"apparel":{
"category":[
{
"id":"a1",
"style":"top",
"comments":[
{
"header":{
"type":"apparel.detail.Summary",
"major_version":1,
"minor_version":0
},
"summary": "notes"
}]
}
]
},
"accessories":[
{
"header":{
"type":"accessories.detail.Handbag",
"major_version":1,
"minor_version":0
},
"details":{
"brand":"Gucci",
"sno.":"G12"
},
"color":"Red",
},
{
"header":{
"type":"accessories.detail.Hat",
"major_version":1,
"minor_version":0
},
"details":{
"brand":"Adidas",
"sno.":"A12"
}
}
]
}
我无法访问“服装”,我无法添加任何字段级别或类级别的json注释。 json中有一个属性“header”,可以帮助我确定要将该实体转换为的类的类型。一旦确定了类类型,我将从json中删除标题(因为标头未在我的目标类类型中定义,因为反序列化将失败)
我需要编写一个返回泛型类类型对象的自定义反序列化器。它将检查是否有标头,获取目标类名,删除标头并将其反序列化为获取的目标类并返回。
这是我编写的代码,但它不起作用,我甚至不确定是否可以在SimpleModule中注入一个带有泛型返回类型的自定义反序列化器。
@Singleton
@Provides
private Transformer provideTransformer(final HeaderDeserializer headerDeserializer) {
final SimpleModule simpleModule = new SimpleModule();
simpleModule.addDeserializer(Object.class, headerDeserializer);
mapper.registerModule(simpleModule);
}
@Singleton
@Provides
private HeaderDeserializer provideHeaderDeserializer(final ObjectMapper objectMapper) {
return new HeaderDeserializer(objectMapper);
}
@Singleton
@Provides
private ObjectMapper provideObjectMapper() {
final ObjectMapper mapper = new ObjectMapper()
// Tell object mapper how to handle joda-time.
.registerModule(new JodaModule())
// include non-null values only
.setSerializationInclusion(Include.NON_NULL)
// ensures that timezone is preserved
.disable(DeserializationFeature.ADJUST_DATES_TO_CONTEXT_TIME_ZONE);
return mapper;
}
My HeaderDeserializer看起来像这样:
public class HeaderDeserializer<T> extends StdDeserializer<T> {
private static final long serialVersionUID = 1L;
private final ObjectMapper mapper;
public HeaderDeserializer(final ObjectMapper mapper) {
this(null, mapper);
}
public HeaderDeserializer(final Class<?> vc, final ObjectMapper mapper) {
super(vc);
this.mapper = mapper;
}
@Override
public T deserialize(final JsonParser jp, final DeserializationContext ctx) {
Object value = null;
try {
JsonNode node = this.mapper.readTree(jp);
JsonNode header = node.get("header");
if (node.has("header")) {
String targetClass = header.get("type").textValue();
removeHeaderFromJsonDoc(node);
value = this.mapper.readValue(jp, Class.forName(targetClass));
}
} catch (final IOException e) {
throw new UncheckedIOException(e);
} catch (final ClassNotFoundException e) {
// do somehting
}
return (T) value;
}
private void removeHeaderFromJsonDoc(final JsonNode document) {
final Iterator<Entry<String, JsonNode>> itr = document.fields();
while (itr.hasNext()) {
final Entry<String, JsonNode> childNodeEntry = itr.next();
if (childNodeEntry.getKey().equals("header")) {
itr.remove();
}
}
}
}
我将使用上面定义的自定义反序列化器的主反序列化器如下所示:
public final Clothing deserialize(
final String stringValue,
final Class<? extends Clothing> clazz) {
try {
return this.objectMapper.readValue(stringValue, clazz);
} catch (final IOException e) {
throw new IllegalArgumentException();
}
}
答案 0 :(得分:0)
this.objectMapper.readValue(stringValue, clazz);
类型的&#39; clazz&#39;在这个readValue方法中应该匹配在simpleModule.addDeserializer中传递的类类型。
它不会进入您的反序列化器,因为您要将解串器添加到SimpleModule中以用于&#39;对象&#39;不同类的班级和阅读价值传递给&#39;服装反序列化&#39;,