在微服务之间互相调用restful api的时候有会遇到406问题,
比如异常 HttpMediaTypeNotAcceptableException 或 HttpClientErrorException:406
使用restTemplate.exchange()或者execute()等方法调用Restful API call 去获取一个json或者xml并解析到pojo的时候:
(下列程序XMLPOJO为一个xml存储对象, 可以是@JacksonXmlRootElement(localName = "xml")的类等)
ResponseEntity<XMLPOJO> response = restTemplate.exchange("https//xxxx.xxxx.xxx/xxx/xx", HttpMethod.POST, entity, XMLPOJO.class);
如果返回406, 或者报异常: org.springframework.web.client.HttpClientErrorException$NOT ACCEPTABLE: 406
说明server返回的值和你需求的值不匹配..
比如我们有server端controller代码:
@RequestMapping(value = "/api1", method = RequestMethod.POST, produces = MediaType.TEXT_PLAIN_VALUE)
public ResponseEntity<String> chat(@RequestBody String info, final HttpServletRequest request) {
xxxx;
}
可以看到 我们调用了server并需求一个 XML格式的返回,但是server端定义 produces的是一个text/plain, 导致plain text 不一定能转化为xml,就出了406错误。 (注意,此处是说不一定,而不是100%的返回不能)
baeldung对406也给出了说明:
https://www.baeldung.com/spring-httpmediatypenotacceptable
解决方案:
方案1:
首先把client端的微服务接受值改成string, 然后手动或者用jackson来解析string为xml对象: (e.g. 下列程序xmlParse()为手动编写的xml解析方法)。 一般来说ResponseEntity<String> 可以hold的住绝大部分的返回值。-> 建议一直用String
ResponseEntity<String> response = restTemplate.exchange("https//xxxx.xxxx.xxx/xxx/xx", HttpMethod.POST, entity, String.class);
XMLPOJO xml = xmlParse(response);
方案2:
把server端的produces改成xml, 这个改动较大, 可能影响其他client调用...慎用!
@RequestMapping(value = "/api1", method = RequestMethod.POST, produces = MediaType.APPLICATION_XML_VALUE)
public ResponseEntity<String> chat(@RequestBody String info, final HttpServletRequest request) {
xxxx;
}
个人倾向于方案1,修改client端的接受值,对server端微服务影响较小。 |