【问题标题】:Java Spring POST with array and object JSON data problemJava Spring POST 与数组和对象 JSON 数据问题
【发布时间】: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,我已经编辑了我的问题。但仍然有错误。请帮忙。

标签: java json spring


【解决方案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){
    

    【讨论】:

      猜你喜欢
      • 2019-03-27
      • 1970-01-01
      • 2023-03-25
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-07-19
      • 1970-01-01
      相关资源
      最近更新 更多