杰克逊数据绑定枚举不区分大小写 [英] Jackson databind enum case insensitive

查看:307
本文介绍了杰克逊数据绑定枚举不区分大小写的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

如何反序列化包含不区分大小写的枚举值的JSON字符串? (使用Jackson Databind)



JSON字符串:

  [{ url:foo,type:json}] 

和我的Java POJO :

  public static class Endpoint {

public enum DataType {
JSON,HTML
}

public String url;
public DataType type;

public Endpoint(){

}

}

在这种情况下,使用类型反序列化JSON:json将失败,因为类型:JSON将工作。
但是我想要json为命名约定原因工作。



序列化POJO也导致大写type:JSON



我以为使用 @JsonCreator 和@JsonGetter:

  @JsonCreator 
private Endpoint(@JsonProperty( name)String url,@JsonProperty(type)String type){
this.url = url;
this.type = DataType.valueOf(type.toUpperCase());
}

// ....
@JsonGetter
private String getType(){
return type.name()。toLowerCase();
}

它的工作。但我想知道是否有更好的解决方案,因为这看起来像是对我的一个黑客。



我也可以编写一个自定义的解串器,但是我有很多不同的使用枚举的POJO,这将很难维护。



/ p>

我不希望我的java中的枚举是小写的!



这是我使用的一些测试代码:

  String data =[{\url\:\foo\,\type\:\json\}] 
Endpoint [] arr = new ObjectMapper()。readValue(data,Endpoint []。class);
System.out.println(POJO [] - >+ Arrays.toString(arr));
System.out.println(JSON - >+ new ObjectMapper()。writeValueAsString(arr));


解决方案

在2.4.0版本中,您可以注册一个自定义序列化程序对于所有枚举类型(链接到github问题)。此外,您可以自行替换将要了解的Enum类型的标准Enum解串器。这是一个例子:

  public class JacksonEnum {

public static enum DataType {
JSON,HTML
}

public static void main(String [] args)throws IOException {
列表< DataType> types = Arrays.asList(JSON,HTML);
ObjectMapper mapper = new ObjectMapper();
SimpleModule module = new SimpleModule();
module.setDeserializerModifier(new BeanDeserializerModifier(){
@Override
public JsonDeserializer&Enum> modifyEnumDeserializer(DeserializationConfig config,
final JavaType type,
BeanDescription beanDesc,
final JsonDeserializer<?> deserializer){
return new JsonDeserializer< Enum>(){
@Override
public Enum deserialize(JsonParser jp,DeserializationContext ctxt)throws IOException {
类<?extends Enum> rawClass =(Class&Enum<?>)type.getRawClass();
返回Enum.valueOf(rawClass,jp.getValueAsString()。toUpperCase());
}
};
}
});
module.addSerializer(Enum.class,new StdSerializer&Enum>(Enum.class){
@Override
public void serialize(枚举值,JsonGenerator jgen,SerializerProvider provider)throws IOException {
jgen.writeString(value.name()。toLowerCase());
}
});
mapper.registerModule(module);
String json = mapper.writeValueAsString(types);
System.out.println(json);
列表< DataType> types2 = mapper.readValue(json,new TypeReference< List< DataType>>(){});
System.out.println(types2);
}
}

输出:

  [json,html] 
[JSON,HTML]


How can I deserialize JSON string that contains enum values that are case insensitive? (using Jackson Databind)

The JSON string:

[{"url": "foo", "type": "json"}]

and my Java POJO:

public static class Endpoint {

    public enum DataType {
        JSON, HTML
    }

    public String url;
    public DataType type;

    public Endpoint() {

    }

}

in this case,deserializing the JSON with "type":"json" would fail where as "type":"JSON" would work. But I want "json" to work as well for naming convention reasons.

Serializing the POJO also results in upper case "type":"JSON"

I thought of using @JsonCreator and @JsonGetter:

    @JsonCreator
    private Endpoint(@JsonProperty("name") String url, @JsonProperty("type") String type) {
        this.url = url;
        this.type = DataType.valueOf(type.toUpperCase());
    }

    //....
    @JsonGetter
    private String getType() {
        return type.name().toLowerCase();
    }

And it worked. But I was wondering whether there's a better solutuon because this looks like a hack to me.

I can also write a custom deserializer but I got many different POJOs that use enums and it would be hard to maintain.

Can anyone suggest a better way to serialize and deserialize enums with proper naming convention?

I don't want my enums in java to be lowercase!

Here is some test code that I used:

    String data = "[{\"url\":\"foo\", \"type\":\"json\"}]";
    Endpoint[] arr = new ObjectMapper().readValue(data, Endpoint[].class);
        System.out.println("POJO[]->" + Arrays.toString(arr));
        System.out.println("JSON ->" + new ObjectMapper().writeValueAsString(arr));

解决方案

In version 2.4.0 you can register a custom serializer for all the Enum types (link to the github issue). Also you can replace the standard Enum deserializer on your own that will be aware about the Enum type. Here is an example:

public class JacksonEnum {

    public static enum DataType {
        JSON, HTML
    }

    public static void main(String[] args) throws IOException {
        List<DataType> types = Arrays.asList(JSON, HTML);
        ObjectMapper mapper = new ObjectMapper();
        SimpleModule module = new SimpleModule();
        module.setDeserializerModifier(new BeanDeserializerModifier() {
            @Override
            public JsonDeserializer<Enum> modifyEnumDeserializer(DeserializationConfig config,
                                                              final JavaType type,
                                                              BeanDescription beanDesc,
                                                              final JsonDeserializer<?> deserializer) {
                return new JsonDeserializer<Enum>() {
                    @Override
                    public Enum deserialize(JsonParser jp, DeserializationContext ctxt) throws IOException {
                        Class<? extends Enum> rawClass = (Class<Enum<?>>) type.getRawClass();
                        return Enum.valueOf(rawClass, jp.getValueAsString().toUpperCase());
                    }
                };
            }
        });
        module.addSerializer(Enum.class, new StdSerializer<Enum>(Enum.class) {
            @Override
            public void serialize(Enum value, JsonGenerator jgen, SerializerProvider provider) throws IOException {
                jgen.writeString(value.name().toLowerCase());
            }
        });
        mapper.registerModule(module);
        String json = mapper.writeValueAsString(types);
        System.out.println(json);
        List<DataType> types2 = mapper.readValue(json, new TypeReference<List<DataType>>() {});
        System.out.println(types2);
    }
}

Output:

["json","html"]
[JSON, HTML]

这篇关于杰克逊数据绑定枚举不区分大小写的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆