[Restful] 执行 RestTemplate 时返回406 NOT Acceptable HttpClientErrorExceptio

论坛 期权论坛 编程之家     
选择匿名的用户   2021-6-2 20:41   2340   0

在微服务之间互相调用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端微服务影响较小。

分享到 :
0 人收藏
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

积分:3875789
帖子:775174
精华:0
期权论坛 期权论坛
发布
内容

下载期权论坛手机APP