用jackson反序列化枚举
我正在尝试并且没有用Jackson 2.5.4反序列化枚举,我在那里看不到我的情况。 我的输入字符串是驼峰式的,我想简单地映射到标准的Enum约定。
@JsonFormat(shape = JsonFormat.Shape.STRING) public enum Status { READY("ready"), NOT_READY("notReady"), NOT_READY_AT_ALL("notReadyAtAll"); private static Map FORMAT_MAP = Stream .of(Status.values()) .collect(toMap(s -> s.formatted, Function.identity())); private final String formatted; Status(String formatted) { this.formatted = formatted; } @JsonCreator public Status fromString(String string) { Status status = FORMAT_MAP.get(string); if (status == null) { throw new IllegalArgumentException(string + " has no corresponding value"); } return status; } }
我也试过@JsonValue
一个无法获得,这是我在别处看到的一个选项。 他们都爆炸了:
com.fasterxml.jackson.databind.exc.InvalidFormatException: Can not construct instance of ...Status from String value 'ready': value not one of declared Enum instance names: ...
我究竟做错了什么?
编辑:从Jackson 2.6开始,您可以在枚举的每个元素上使用@JsonProperty
来指定其序列化/反序列化值( 请参阅此处 ):
public enum Status { @JsonProperty("ready") READY, @JsonProperty("notReady") NOT_READY, @JsonProperty("notReadyAtAll") NOT_READY_AT_ALL; }
(这个答案的其余部分仍然适用于旧版本的jackson)
您应该使用@JsonCreator
来注释接收String
参数的静态方法。 这就是jackson所说的工厂方法 :
public enum Status { READY("ready"), NOT_READY("notReady"), NOT_READY_AT_ALL("notReadyAtAll"); private static Map FORMAT_MAP = Stream .of(Status.values()) .collect(Collectors.toMap(s -> s.formatted, Function.identity())); private final String formatted; Status(String formatted) { this.formatted = formatted; } @JsonCreator // This is the factory method and must be static public static Status fromString(String string) { return Optional .ofNullable(FORMAT_MAP.get(string)) .orElseThrow(() -> new IllegalArgumentException(string)); } }
这是测试:
ObjectMapper mapper = new ObjectMapper(); Status s1 = mapper.readValue("\"ready\"", Status.class); Status s2 = mapper.readValue("\"notReadyAtAll\"", Status.class); System.out.println(s1); // READY System.out.println(s2); // NOT_READY_AT_ALL
由于工厂方法需要String
,因此必须对字符串使用JSON有效语法,即引用值。
这可能是一种更快的方法:
public enum Status { READY("ready"), NOT_READY("notReady"), NOT_READY_AT_ALL("notReadyAtAll"); private final String formatted; Status(String formatted) { this.formatted = formatted; } @Override public String toString() { return formatted; } } public static void main(String[] args) throws IOException { ObjectMapper mapper = new ObjectMapper(); ObjectReader reader = mapper.reader(Status.class); Status status = reader.with(DeserializationFeature.READ_ENUMS_USING_TO_STRING).readValue("\"notReady\""); System.out.println(status.name()); // NOT_READY }
- 如何为json响应添加和忽略字段
- jackson:自定义集合序列化到JSON
- 由于java.lang.NoClassDefFoundError无法运行代码:com / fasterxml / jackson / annotation / JsonMerge
- 直接自引用导致循环exception
- jackson没有填充所有财产
- 单个自定义序列化程序,用于所有嵌入的带注释的对象,用它们的id替换它们
- @JsonIgnore和@JsonBackReference,@ JsonManagedReference之间的区别
- RestEasy:org.codehaus.jackson.map.JsonMappingException:无法从START_OBJECT标记(..)中反序列化java.util.ArrayList的实例
- 使用条件动态排除Jackson json序列化中的POJO属性