AppleT
AppleT

Reputation: 61

Java Spring POST with array and object JSON data problem

I am sending this from the frontend via POST ajax:

It consists of JSON array and object.

EDIT: I have set :

contentType: 'application/json'

The exact JSON is sent as follows:

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

I am trying to get this from the Controller: (EDITED)

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

But I am getting an error (HTTP 400):

Resolved [org.springframework.http.converter.HttpMessageNotReadableException: JSON parse error: Cannot deserialize instance of java.util.ArrayList out of START_OBJECT token; nested exception is com.fasterxml.jackson.databind.exc.MismatchedInputException: Cannot deserialize instance of java.util.ArrayList out of START_OBJECT token at [Source: (PushbackInputStream); line: 1, column: 1]]

How can I code my controller backend? Please help. Thanks.

Upvotes: 0

Views: 2488

Answers (2)

Atmas
Atmas

Reputation: 2393

There is a disconnect between what you're sending and what your controller is expecting. The JSON message in its confusing verbiage actually puts it pretty precisely once you notice the disconnect.

What you're sending is an OBJECT that contains two keys, one of which is a LIST of things.

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

What your Controller is expecting is JUST the listof things

List<AlertKeeperDTO> alertKeeperDTOs

This results in the error Cannot deserialize instance of java.util.ArrayList out of START_OBJECT token because the OBJECT you started isn't a LIST!

So you need to decide what you want to do at this point. Do you want to send the object or the list? If you want to send just the LIST, then change what you send to just be the array contents. So you would send:

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

But if you need the deviceId information to be sent too or other information in that object's structure, then you need to create the larger/wrapper object as Benjamin suggested in the prior answer and continue to send as you have been.

Upvotes: 1

Benjamin Sch&#252;ller
Benjamin Sch&#252;ller

Reputation: 2189

Create a class that contains the alertKeeperDTOs-List and the deviceId as a wrapper. Then use it in your controller.

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

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

Upvotes: 1

Related Questions