最容易被忽视Http请求中的Accept

最近在进行三方接口联调的时候,发现了一个问题,这边给第三方返回响应的数据类型设计的是JSON的形式,但是我拿到响应结果的时候,需要对响应结果进行解析之后然后进行格式化再返回给调用方,但是当我使用

JSONObject jsonObject = JSONObject.parseObject(responseData);

这一段代码的时候,报错了。然后就进行了排查,在过滤器filter中打印了请求头的content-type,

ServerHttpRequest request = exchange.getRequest();
        HttpHeaders headers = request.getHeaders();

发现打印出来的结果是Content-type:application/json,而且我设计Controller层也是有注解RestController注解的,返回响应结果也是类型也是JSON,然后我就看了一下报错的结果是:

com.alibaba.fastjson2.JSONException: illegal input, offset 1, char <

很奇怪,这个报错,完全没有思路,然后我就搜索了一些辅助工具,说是JSON解析异常,然后我就打印了返回结果发现是一个xml格式,我就纳闷了,为啥是xml格式,明明打印出来请求头header中的content-type是application/json,然后我就在我的过滤器里面,对请求头的content-type重新进行赋值一遍

header.put("Content-Type",Arrays.asList("application/json"));

发现还是不行,然后我就着重看一下header里面的详细数据,发现有一个叫做Accept的,它的值是:

text/plain,application/xml,text/xml.application/json.application/*+xml,application/*+json,*/*

我就想会不会是这个Accept的问题,然后我就了解了一下这个Accept的含义。

这个Accept是代表客户端希望服务器响应的类型,但是现在服务器返回的响应类型是JSON,(大家可以查看Http请求头中的内容还有哪些,以及响应头中的内容还有哪些,进行归纳整理)那么

HttpMessageConverter就会对我们的响应类型JSON进行转化,spring就将JSON转化为xml格式,然后设置到响应头中的content-type:application/xml,然后再把响应结果返回给客户端。这时候xml就无法转化成JSON。所以就报错了,那么为什么我平常前端界面发出的请求也没有设置这个Accpet,为什么就不会报错呢,那是因为默认就给我们设置成application/json,那为什么这次的默认值是这么长,因为在进行三方接口调用的时候,一般我们都会用一些http工具,比如restTemplate,或者是httpClient等http请求方法,对于这些的话,默认就不是application/json了

总结:

所以服务器会响应什么数据类型并不是你接口决定是什么类型就一定返回什么类型,而是根据请求的请求头部中的Accept决定的。如果和Accept不一致的话,

        HttpMessageConverter

就会转成Accept对应的类型进行返回。

所以以后遇到需要调用第三方接口的时候,我们最好自己通过代码设置Accept为我们希望响应的数据类型。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值