【问题标题】:When I send a request array via POST on RestTemplate I receive error 400当我通过 RestTemplate 上的 POST 发送请求数组时,我收到错误 400
【发布时间】:2017-06-12 21:10:24
【问题描述】:

有一个外部服务叫做

http://externalServer:9000/pathServer/serviceCalled

此服务作为输入参数接收对象列表。

Request
    [
        { "atr1" : "value" },
        { "atr1" : "value" },
        { "atr1" : "value" },
        { "atr1" : "value" }
    ]

在我的后端调用此服务,因为它不在我的域中。为此,我使用 Spring 的 RestTemplate。

我已经使用过这个,但是当我拨打电话时,它给了我一个 400 bad request 错误。

这是我的代码。

String jsonValue= "[{ \"atr1\" : \"value\" },{ \"atr1\" : \"value\" },{ \"atr1\" : \"value\" },{ \"atr1\" : \"value\" }]";

HttpHeaders headers = new HttpHeaders();
headers.setContentType(MediaType.APPLICATION_JSON);

HttpEntity<String> entity = new HttpEntity<>(jsonValue,headers);

String url = "http://externalServer:9000/pathServer/serviceCalled";

ResponseEntity<String> STRresponse = restTemplate.exchange(url, HttpMethod.POST, entity, String.class);

到 STResponse 的输出打印是

我知道这个请求是正确的,因为当我用邮递员发送它时它工作正常。

我做错了什么?

【问题讨论】:

  • 我尝试但我收到一个错误 org.springframework.http.converter.HttpMessageNotReadableException: 无法读取文档: 无法反序列化 java.util.ArrayList 的实例 out of START_OBJECT token at [Source: java.util.ArrayList io.ByteArrayInputStream@7bb08eeb;行:1,列:1];嵌套异常是 com.fasterxml.jackson.databind.JsonMappingException:无法从 START_OBJECT 令牌中反序列化 java.util.ArrayList 的实例
  • 您确实根据消息发布了一个对象,而不是列表
  • 但服务收到一个列表,我无法更改它

标签: java json spring rest resttemplate


【解决方案1】:

您是否尝试过使用 RequestEntity 而不是 HTTPEntity?

Spring 的 javadoc 有一个示例,您可以参考。

https://docs.spring.io/spring/docs/current/javadoc-api/org/springframework/http/RequestEntity.html

【讨论】:

  • 我试过但结果是一样的 ERROR 400 bad request
【解决方案2】:

正如在 cmets 中所说,尝试使用带有名为 atr1 的字段的某个类 Request,以及带有名为 codemessage 的两个字段的其他类 Result

class Request {
    private String atr1;
    // getter, setter
}

class Result {
    private String code;
    private String message;
    // getter, setter
}

然后

List<Request> data = new ArrayList<>();
Request req1 = new Request();
req1.setAtr1("value");
data.add(req1);
Request req2 = new Request();
req2.setAtr1("value");
data.add(req2);

String url = "http://externalServer:9000/pathServer/serviceCalled";
ResponseEntity<Result> response = restTemplate.postForEntity(url, data, Result.class);

【讨论】:

  • 我收到此错误无法读取文档:无法从 [Source: java.io.PushbackInputStream@11c07e0d; 的 START_OBJECT 令牌中反序列化 java.lang.String 实例\n;行:1,列:1];嵌套异常是 com.fasterxml.jackson.databind.JsonMappingException: Can not deserialize an instance of java.lang.String out of START_OBJECT token\n at [Source: java.io.PushbackInputStream@11c07e0d;行:1,列:1]
  • @EliasVargas 我很糟糕,结果是一个对象而不是字符串(我确实复制了你的代码),请参阅我的编辑
【解决方案3】:

我在删除方法中遇到了rest模板的问题,经过长时间的调试后发现了!这个问题与使用在 rest 模板中使用的 ClientHttpRequestFactory 类的错误配置有关,使用另一个像 SimpleClientHttpRequestFactory 等等,例如我使用下面的代码来支持正文消息的所有方法:

public class CustomSimpleClientHttpRequestFactory extends 
    SimpleClientHttpRequestFactory {

    @Override
    protected void prepareConnection(HttpURLConnection connection, String httpMethod) 
    throws IOException {
        super.prepareConnection(connection, httpMethod);

        connection.setDoOutput(true);
    }
}

并在 RestTemplate 中进行如下配置:

RestTemplate restTemplate = new RestTemplate(new CustomSimpleClientHttpRequestFactory());
restTemplate.getMessageConverters().add(new MappingJacksonHttpMessageConverter());
/* and other configure you like*/

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2017-01-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-01-26
    • 1970-01-01
    相关资源
    最近更新 更多