Java Spring POST 与数组和对象 JSON 数据问题

Posted

技术标签:

【中文标题】Java Spring POST 与数组和对象 JSON 数据问题【英文标题】:Java Spring POST with array and object JSON data problem 【发布时间】:2021-07-21 15:45:21 【问题描述】:

我通过 POST ajax 从前端发送这个:

它由 JSON 数组和对象组成。

编辑:我已经设置:

contentType: 'application/json'

准确的 JSON 发送如下:


    "alertKeeperDTOs": [
        
            "isSelected": true,
            "rn": 0,
            "keeperId": "B116453993D52735E0530A10CA0A9D27",
            "keeperName": "myName"          
        ,
        
            "isSelected": false,
            "rn": 1,
            "keeperId": "65EE22D4A55C4437A4F5552CBFD8D6D0",
            "keeperName": "test",           
        
    ],
    "deviceId": 4

我正在尝试从控制器中获取此信息: (已编辑)

public @ResponseBody String updateDeviceToKeeperList(@RequestBody List<AlertKeeperDTO> alertKeeperDTOs,
 @RequestBody Long deviceId, HttpServletRequest request)
        ....
    

但我收到一个错误(HTTP 400):

已解决 [org.springframework.http.converter.HttpMessageNotReadableException:JSON 解析错误:无法从 START_OBJECT 令牌中反序列化 java.util.ArrayList 的实例;嵌套异常是 com.fasterxml.jackson.databind.exc.MismatchedInputException: 无法从 START_OBJECT 令牌中反序列化 java.util.ArrayList 的实例 在 [来源:(PushbackInputStream);行:1,列:1]]

如何编码我的控制器后端?请帮忙。谢谢。

【问题讨论】:

检查 Content-Type 请求的标头,您说您正在发送 JSON 正文,但看起来 Content-Typeapplication/x-www-form-urlencoded 而不是 application/json。另外,如果要将请求正文映射到alertKeeperDTOs,请使用@RequestBody 注释而不是@RequestParam 嗨@MaciejDobrowolski,我已经编辑了我的问题。但仍然有错误。请帮忙。 【参考方案1】:

您发送的内容与控制器的预期内容之间存在脱节。一旦您注意到断开连接,JSON 消息在其令人困惑的措辞中实际上非常准确地表达了它。

您发送的是一个包含两个键的 OBJECT,其中一个是事物列表。


    "alertKeeperDTOs": [ ..list of things.. ],
    "deviceId": ...

您的控制器所期望的只是事物列表

List<AlertKeeperDTO> alertKeeperDTOs

这会导致错误 Cannot deserialize instance of java.util.ArrayList out of START_OBJECT token,因为您启动的 OBJECT 不是 LIST!

因此,此时您需要决定要做什么。您要发送对象还是列表?如果您只想发送 LIST,则将您发送的内容更改为数组内容。所以你会发送:

[
        
            "isSelected": true,
            "rn": 0,
            "keeperId": "B116453993D52735E0530A10CA0A9D27",
            "keeperName": "myName"          
        ,
        
            "isSelected": false,
            "rn": 1,
            "keeperId": "65EE22D4A55C4437A4F5552CBFD8D6D0",
            "keeperName": "test",           
        
    ]

但是,如果您也需要发送 deviceId 信息或该对象结构中的其他信息,那么您需要按照 Benjamin 在先前答案中的建议创建更大的/包装器对象,并继续发送。

【讨论】:

【参考方案2】:

创建一个包含 alertKeeperDTOs-List 和 deviceId 作为包装器的类。然后在你的控制器中使用它。

public class Device 
  private List<AlertKeeperDTO> alertKeeperDTOs;
  private Long deviceId;
  //empty constructor
  //getters and setters


public @ResponseBody String updateDeviceToKeeperList(@RequestBody Device device, HttpServletRequest request)

【讨论】:

以上是关于Java Spring POST 与数组和对象 JSON 数据问题的主要内容,如果未能解决你的问题,请参考以下文章

java数组赋值给另一个数组,2021最新版!

将 Javascript 数组与 Java 列表匹配

POST / PUT 上的 Java Spring REST API 状态 400 响应

十年Java编程开发生涯,java获取数组最大值的函数

Java面试题,java提取json数组对象所有的id

java中把json怎么转换成数组