当前位置: 首页 > 面试题库 >

Jackson Databind枚举不区分大小写

范翰飞
2023-03-14
问题内容

如何反序列化包含不区分大小写的枚举值的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反序列化"type":"json"将在"type":"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();
    }

而且有效。但是我想知道是否有更好的解决方案,因为这对我来说似乎是hack。

我也可以编写一个自定义的反序列化器,但是我有许多使用枚举的POJO,很难维护。

有人可以建议一种使用正确的命名约定对枚举进行序列化和反序列化的更好方法吗?

我不希望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版中,您可以为所有Enum类型注册自定义序列化程序(链接到github问题)。您也可以自己替换将了解Enum类型的标准Enum解串器。这是一个例子:

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);
    }
}

输出:

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


 类似资料:
  • 我正在构建一个Spring Boot REST API。它有一个POST请求,用于将大型对象保存到Mongo数据库。我试图使用枚举来控制数据存储方式的一致性。例如,这是我对象的一部分: 我的问题:当我传入一个不是我的枚举的大写版本的值(例如“mobile”或“Mobile”)时,我得到以下错误: 我觉得应该有一种相对简单的方法来获取传递到API中的内容,将其转换为大写字母,将其与枚举进行比较,如果

  • 枚举 场域 Application.Properties(小写)

  • 问题内容: 如果我像这样在Spring控制器中有一个RequestMapping … 产品是一个枚举。例如。产品首页 当我请求页面时,mysite.com / home 我懂了 有没有办法让枚举类型转换器理解小写的home实际上是Home? 我想保持url大小写不敏感,并且我的Java枚举使用标准大写字母。 谢谢 解 注册 添加到需要特殊转换的控制器 问题答案: 概括地说,您想创建一个新的Prop

  • 我试图重写/实现JSR311中的所有属性,但Jersey绑定似乎区分大小写: 做一个原始类型 有一个接受单个String参数的构造函数 有一个静态方法命名为value eOf或from mString,它接受单个String参数(例如,参见Integer.valueOf(String)) 是List、Set或sortedSet,其中T满足上面的2或3。生成的集合是只读的。 如何使枚举的泽西绑定不区

  • 对于报告(0.1%的所有查询),我需要返回一个所有可能类别的列表,区分大小写! 考虑以下文件: 运行以下查询: 返回: 是否有方法返回区分大小写的类别(存储在文档中)?我对此查询结果中的感兴趣。 Elasticsearch论坛中的问题 谢谢,伊泰