美文网首页Spring Boot
RestTemplate或者AsyncRestTemplate设

RestTemplate或者AsyncRestTemplate设

作者: else05 | 来源:发表于2018-05-23 14:11 被阅读137次

环境:

jdk: 8
spring-boot: 2.x

一、问题描述

  1. 在spring-boot 项目中使用RestTemplate和AsyncRestTemplate,RestTemplate发送请求时不会出现乱码,但是AsyncRestTemplate会出现乱码情况

二、问题分析

  1. 首先想到是加请求头 application/json;charset=utf-8 , RestTemplate没问题,AsyncRestTemplate依旧乱码。
HttpHeaders headers = new HttpHeaders();
// 等价  ContentType: application/json;charset=utf-8
headers.add(HttpHeaders.CONTENT_TYPE, ContentType.APPLICATION_JSON.getMimeType());
asyncRestTemplate.postForEntity(url, new HttpEntity<>(data,headers), ResponseModel.class);
  1. 断点查看 MessageConverters
  • RestTemplate : 有两个StringHttpMessageConverter ,分别对应 UTF-8ISO-8859-1 编码
    RestTemplate
  • AsyncRestTemplate : 只有一个StringHttpMessageConverter ,对应 ISO-8859-1 编码
    AsyncRestTemplate

综上所述,可以看到 AsyncRestTemplate 默认缺少 utf-8 的解析器 , 所以造成无法编码成utf-8

三、解决方式 (两种方式差不多)

  1. 增加一个 UTF-8 解析器 (第一种)
    private AsyncRestTemplate asyncRestTemplate ;

    @PostConstruct
    public void init(){
        asyncRestTemplate = new AsyncRestTemplate() ;
        // 增加一个 utf-8 解析器
        asyncRestTemplate.getMessageConverters().add(0, new StringHttpMessageConverter(Charset.forName("UTF-8")));
    }
  1. 删除原有的 StringHttpMessageConverter , 然后重新添加 UTF-8 解析器 (第二种)
    private AsyncRestTemplate asyncRestTemplate ;

    @PostConstruct
    public void init(){
        asyncRestTemplate = new AsyncRestTemplate() ;
        // 删除所有的 StringHttpMessageConverter
        Iterator<HttpMessageConverter<?>> iterator = asyncRestTemplate.getMessageConverters().iterator();
        while (iterator.hasNext()) {
            final HttpMessageConverter<?> converter = iterator.next();
            if (converter instanceof StringHttpMessageConverter) {
                iterator.remove();
            }
        }
        // 添加 UTF-8 的解析器
        asyncRestTemplate.getMessageConverters().add(0, new StringHttpMessageConverter(Charset.forName("UTF-8")));
    }

注意 :增加解析器后,最好在 postputdelete 请求增加contentType 头信息,类似如下

HttpHeaders headers = new HttpHeaders();
// 等价  ContentType: application/json;charset=utf-8
headers.add(HttpHeaders.CONTENT_TYPE, ContentType.APPLICATION_JSON.getMimeType());
asyncRestTemplate.postForEntity(url, new HttpEntity<>(data,headers), ResponseModel.class);

相关文章

网友评论

  • 殷建卫:我看了一下,应该是StringHttpMessageConverter.readInternal方法处理了编码问题
    @Override
    protected String readInternal(Class<? extends String> clazz, HttpInputMessage inputMessage) throws IOException {
    Charset charset = getContentTypeCharset(inputMessage.getHeaders().getContentType());
    return StreamUtils.copyToString(inputMessage.getBody(), charset);
    }
    再进到getContentTypeCharset方法中
    private Charset getContentTypeCharset(MediaType contentType) {
    if (contentType != null && contentType.getCharset() != null) {
    return contentType.getCharset();
    }
    else {
    return getDefaultCharset();
    }
    }
    如果response中header存在如下内容,就可以获取charset
    Content-Type:application/json;charset=UTF-8

本文标题:RestTemplate或者AsyncRestTemplate设

本文链接:https://www.haomeiwen.com/subject/ejfrjftx.html