【问题标题】:springboot Can not deserialize-HttpMessageNotReadableExceptionspring boot 无法反序列化-HttpMessageNotReadableException
【发布时间】:2017-05-24 15:51:33
【问题描述】:

我正在尝试在我的 Spring Boot 项目中读取 json。

我的JSON数据如下:

[{
    "userId":"101"
},
{
    "partNum":"aaa"
},
{
    "partNum":"bbb"
},
{
    "partNum":"ccc"
}]

我已经创建了一个 DTO 类:

public class TcPartDto {
    private String userId;
    private List<String> partNum;

    public String getUserId() {
        return userId;
    }
    public void setUserId(String userId) {
        this.userId = userId;
    }
    public List<String> getPartNum() {
        return partNum;
    }
}

我在我的控制器中调用它如下:

@RequestMapping(value = "/volumeinfo", method = RequestMethod.POST, consumes = {"application/json"}, produces = {"application/json"})
@ResponseBody
public List<TcPartVolumeDto> volumeinfo(@RequestBody TcPartDto partList) throws Exception {
    return tcService.fetchVolumeInfo(partList);
}

但我收到以下错误:

通过 Postman 我得到了这个错误:

“无法读取文档:无法反序列化 tc.service.model.TcPartDto out of START_ARRAY token\n at [Source: java.io.PushbackInputStream@5359141a;行:1,列:1];嵌套的 例外是 com.fasterxml.jackson.databind.JsonMappingException: Can 不反序列化 tc.service.model.TcPartDto 的实例 START_ARRAY 令牌\n 在 [来源:java.io.PushbackInputStream@5359141a; 行:1,列:1]"

我做错了什么?

【问题讨论】:

    标签: java json spring-mvc spring-boot


    【解决方案1】:

    正如其他人已经指出的各种答案。

    如果这是您想要在不更改类的情况下映射的 json:

    JSON:

    [{
        "userId":"101"
    },
    {
        "partNum":"aaa"
    },
    {
        "partNum":"bbb"
    },
    {
        "partNum":"ccc"
    }]
    

    类:

    @JsonIgnoreProperties(ignoreUnknown=true)
    public class TcPartDto {
    
        private String userId;
        private List<String> partNum;
    //getters and setters 
    }
    

    控制器:

    @RequestMapping(value = "/volumeinfo", method = RequestMethod.POST, consumes = {"application/json"}, produces = {"application/json"})
    @ResponseBody
    public List<TcPartVolumeDto> volumeinfo(@RequestBody TcPartDto[] partArray) throws Exception {
        return tcService.fetchVolumeInfo(partArray);
    }
    

    输出:

    [{"userId":"101","partNum":null},{"userId":null,"partNum":["aaa"]},{"userId":null,"partNum":["bbb"]},{"userId":null,"partNum":["ccc"]}]
    

    【讨论】:

      【解决方案2】:

      您创建的 DTO 与其尝试读取的 json 数据不匹配。

      根据您的 DTO 示例 json 应该是:

      {
        "userId" : "someId",
        "partNum" : [ "partNum1", "partNum2"]
      }
      

      否则,如果您使用的 json 对象是固定的,那么 DTO 应该是:

      public class MyDTO {
      
          private String userId;
          private String partNum;
      
          // ...
      }
      

      以及带有类型参数的控制器

      List<MyDTO>
      

      【讨论】:

        【解决方案3】:

        您正在向您的 public List&lt;TcPartVolumeDto&gt; volumeinfo(@RequestBody TcPartDto partList) 方法发送一个 JSON 数组。但它应该反序列化为单个对象:TcPartDto partList

        更改您的 JSON 结构以仅发送一个 TcPartDto 或确保您的 volumeinfo 方法可以接收 ArrayList

        如果你想发送单个对象,你必须改变你的 JSON 结构:

        {
          "userId": 101,
          "partNum": [
            "aaa",
            "bbb",
            "ccc"
          ]
        }
        

        【讨论】:

        • 我不能像这样更改 JSON 格式,它是从另一个应用程序生成的,我必须按原样使用它