我有一个简单枚举Days
public enum Days {
@JsonProperty("Monday")
MONDAY("Monday"),
@JsonProperty("Tuesday")
TUESDAY("Tuesday");
private String day;
Days(String day) {
this.day = day;
}
@JsonValue
public String getDay() {
return day;
}
}
和一类Event
public class Event {
private Days day;
private String name;
@JsonCreator
public Event(@JsonProperty("day") Days day,
@JsonProperty("name") String name) {
this.day = day;
this.name = name;
}
public Days getDay() {
return day;
}
public String getName() {
return name;
}
}
我用杰克逊2.9,this answer表明,采用@JsonProperty
应该是够了,但是我很难反序列化这样的:
public static void main(String[] args) throws JsonProcessingException {
ObjectMapper objectMapper = new ObjectMapper();
Event event = new Event(Days.MONDAY, "Birthday");
String serialisedEvent = objectMapper.writeValueAsString(event);
System.out.println(serialisedEvent);
// {"day":"Monday","name":"Birthday"}
Event deserialisedEvent = objectMapper.convertValue(serialisedEvent, Event.class);
// Exception in thread "main" java.lang.IllegalArgumentException: Cannot construct instance of `xyz.blabla.Event` (although at least one Creator exists): no String-argument constructor/factory method to deserialize from String value ('{"day":"Monday","name":"Birthday"}')
// at [Source: UNKNOWN; line: -1, column: -1]
// at com.fasterxml.jackson.databind.ObjectMapper._convert(ObjectMapper.java:3750)
System.out.println(deserialisedEvent.getDay());
}
我在春天启动2项目中使用Java 11和杰克逊2.9。我怎样才能使这项工作?
杰克逊反序列化方法被调用readValue
。
convertValue
的目的是不同的 - 其序列的对象(其可以是一个字符串 - 这将成为一个JSON-字串文本然后)第一,然后将结果反序列化到目标类型的一个对象。
下面应该工作:
Event deserialisedEvent = objectMapper.readValue(serialisedEvent, Event.class);
您没有默认的构造函数,但一个参数的构造函数。
你有@JsonCreator
进行注解,以便杰克逊用它来反序列化JSON的:
@JsonCreator
public Event(Days day, String name) {
this.day = day;
this.name = name;
}
序列化Java对象到JSON,构造函数没有被杰克逊,因为它没有创建Java实例,但只使用getter检索它的性能。所以,它的工作。但是,反序列化JSON到Java对象,杰克逊需要实例化目标类。默认情况下,它会寻找无参数的构造函数。
还要注意的是注释与@JsonProperty("...")
构造函数的参数,如果你使用ParameterNamesModule
如不需要:
ObjectMapper objectMapper = new ObjectMapper();
objectMapper.registerModule(new ParameterNamesModule());
春季启动2提供为你,你要看杰克逊。 在这里,你需要它,因为你不使用由Spring启动映射器接线,但你自己实例化。
除了不需要设在枚举的@JsonProperty
注解之一:
public enum Days {
@JsonProperty("Monday")
MONDAY("Monday"),
@JsonProperty("Tuesday")
TUESDAY("Tuesday");
//...
}
它允许改变枚举的串行输出,但实际上你并不需要去改变它,你把它映射到当前用于枚举杰克逊映射day
字段值...