【问题标题】:Automatic deserialization from String to object for @RequestBody in SpringSpring中@RequestBody从String到对象的自动反序列化
【发布时间】:2021-11-09 01:24:10
【问题描述】:

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

我的@RestController 里面有类似这个方法和端点的东西:

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&lt;Enum2&gt; 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"])]

有没有办法做到这一点?

【问题讨论】:

  • 您是否正确发送了 Enum2 值?它们应该采用 [A,B,C...] 格式才能进行解码。你能检查或分享你的数据发送到哪里的代码吗?

标签: java json spring jackson deserialization


【解决方案1】:

我找到了解决方案。我必须将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 进行拆分和转换为列表。

现在TrackDeserializer 会为每个Track 在问题中使用给定的JSON 调用。

【讨论】:

    【解决方案2】:

    可能,不使用任何Jackson 注释的最简单解决方案是使用自定义setter 方法:

    private void setMissions(String value) {
        this.missions = convert_value_to_list_of_enums;
    }
    

    Jackson 将使用以下值调用此方法:ABCCBACBBCA

    【讨论】:

      猜你喜欢
      • 2018-09-24
      • 2020-01-19
      • 1970-01-01
      • 2021-12-20
      • 1970-01-01
      • 2019-05-10
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多