简体   繁体   中英

How to create custom Generic deserializer in Jackson?

I am looking to create a custom Deserializer in Jackson for set of Enum class. Since the behaviour of custom deserializer would be same for all enum. I want to make common Deserializer for all my enum class.

I tried making generic custom deserialize as follow:

class MyEnumDeserialize<T> extends JsonDeserializer<T> {

    private Class beanClass;
    public MyEnumDeserialize() {
        
    }
    
    public MyEnumDeserialize(Class beanClass) {
        this.beanClass = beanClass;
    }
    @Override
    public T deserialize(JsonParser jsonParser, DeserializationContext deserializationContext) throws IOException {
        TreeNode node = jsonParser.getCodec().readTree(jsonParser);
        T type = null;
        try{
            if(node.get("attr") != null){
               // I don't know how to call ENUM static method here as I don't have context information here
                if (type != null) {
                    return type;
                }
            }
        }catch(Exception e){
            type = null;
        }
        return null;
    }
}

The problem is I want to call Enum static method inside the deserializer but unable to do so since I don't have any class/enum context information available.
Could you please help me know how could I achieve it.

I somehow managed to make following solution worked:

I created a module and modify EnumDeserializer as follow:

module.setDeserializerModifier(new BeanDeserializerModifier()
        {
          @Override public JsonDeserializer<?>  modifyEnumDeserializer(DeserializationConfig config,
                  JavaType type, BeanDescription beanDesc, JsonDeserializer<?> deserializer)
          {
             
            if (beanDesc.getBeanClass().isEnum()) {
                 return new MyEnumDeserialize<>(beanDesc.getBeanClass());
            }
            return deserializer;
          }
        });

class MyEnumDeserialize<T extends Enum> extends JsonDeserializer<T> {

    private Class beanClass;
    public MyEnumDeserialize() {
        
    }
    
    public MyEnumDeserialize(Class beanClass) {
        this.beanClass = beanClass; 
    }
    @Override
    public T deserialize(JsonParser jsonParser, DeserializationContext deserializationContext) throws IOException {
        TreeNode node = jsonParser.getCodec().readTree(jsonParser);
        T type = null;
        try{
            if(node.isValueNode()){
                ValueNode valueNode = (ValueNode)node;
                Method method = this.beanClass.getDeclaredMethod("get",short.class);
                type = (T)method.invoke(null, Short.parseShort(valueNode.asText()));
                if (type != null) {
                    return type;
                }
            }
        }catch(Exception e){
            type = null;
        }
        return type;
    

} }

Though now, I am unable to provide Strict type checking ( creating instance with "<>").

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM