java - jackson 数据绑定(bind)枚举不区分大小写

标签 java json serialization enums jackson

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

JSON 字符串:

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

还有我的 Java POJO:

public static class Endpoint {

    public enum DataType {
        JSON, HTML
    }

    public String url;
    public DataType type;

    public Endpoint() {

    }

}

在这种情况下,使用 "type":"json" 反序列化 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();
    }

它奏效了。但我想知道是否有更好的解决方案,因为这对我来说就像一个黑客。

我也可以编写一个自定义的反序列化器,但是我有很多不同的 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));

最佳答案

jackson 2.9

现在这很简单,使用 jackson-databind 2.9.0 及更高版本

ObjectMapper objectMapper = new ObjectMapper();
objectMapper.enable(MapperFeature.ACCEPT_CASE_INSENSITIVE_ENUMS);

// objectMapper now deserializes enums in a case-insensitive manner

带有测试的完整示例

import com.fasterxml.jackson.databind.MapperFeature;
import com.fasterxml.jackson.databind.ObjectMapper;

public class Main {

  private enum TestEnum { ONE }
  private static class TestObject { public TestEnum testEnum; }

  public static void main (String[] args) {
    ObjectMapper objectMapper = new ObjectMapper();
    objectMapper.enable(MapperFeature.ACCEPT_CASE_INSENSITIVE_ENUMS);

    try {
      TestObject uppercase = 
        objectMapper.readValue("{ \"testEnum\": \"ONE\" }", TestObject.class);
      TestObject lowercase = 
        objectMapper.readValue("{ \"testEnum\": \"one\" }", TestObject.class);
      TestObject mixedcase = 
        objectMapper.readValue("{ \"testEnum\": \"oNe\" }", TestObject.class);

      if (uppercase.testEnum != TestEnum.ONE) throw new Exception("cannot deserialize uppercase value");
      if (lowercase.testEnum != TestEnum.ONE) throw new Exception("cannot deserialize lowercase value");
      if (mixedcase.testEnum != TestEnum.ONE) throw new Exception("cannot deserialize mixedcase value");

      System.out.println("Success: all deserializations worked");
    } catch (Exception e) {
      e.printStackTrace();
    }
  }
}

关于java - jackson 数据绑定(bind)枚举不区分大小写,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24157817/

相关文章:

c# - 为什么 Iterator 定义 remove() 操作?

java - 已被 CORS 策略阻止 : Response to preflight request doesn't pass access control check: It does not have HTTP ok status

java - 无法加载 ApplicationContext ...创建名为 'entityManagerFactory' 的 bean 时出错 ...NoClassDefFoundError : org/dom4j/io/STAXEventReader

java - 自 Java 1.7.0u40 以来,Java WebStart 应用程序的启动延迟很长

c# - 为值对象序列化自定义 NewtonSoft.Json

c# - 将json字符串转换为字符串数组

java - 将请求的查询字符串解析为 JSON

android - 使用计时器从 JSON 添加多个标记

javascript - 通过 AJAX POST 将 JSON 或 JS 对象与表单数据一起传递到 PHP 的最有效方法

c# - 文档存储序列化