定制jackson解串器获取当前现场类
我正在尝试为jackson编写一个自定义反序列化器,我想让它成为通用的(在任何类型的工作意义上都是通用的,而不是在“generics”中)。
但是我似乎无法弄清楚如何处理被反序列化的字段类型。
例如,我正在寻找以下内容:
@Override public MyObject deserialize(JsonParser jp, DeserializationContext ctxt) throws IOException, JsonProcessingException { Class c = // do something with that type return new SubclassOfC(somedata based on c); }
这是我一直在努力的当前领域部分的获取类型 。
编辑:这是我感兴趣的java字段的类型。
您没有 – 反序列化器按类型注册,因此您需要构造反序列化器以了解反序列化的类型。
如果您确实想要注册通用反序列化器,则可以通过实现ContextualDeserializer
使事物更具动态性。 它的createContextual()
方法是使用BeanProperty
参数调用的,您可以检查属性的名称(如果属性未引用的根值,则可以为null)和类型(声明的类型)。 然后,此方法可以返回一个新实例(不要修改原始反序列化器,因为它由所有属性共享),配置了您需要的所有额外信息。
我通过向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));
这将返回为每个单独的枚举类型实例化的自定义EnumDeserializer。
粗略地说,无一例外地捕获和错误检查……
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; } } } }
我这样解决了。
获取当前字段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; }