Spring中@RequestBody从字符串到对象的自动反序列化



我遇到了序列化问题,尽管我一直在四处寻找,但我无法找到解决方案。

我在我的@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将以ABCCBACBBCA的值调用此方法。

相关内容

  • 没有找到相关文章

最新更新