RestTemplate请求406错误、中文乱码问题

使用RestTemplate请求某第三方API时,当未添加 系统中的convert时会出现406错误,添加了convert后,会出现中文乱码。

调查结果:

  1. 406是因为 该第三方API需要Accept为"text/plain"或*/*或其他的(我不知道他具体要什么),
  2. 请求头中的中文乱码是当Accept为"text/plain"时响应即为中文乱码。

源码跟踪:

org.springframework.web.client.RestTemplate.AcceptHeaderRequestCallback#doWithRequest

技术点:

RestTemplate会把它的MessageConverters支持的媒体类型(即可解析的媒体类型)放到Accept中发送该请求。

业务问题:

因为第三方API的设定http请求中的Accept中不包含*/*或"text/plain"时会响应406。

技术问题:

没有MessageConverter可支持*/*或"text/plain"。

解决方案:

添加MessageConverter可支持*/*
@Override
		public void doWithRequest(ClientHttpRequest request) throws IOException {
			if (this.responseType != null) {
				Class<?> responseClass = null;
				if (this.responseType instanceof Class) {
					responseClass = (Class<?>) this.responseType;
				}
				List<MediaType> allSupportedMediaTypes = new ArrayList<>();
				for (HttpMessageConverter<?> converter : getMessageConverters()) {
					if (responseClass != null) {
						if (converter.canRead(responseClass, null)) {
							allSupportedMediaTypes.addAll(getSupportedMediaTypes(converter));
						}
					}
					else if (converter instanceof GenericHttpMessageConverter) {
						GenericHttpMessageConverter<?> genericConverter = (GenericHttpMessageConverter<?>) converter;
						if (genericConverter.canRead(this.responseType, null, null)) {

// 请求发出之前,根据RestTemplate的Converts能转换哪些,放到Accept中发送该请求。
							allSupportedMediaTypes.addAll(getSupportedMediaTypes(converter));
						}
					}
				}
				if (!allSupportedMediaTypes.isEmpty()) {
					MediaType.sortBySpecificity(allSupportedMediaTypes);
					if (logger.isDebugEnabled()) {
						logger.debug("Setting request Accept header to " + allSupportedMediaTypes);
					}
					request.getHeaders().setAccept(allSupportedMediaTypes);
				}
			}

Accpet和ContentType:

1.Accept属于请求头, Content-Type属于实体头。
Http报头分为通用报头,请求报头,响应报头和实体报头。
请求方的http报头结构:通用报头|请求报头|实体报头
响应方的http报头结构:通用报头|响应报头|实体报头

2.Accept代表发送端(客户端)希望接受的数据类型。
比如:Accept:text/xml(application/json);
代表客户端希望接受的数据类型是xml(json )类型
Content-Type代表发送端(客户端|服务器)发送的实体数据的数据类型。

比如:Content-Type:text/html(application/json) ;
代表发送端发送的数据格式是html(json)。
二者合起来,

Accept:text/xml;
Content-Type:text/html

即代表希望接受的数据类型是xml格式,本次请求发送的数据的数据格式是html。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值