如何解决Java RestTemplate在使用Map而不是有效的JSON时出现400错误的问题。

huangapple go评论83阅读模式
英文:

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 methods)
}

Now I'm trying to do a POST-Call to my API via Java. I am using RestTemplate, but I only have a Map when I try to do the POST-Call, so I get an HTTP 400 Status Code Bad Request Invalid JSON.

I try to do it like this:

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("beltno", "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
<details>
<summary>英文:</summary>
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(&quot;/calls&quot;)
public List&lt;Call&gt; getAllCalls(){
return callService.getAllCallList();
}
@PostMapping(value = &quot;/calls&quot;)
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&lt;Call&gt; callList = new ArrayList&lt;&gt;(Arrays.asList(new Call(&quot;33333301&quot;,&quot;61&quot;,&quot;Test&quot;,
&quot;Test&quot;,&quot;Test&quot;,&quot;Test&quot;,&quot;Test&quot;,&quot;Test&quot;,&quot;Test&quot;,&quot;Test&quot;,
&quot;Test&quot;,&quot;Test&quot;,&quot;Test&quot;,&quot;Test&quot;,&quot;Test&quot;,&quot;Test&quot;,&quot;Test&quot;,
&quot;Test&quot;,&quot;Test&quot;,&quot;Test&quot;,&quot;Test&quot;,&quot;Test&quot;,&quot;Test&quot;,
&quot;Test&quot;,&quot;Test&quot;,&quot;Test&quot;,&quot;Test&quot;,&quot;Test&quot;,&quot;Test&quot;,
&quot;Test&quot;,&quot;Test&quot;,&quot;Test&quot;),new Call(&quot;33333302&quot;,&quot;61&quot;,&quot;Test&quot;,
&quot;Test&quot;,&quot;Test&quot;,&quot;Test&quot;,&quot;Test&quot;,&quot;Test&quot;,&quot;Test&quot;,&quot;Test&quot;,
&quot;Test&quot;,&quot;Test&quot;,&quot;Test&quot;,&quot;Test&quot;,&quot;Test&quot;,&quot;Test&quot;,&quot;Test&quot;,
&quot;Test&quot;,&quot;Test&quot;,&quot;Test&quot;,&quot;Test&quot;,&quot;Test&quot;,&quot;Test&quot;,
&quot;Test&quot;,&quot;Test&quot;,&quot;Test&quot;,&quot;Test&quot;,&quot;Test&quot;,&quot;Test&quot;,
&quot;Test&quot;,&quot;Test&quot;,&quot;Test&quot;)));
public List&lt;Call&gt; 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&#39;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&lt;String, String&gt; parameters = new LinkedMultiValueMap&lt;&gt;();
parameters.add(&quot;tcpident&quot;,&quot;1&quot;);
parameters.add(&quot;requestid&quot;,&quot;2&quot;);
parameters.add(&quot;mclass&quot;,&quot;3&quot;);
parameters.add(&quot;mno&quot;,&quot;4&quot;);
parameters.add(&quot;errorstate&quot;,&quot;5&quot;);
parameters.add(&quot;datalength&quot;,&quot;6&quot;);
parameters.add(&quot;resourceid&quot;,&quot;1&quot;);
parameters.add(&quot;ono&quot;,&quot;2&quot;);
parameters.add(&quot;opos&quot;,&quot;3&quot;);
parameters.add(&quot;wpno&quot;,&quot;23&quot;);
parameters.add(&quot;opno&quot;,&quot;ddsds&quot;);
parameters.add(&quot;bufno&quot;,&quot;d&quot;);
parameters.add(&quot;bufpos&quot;,&quot;ds&quot;);
parameters.add(&quot;carrierid&quot;,&quot;dsdd&quot;);
parameters.add(&quot;palletid&quot;,&quot;dsd&quot;);
parameters.add(&quot;palletpos&quot;,&quot;dsd&quot;);
parameters.add(&quot;pno&quot;,&quot;dsd&quot;);
parameters.add(&quot;oposid&quot;,&quot;ds&quot;);
parameters.add(&quot;stepno&quot;,&quot;dsd&quot;);
parameters.add(&quot;maxrecords&quot;,&quot;dsd&quot;);
parameters.add(&quot;boxid&quot;,&quot;dsd&quot;);
parameters.add(&quot;boxpos&quot;,&quot;dsd&quot;);
parameters.add(&quot;mainopos&quot;,&quot;dsds&quot;);
parameters.add(&quot;eltno&quot;,&quot;dsd&quot;);
parameters.add(&quot;cno&quot;,&quot;dsd&quot;);
parameters.add(&quot;boxpno&quot;,&quot;ds&quot;);
parameters.add(&quot;palletpno&quot;,&quot;dsd&quot;);
parameters.add(&quot;aux1int&quot;,&quot;ds&quot;);
parameters.add(&quot;aux2int&quot;,&quot;ds&quot;);
parameters.add(&quot;aux1dint&quot;,&quot;dsdsd&quot;);
parameters.add(&quot;aux2dint&quot;,&quot;dsd&quot;);
parameters.add(&quot;mainpno&quot;,&quot;dsod&quot;);
HttpEntity&lt;MultiValueMap&lt;String, String&gt;&gt; request = new HttpEntity&lt;&gt;(parameters,headers);
System.out.println(&quot;Headers:  &quot;+request.getHeaders());
System.out.println(&quot;Body:    &quot;+request.getBody());
//Call call = mapper.convertValue(request, Call.class);
//Call call = restTemplate.postForObject(&quot;http://localhost:8080/calls&quot;, request,Call.class);
ResponseEntity&lt;Call[]&gt; response = restTemplate.postForEntity(&quot;http://localhost:8080/calls&quot;, request, Call[].class);
}
the request and headers I printed are:
Headers:  [Content-Type:&quot;application/json&quot;]
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:
{
&quot;tcpident&quot;: &quot;00110011&quot;,
&quot;requestid&quot;: 47,
&quot;mclass&quot;: false,
&quot;mno&quot;: null,
&quot;errorstate&quot;: null,
&quot;datalength&quot;: null,
&quot;resourceid&quot;: null,
&quot;ono&quot;: null,
&quot;opos&quot;: null,
&quot;wpno&quot;: null,
&quot;opno&quot;: null,
&quot;bufno&quot;: null,
&quot;bufpos&quot;: null,
&quot;carrierid&quot;: null,
&quot;palletid&quot;: null,
&quot;palletpos&quot;: null,
&quot;pno&quot;: null,
&quot;oposid&quot;: null,
&quot;stepno&quot;: null,
&quot;maxrecords&quot;: null,
&quot;boxid&quot;: null,
&quot;boxpos&quot;: null,
&quot;mainopos&quot;: null,
&quot;beltno&quot;: null,
&quot;cno&quot;: null,
&quot;boxpno&quot;: null,
&quot;palletpno&quot;: null,
&quot;aux1int&quot;: null,
&quot;aux2int&quot;: null,
&quot;aux1dint&quot;: null,
&quot;aux2dint&quot;: null,
&quot;mainpno&quot;: null
}
</details>
# 答案1
**得分**: 1
`MultiValueMap` 应该用于以 `APPLICATION_FORM_URLENCODED` 媒体类型发送表单数据。您的情况是JSON请求,您可以尝试使用 `JSONObject`。
示例::
```java
JSONObject jsonObject = new JSONObject();
jsonObject.put("tcpident", "00110011");
jsonObject.put("requestid", "47");
... 更多参数
HttpEntity<String> request = 
new HttpEntity<String>(jsonObject.toString(), headers);
restTemplate.postForEntity("http://localhost:8080/calls", request, Call[].class);
英文:

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(&quot;tcpident&quot;, &quot;00110011&quot;);
jsonObject.put(&quot;requestid&quot;, &quot;47&quot;);
... more params
HttpEntity&lt;String&gt; request = 
new HttpEntity&lt;String&gt;(jsonObject.toString(), headers);
restTemplate.postForEntity(&quot;http://localhost:8080/calls&quot;, request, Call[].class);

答案2

得分: 0

MultiValueMap<String, Object> parameters = new LinkedMultiValueMap<>();
?

英文:

Have out tried with:
MultiValueMap<String, Object> parameters = new LinkedMultiValueMap<>();
?

huangapple
  • 本文由 发表于 2020年8月7日 15:42:21
  • 转载请务必保留本文链接:https://go.coder-hub.com/63297382.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定