Published 24 Oct, 2022

Java - POST array in RequestBody to Spring Controller as List of Objects

Category Java
Modified : Nov 27, 2022
87

I'm fairly new to Spring, and I've looked at many posts about similar scenarios, but I have yet to figure this out.

I'm trying to alter an existing (working) endpoint in my project to pass an array of Region objects from Angular frontend to a list or other collection in Spring backend. Most of my attempts have resulted in the error: Bad argument(s) for enum JSON parse error: Cannot deserialize instance of java.util.ArrayList<com.cigna.apps.shapeup.domain.Region> out of START_OBJECT token.

Here is my frontend API call:

createCampaignReports(apiRoot: HateoasResponse, campaignId: number, regionList: Region[]): Observable<Action> {
    if (hasHref(apiRoot, this.links.reports)) {
      let params: HttpParams = new HttpParams();
      params = params.set('campaignId', campaignId.toString());
      return this.httpClient.post(getHref(apiRoot, this.links.reports), , )

    ...other code...

    }
  }

And here is a stringified sample array from my frontend:

[
  {
    "sid": 2,
    "region": "New Zealand"
  },
  {
    "sid": 18,
    "region": "Middle East"
  },
  {
    "sid": 19,
    "region": "Kenya"
  }
]

My Spring Controller:

@PostMapping("/reports")
    ResponseEntity<ApiResponse> generateReports(@RequestParam(value = 'campaignId', required = true) Integer campaignId,
                                                @RequestBody (required = false) List<Region> regionList,
                                                HttpServletRequest request,
                                                HttpServletResponse response) {
...other code...

def user = userService.getUser(userId)
def report = portalService.generateReport(user, campaignId, regionList)

...

And finally, my Region class in the backend:

class Region extends BaseEntity {

    String region

    int age
}

Answers

There are 1 suggested solutions here and each one has been listed below with a detailed description. The following topics have been covered briefly such as Json, Angular, Java, Spring Mvc, Spring. These have been categorized in sections for a clear and precise explanation.

28

You could create wrapper class (DTO) for regions list, like:

public class RegionsRequest {
    private List<Region> regions;
    // getters/setters

Update your controller accordingly:

@PostMapping("/reports") 
ResponseEntity<ApiResponse> generateReports(
    @RequestParam(value = 'campaignId', required = true) Integer campaignId, 
    @RequestBody (required = false) RegionsRequest regions, 
    HttpServletRequest request, 
    HttpServletResponse response) { 
    // other code