我正在尝试为杰克逊编写一个自定义反序列化程序,我想让它变得通用(在任何类型的意义上都是通用的,而不是在“泛型”中)。
但是我似乎无法弄清楚如何处理被反序列化的字段的类型。
例如,我正在寻找以下内容:
@Override
public MyObject deserialize(JsonParser jp, DeserializationContext ctxt) throws IOException, JsonProcessingException {
Class c = <get type of current field>
// do something with that type
return new SubclassOfC(somedata based on c);
}
具体是获取当前字段的类型部分,我一直在努力。
编辑:这是我感兴趣的java字段的类型。
答案 0 :(得分:3)
您没有 - 反序列化器按类型注册,因此您需要构建反序列化器以了解预期反序列化的类型。
如果您确实想要注册通用反序列化器,则可以通过实现ContextualDeserializer
来使事物更具动态性。使用createContextual()
参数调用其BeanProperty
方法,您可以检查属性名称(如果属性未引用的根值,则可能为null)和类型(是声明的类型)。
然后,此方法可以返回一个新实例(不要修改原始反序列化器,因为它由所有属性共享),并配置了您需要的所有额外信息。
答案 1 :(得分:2)
我通过向ObjectMapper添加反序列化器的实现来解决我的特殊问题。例如
Deserializers d = new Deserializers.Base() {
@Override
public JsonDeserializer<?> findEnumDeserializer(Class<?> type, DeserializationConfig config, BeanDescription beanDesc, BeanProperty property)
throws JsonMappingException {
if (property.getType().getContentType() != null)
return new EnumDeserializer(property.getType().getContentType().getRawClass());
return new EnumDeserializer(property.getType().getRawClass());
}
};
mapper.setDeserializerProvider(mapper.getDeserializerProvider().withAdditionalDeserializers(d));
这将返回为每个单独的Enum类型实例化的自定义EnumDeserializer。
答案 2 :(得分:0)
粗略地说,无一例外地捕捉和错误检查......
JsonToken tok = jp.nextValue();
Field field = findField(jp.getCurrentName());
Class<?> fc = field.getType();
if(fc == int.class) {
field.setInt(this, jp.getIntValue());
} // handle all the primitive types and String in the same way, then...
} ... else if(tok == JsonToken.START_ARRAY) {
if(fc.isArray()) {
// Load into an array
} else if(Collection.class.isAssignableFrom(fc)) {
// Load into a collection
} else {
// throw
}
} else if(tok == JsonToken.START_OBJECT) {
// Recursively create that object from the JSON stream
}
...并循环直到tok
为END_OBJECT。要按名称查找当前类:
Field findField(String name) {
for(Class<?> c = getClass(); c != null; c = c.getSuperclass()) {
for(Field field : c.getDeclaredFields()) {
if(field.getName().equals(name)) {
return field;
}
}
}
}
答案 3 :(得分:0)
我这样解决了。
获取当前字段java类型...
@Override
public Enum deserialize(JsonParser jsonparser, DeserializationContext context) throws IOException, JsonProcessingException {
System.out.println("EnumDeserializer ....");
Field field = findField(jsonparser.getCurrentName(), jsonparser.getCurrentValue().getClass());
Class<?> javaType = field.getType();
return null;
}
public Field findField(String name, Class<?> c) {
for (; c != null; c = c.getSuperclass()) {
for (Field field : c.getDeclaredFields()) {
if (Modifier.isStatic(field.getModifiers())) {
continue;
}
if (field.getName().equals(name)) {
return field;
}
}
}
return null;
}