我遇到了序列化问题,尽管我一直在四处寻找,但我无法找到解决方案。
我在我的@RestController
中有一个类似的方法for和端点:
public ResponseEntity<String>(@RequestBody RequestObject requestObject )
RequestObject
看起来像这样:
public class RequestObject {
private Driver driver;
private List<Tracks> tracks;
//constructors, getters and setters
}
public class Tracks {
private Enum1 name;
private List<Enum2> missions;
//constructors, getters and setters
}
所以,问题来自于Enum2的List
。这是因为我从JSON中收到的不是字符串列表,而是一个字符串,我需要解析以转换为Enum2
的值。所以Enum2
看起来像这样:
A,
B,
C;
我从请求中得到的JSON是:
{
"driver" : {
"name" : "myname"
}
},
"tracks" : [
{
"name" : "madrid",
"missions" : "ABCCBA"
},
{
"name" : "barcelona",
"mission" : "CBBCA"
},
]
}
除了List<Enum2> missions
,所有的反序列化都是开箱有效的(包括所有嵌套的枚举)我已经设法做了一个肮脏的技巧,但我想做正确的方式,我理解的是写某种反序列化器,当控制器被触发时运行,它做所有的解析和转换从字符串到列表(这个分割代码我有它,但我不知道把它放在哪里)。
此刻我得到这个
2021-09-13 21:02:34.924 WARN 99904 --- [nio-8080-exec-8] .w.s.m.s.DefaultHandlerExceptionResolver : Resolved [org.springframework.http.converter.HttpMessageNotReadableException: JSON parse error: Cannot deserialize value of type `java.util.ArrayList<org.package.model.Enum2>` from String value (token `JsonToken.VALUE_STRING`); nested exception is com.fasterxml.jackson.databind.exc.MismatchedInputException: Cannot deserialize value of type `java.util.ArrayList<org.model.Enum2>` from String value (token `JsonToken.VALUE_STRING`)
at [Source: (PushbackInputStream); line: 13, column: 26] (through reference chain: org.model.RequestObject["missions"]->java.util.ArrayList[0]-org.model.Track["missions"])]
有办法做到这一点吗?
我找到了解决方案。我必须这样标记Track
:
@JsonDeserialize(using = TrackDeserializer.class)
public class Track
和写TrackDeserializer
:
public class TrackDeserializer extends JsonDeserializer<Track>{
@Override
public Track deserialize(JsonParser j, DeserializationContext ctxt) throws IOException{
JsonNode jsonNode = j.getCodec().readTree(jsonParser);
String name = jsonNode.get("name").asText();
final List<Enum2> enum = parseEnums(jsonNode.get("mission").asText());
return new Track(name, enum);
}
和parseEnums
进行拆分和转换到列表。
现在每个Track
在问题中使用给定的JSON调用TrackDeserializer
。
可能,不使用任何Jackson
注释的最简单解决方案是使用自定义setter
方法:
private void setMissions(String value) {
this.missions = convert_value_to_list_of_enums;
}
Jackson
将以ABCCBA
和CBBCA
的值调用此方法。