Search code examples
javajsonspring-bootpostresttemplate

How to solve Java resttemplate post having map instead of valid json bad request Error 400


I am programming a Spring Boot Application, that should send a JSON via POST-Request to my REST-API.

My Controller class looks like:

package com.example.workflow;

import jdk.jfr.ContentType;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RestController;

import java.util.List;

@RestController
public class CallController {

    @Autowired
    private CallService callService;

    @GetMapping("/calls")
    public List<Call> getAllCalls(){
        return callService.getAllCallList();
    }

    @PostMapping(value = "/calls")
    public void addCall(@RequestBody Call call){
        callService.addCall(call);
    }
}

My Service Class looks like:

package com.example.workflow;

import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

@Service
public class CallService {
    private List<Call> callList = new ArrayList<>(Arrays.asList(new Call("33333301","61","Test",
            "Test","Test","Test","Test","Test","Test","Test",
            "Test","Test","Test","Test","Test","Test","Test",
            "Test","Test","Test","Test","Test","Test",
            "Test","Test","Test","Test","Test","Test",
            "Test","Test","Test"),new Call("33333302","61","Test",
            "Test","Test","Test","Test","Test","Test","Test",
            "Test","Test","Test","Test","Test","Test","Test",
            "Test","Test","Test","Test","Test","Test",
            "Test","Test","Test","Test","Test","Test",
            "Test","Test","Test")));

    public List<Call> getAllCallList() {
        return callList;
    }

    public void addCall(Call call) {
        callList.add(call);
    }
}

My Model Class Call.java is like:

package com.example.workflow;

public class Call {
    String tcpident, requestid, mclass, mno, errorstate, datalength, resourceid, ono, opos,
            wpno, opno, bufno, bufpos, carrierid, palletid, palletpos, pno, oposid, stepno,
            maxrecords, boxid, boxpos, mainopos, beltno, cno, boxpno, palletpno,aux1int,
            aux2int,aux1dint,aux2dint,mainpno;

    public Call() {
    }

    public Call(String tcpident, String requestid, String mclass, String mno, String errorstate, String datalength,
                String resourceid, String ono, String opos, String wpno, String opno, String bufno, String bufpos,
                String carrierid, String palletid, String palletpos, String pno, String oposid, String stepno,
                String maxrecords, String boxid, String boxpos, String mainopos, String beltno, String cno,
                String boxpno, String palletpno, String aux1int, String aux2int, String aux1dint,
                String aux2dint, String mainpno) {
        this.tcpident = tcpident;
        this.requestid = requestid;
        this.mclass = mclass;
        this.mno = mno;
....+getter and setter

Now im trying to do a POST-Call to my API via Java. I am using Resttemplate, but I only have a Map, if i try to do the POST-Call so I'll get a HTTP 400 Status Code Bad Request Invalid JSON.

I try to do it so:

public void post() throws JsonProcessingException {
        HttpHeaders headers = new HttpHeaders();
        headers.setContentType(MediaType.APPLICATION_JSON);
        MultiValueMap<String, String> parameters = new LinkedMultiValueMap<>();
        parameters.add("tcpident","1");
        parameters.add("requestid","2");
        parameters.add("mclass","3");
        parameters.add("mno","4");
        parameters.add("errorstate","5");
        parameters.add("datalength","6");
        parameters.add("resourceid","1");
        parameters.add("ono","2");
        parameters.add("opos","3");
        parameters.add("wpno","23");
        parameters.add("opno","ddsds");
        parameters.add("bufno","d");
        parameters.add("bufpos","ds");
        parameters.add("carrierid","dsdd");
        parameters.add("palletid","dsd");
        parameters.add("palletpos","dsd");
        parameters.add("pno","dsd");
        parameters.add("oposid","ds");
        parameters.add("stepno","dsd");
        parameters.add("maxrecords","dsd");
        parameters.add("boxid","dsd");
        parameters.add("boxpos","dsd");
        parameters.add("mainopos","dsds");
        parameters.add("eltno","dsd");
        parameters.add("cno","dsd");
        parameters.add("boxpno","ds");
        parameters.add("palletpno","dsd");
        parameters.add("aux1int","ds");
        parameters.add("aux2int","ds");
        parameters.add("aux1dint","dsdsd");
        parameters.add("aux2dint","dsd");
        parameters.add("mainpno","dsod");
        HttpEntity<MultiValueMap<String, String>> request = new HttpEntity<>(parameters,headers);
        System.out.println("Headers:  "+request.getHeaders());
        System.out.println("Body:    "+request.getBody());
        //Call call = mapper.convertValue(request, Call.class);
        //Call call = restTemplate.postForObject("http://localhost:8080/calls", request,Call.class);
        ResponseEntity<Call[]> response = restTemplate.postForEntity("http://localhost:8080/calls", request, Call[].class);
    }

the request and headers I printed are:

Headers:  [Content-Type:"application/json"]
Body:    {tcpident=[1], requestid=[2], mclass=[3], mno=[4], errorstate=[5], datalength=[6], resourceid=[1], ono=[2], opos=[3], wpno=[23], opno=[ddsds], bufno=[d], bufpos=[ds], carrierid=[dsdd], palletid=[dsd], palletpos=[dsd], pno=[dsd], oposid=[ds], stepno=[dsd], maxrecords=[dsd], boxid=[dsd], boxpos=[dsd], mainopos=[dsds], eltno=[dsd], cno=[dsd], boxpno=[ds], palletpno=[dsd], aux1int=[ds], aux2int=[ds], aux1dint=[dsdsd], aux2dint=[dsd], mainpno=[dsod]}

If i do a POST-Call via POSTMAN to my RESTAPI it works, Im using a JSON like this:

{
  "tcpident": "00110011",
  "requestid": 47,
  "mclass": false,
  "mno": null,
  "errorstate": null,
  "datalength": null,
  "resourceid": null,
  "ono": null,
  "opos": null,
  "wpno": null,
  "opno": null,
  "bufno": null,
  "bufpos": null,
  "carrierid": null,
  "palletid": null,
  "palletpos": null,
  "pno": null,
  "oposid": null,
  "stepno": null,
  "maxrecords": null,
  "boxid": null,
  "boxpos": null,
  "mainopos": null,
  "beltno": null,
  "cno": null,
  "boxpno": null,
  "palletpno": null,
  "aux1int": null,
  "aux2int": null,
  "aux1dint": null,
  "aux2dint": null,
  "mainpno": null
}

Solution

  • MultiValueMap should be used to send form data with media-type APPLICATION_FORM_URLENCODED. Your case is JSON request, and You can try to use JSONObject.

    Example::

    JSONObject jsonObject= new JSONObject();
    jsonObject.put("tcpident", "00110011");
    jsonObject.put("requestid", "47");
    ... more params
    
    HttpEntity<String> request = 
      new HttpEntity<String>(jsonObject.toString(), headers);
    
     restTemplate.postForEntity("http://localhost:8080/calls", request, Call[].class);