Java 如何在Jackson中创建自定义泛型反序列化器?

Java 如何在Jackson中创建自定义泛型反序列化器?,java,enums,jackson,Java,Enums,Jackson,我希望在Jackson中为Enum类的集合创建一个自定义反序列化器。因为自定义反序列化器的行为对于所有枚举都是相同的。我想为我的所有枚举类创建公共反序列化程序 我尝试按如下方式进行常规自定义反序列化: class MyEnumDeserialize<T> extends JsonDeserializer<T> { private Class beanClass; public MyEnumDeserialize() { }

我希望在Jackson中为Enum类的集合创建一个自定义反序列化器。因为自定义反序列化器的行为对于所有枚举都是相同的。我想为我的所有枚举类创建公共反序列化程序

我尝试按如下方式进行常规自定义反序列化:

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;
    }
}
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;
    
类MyEnumDeserialize扩展JsonDeserializer{
私家班beanClass;
公共MyEnumDeserialize(){
}
公共MyEnumDeserialize(beanClass类){
this.beanClass=beanClass;
}
@凌驾
公共T反序列化(JsonParser JsonParser,DeserializationContext DeserializationContext)引发IOException{
TreeNode节点=jsonParser.getCodec().readTree(jsonParser);
T type=null;
试一试{
if(node.get(“attr”)!=null){
//我不知道如何在这里调用ENUM静态方法,因为这里没有上下文信息
if(type!=null){
返回类型;
}
}
}捕获(例外e){
type=null;
}
返回null;
}
}
问题是我想在反序列化程序中调用枚举静态方法,但由于没有任何可用的类/枚举上下文信息,因此无法执行此操作。

你能帮我知道我怎样才能做到这一点吗。

我设法使以下解决方案奏效:

我创建了一个模块并修改了EnumDeserializer,如下所示:

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;
    }
}
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;
    
module.setDeserializerModifier(新的BeanDeserializerModifier()
{
@重写公共JsonDeserializer modifyEnumDeserializer(反序列化配置,
JavaType类型、BeanDescription beanDesc、JsonDeserializer反序列化程序)
{
if(beanDesc.getBeanClass().isEnum()){
返回新的MyEnumDeserialize(beanDesc.getBeanClass());
}
返回反序列化器;
}
});
类MyEnumDeserialize扩展JsonDeserializer{
私家班beanClass;
公共MyEnumDeserialize(){
}
公共MyEnumDeserialize(beanClass类){
this.beanClass=beanClass;
}
@凌驾
公共T反序列化(JsonParser JsonParser,DeserializationContext DeserializationContext)引发IOException{
TreeNode节点=jsonParser.getCodec().readTree(jsonParser);
T type=null;
试一试{
if(node.isValueNode()){
ValueNode ValueNode=(ValueNode)节点;
Method=this.beanClass.getDeclaredMethod(“get”,简称.class);
type=(T)method.invoke(null,Short.parseShort(valueNode.astex());
if(type!=null){
返回类型;
}
}
}捕获(例外e){
type=null;
}
返回类型;
} }


尽管现在,我无法提供严格的类型检查(使用“”创建实例)。

此反序列化程序是否应仅处理枚举,因此不应是某个枚举?JSON的小示例也会很有帮助。@pirho Yes T应是某个枚举。实际上,我的应用程序中有流。在一个流中,我接收ENUM的整数值,在另一个流中,我接收ENUM的字符串名称。我有大约10个枚举类,所以试图创建自定义泛型序列化程序和反序列化程序。@pirho让我们假设我现在有两个枚举类(StudentType和StudentUniform)。我可能会收到以下JSON{“studentType”:“10”,“studentUniform”:“1”}。@pirho我设法找到了一个解决方案。你能复习一下吗