如何反序列化包含不区分大小写的枚举值的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() {
}
}
在这种情况下,使用 "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使用枚举,而且很难维护 .
任何人都可以建议一个更好的方法来使用适当的命名约定序列化和反序列化枚举?
I don't want my enums in java to be lowercase!
这是我使用的一些测试代码:
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));
9 回答
在2.4.0版中,您可以为所有Enum类型注册自定义序列化程序(link到github问题) . 此外,您可以自行更换标准的Enum反序列化器,以便了解Enum类型 . 这是一个例子:
输出:
Jackson 2.9
现在这很简单,从
jackson-databind
2.9.0及以上完整的代码示例
我在我的项目中遇到了同样的问题,我们决定使用字符串键构建枚举,并分别使用
@JsonValue
和静态构造函数进行序列化和反序列化 .从Jackson 2.6开始,您可以简单地执行此操作:
有关完整示例,请参阅this gist .
我选择了Sam B.的解决方案,但这是一个更简单的变体 .
我使用了IagoFernández和Paul解决方案的修改 .
我的requestobject中有一个枚举,需要不区分大小写
问题归结为com.fasterxml.jackson.databind.util.EnumResolver . 它使用HashMap来保存枚举值,而HashMap不支持不区分大小写的键 .
在上面的答案中,所有字符都应该是大写或小写 . 但我修复了枚举的所有敏感问题:
https://gist.github.com/bhdrk/02307ba8066d26fa1537
CustomDeserializers.java
Usage:
当我想以不区分大小写的方式反序列化时(基于问题中发布的代码),我有时会处理枚举的方式:
如果枚举是非平凡的,因此在它自己的类中,我通常会添加一个静态解析方法来处理小写字符串 .
用 Jackson 反序列化枚举很简单 . 当您想要基于String的反序列化枚举需要一个构造函数,一个getter和一个使用该枚举的enum.Also类的setter必须有一个setter接收DataType作为param,而不是String:
当你有了json时,你可以使用Jackson的ObjectMapper反序列化为Endpoint类: