我只是想做一个简单的REST请求,如下面的
String url = "some url";
MultiValueMap<String, String> headers = new LinkedMultiValueMap<>();
headers.add(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_JSON_VALUE);
headers.add(HttpHeaders.AUTHORIZATION, "some authorization");
RestTemplate restTemplate = new RestTemplate();
restTemplate.getMessageConverters().add(new MappingJackson2HttpMessageConverter());
Body body = new Body();
body.setRemarks("test");
org.springframework.http.HttpEntity request = new org.springframework.http.HttpEntity(body, headers);
try {
ResponseEntity<String> response = restTemplate.exchange(url, HttpMethod.PUT, request, String.class);
System.out.println("Status Response: "+ response.getStatusCode() +". Body: "+ response.getBody());
} catch (HttpClientErrorException | HttpServerErrorException e) {
e.printStackTrace();
} catch (Exception e) {
e.printStackTrace();
}
问题是我每次在Java中执行此操作时结果都是不可预测的,我通常会一直收到此错误。
org.springframework.http.InvalidMediaTypeException: Invalid mime type "text/plain, application/json, application/json, application/*+json, application/*+json, */*; charset=UTF-8": Invalid token character ',' in token "plain, application/json, application/json, application/*+json, application/*+json, */*"
at org.springframework.http.MediaType.parseMediaType(MediaType.java:452)
at org.springframework.http.HttpHeaders.getContentType(HttpHeaders.java:745)
at org.springframework.web.client.DefaultResponseErrorHandler.getCharset(DefaultResponseErrorHandler.java:115)
at org.springframework.web.client.DefaultResponseErrorHandler.handleError(DefaultResponseErrorHandler.java:63)
at org.springframework.web.client.RestTemplate.handleResponse(RestTemplate.java:700)
at org.springframework.web.client.RestTemplate.doExecute(RestTemplate.java:653)
at org.springframework.web.client.RestTemplate.execute(RestTemplate.java:613)
at org.springframework.web.client.RestTemplate.exchange(RestTemplate.java:531)
然而,当我通过邮递员尝试相同的请求时,它可以工作。我错过了一些非常简单的事情,我不知道是什么。
我查看了Postman和标题的回复,它们似乎保持良好状态Content-Type →application/json; charset=UTF-8
,响应也很好。
我也无法确定请求或响应是针对哪个Rest模板出现问题的哪个部分。
答案 0 :(得分:2)
在我的案例中,简短的回答是在提出请求之前添加这些额外的标题。
headers.add(HttpHeaders.ACCEPT, MediaType.APPLICATION_JSON_VALUE);
headers.add(HttpHeaders.ACCEPT_CHARSET, StandardCharsets.UTF_8.name());
答案很长:感谢Nikolay Shevchenko's建议使用调试器来挖掘出当服务器上出现错误时RestTemplate
试图从响应中收集所有标题和正文以创建合理的异常消息。在尝试从响应中创建该消息时,它获得了mime类型
text/plain, application/json, application/json, application/*+json, application/*+json, */*; charset=UTF-8
是Postman针对同一请求显示的整个文本长度而不是application/json; charset=UTF-8
。因此,在我尝试parse over上面提供的mime类型的旧版Spring rest模板版本的情况下,它会失败,产生此消息。
org.springframework.http.InvalidMediaTypeException: Invalid mime type "text/plain, application/json, application/json, application/*+json, application/*+json, */*; charset=UTF-8": Invalid token character ',' in token "plain, application/json, application/json, application/*+json, application/*+json, */*"
因此,不是获得服务器错误,而是更精细的mime类型异常从更深的堆栈中冒出来,对于您正在搜索的内容没有任何意义。
根据this post RestTemplate
M. Deinum StringHttpMessageConverter
使用restTemplate.getMessageConverters().add(new MappingJackson2HttpMessageConverter());
的最终结果如何,尽管我已将Jackson指定为Http Message转换器,如下所示。
StringHttpMessageConverter
正如前面提到的writeAcceptCharset
true
{{}}} {{}}} {{}}} {{}}} {{}} {{}} {{}} {{}}在上面提到的帖子中,解决方案是将writeAcceptCharset
设为false
或不写简单字符串但使用对象然后将其编组为字符串。
对于我的用例,我希望响应类型为application/json
且字符集为UTF-8
,因此在配置中设置这些接受标头可以解决我的问题。