前言:
在公司写一些请求封装的接口,按照以往的 Ctrl+C 和 Ctrl + V 是没什么问题的,这不,很不巧就翻车了,起初怀疑我 copy 漏,原来是这次的文档请求有些不一样。
正文
报错:
<302,<html><head><title>Object moved</title></head><body>
<h2>Object moved to <a href="/WebSiteError.aspx">here</a>.</h2>
</body></html>
,[Via:"1.1 SZTMG05", Connection:"Keep-Alive", Proxy-Connection:"Keep-Alive", Transfer-Encoding:"chunked", Date:"Tue, 22 Sep 2020 07:31:38 GMT", Location:"/WebSiteError.aspx", Content-Type:"text/html; charset=utf-8", Server:"Microsoft-IIS/8.5", Cache-Control:"private", X-AspNet-Version:"4.0.30319", X-Powered-By:"ASP.NET", Access-Control-Allow-Origin:"*"]>
2020-09-22 15:38:12.366 ERROR 12764 --- [io-10003-exec-9] o.a.c.c.C.[.[.[/].[dispatcherServlet] : Servlet.service() for servlet [dispatcherServlet] in context with path [] threw exception [Request processing failed; nested exception is com.alibaba.fastjson.JSONException: syntax error, expect {, actual error, pos 0, fastjson-version 1.2.58] with root cause
com.alibaba.fastjson.JSONException: syntax error, expect {, actual error, pos 0, fastjson-version 1.2.58
解决
好家伙,这次文档请求体要求入参是 application/x-www-form-urlencoded 格式,跟以往的 copy 稍微不同,最好采用 map 转换入参。
你敢信,都 0202 年了,我特么能遇到 .net 的项目…虽然我只是封装 .net 暴露出来的接口。
更改后
ResponseEntity<String> responseEntity = null;
MultiValueMap<String, String> map = new LinkedMultiValueMap<>();
map.add("aaa", xxxParam.getAAA());
map.add("bbb", xxxParam.getBBB());
map.add("ccc", xxxParam.getCCC());
HttpHeaders headers = new HttpHeaders();
headers.setContentType(MediaType.APPLICATION_FORM_URLENCODED);
HttpEntity<MultiValueMap<String, String>> stringHttpEntity = new HttpEntity<>(map, headers);
responseEntity = restTemplate.postForEntity(url, stringHttpEntity, String.class);
有时候会遇到报 406 Not Acceptable 的错误
注释: **406**
Not Acceptable
状态码表示客户端错误,指代服务器端无法提供与 Accept-Charset
以及 Accept-Language
消息头指定的值相匹配的响应。
搜索才得知
原来请求头和响应头 的 Content-Type 根据文档来(application/x-www-form-urlencoded 或者 application/json)
解决,可以在实现类里加点东西
HttpHeaders headers = new HttpHeaders();
headers.setContentType(MediaType.APPLICATION_FORM_URLENCODED);
或
在Controller 层
produces 属性 用于匹配页面的请求头Accept信息是否和响应头Accept信息(produces设置)一致。
@PostMapping(value = "/yyy", produces = MediaType.APPLICATION_JSON_VALUE)
public void XXXController{
//TODO
}