spring restTemplate乱码问题解决

对于乱码问题网上也是很多方案,有的是直接把返回的string进行转码,不过这样子不具备通用性,比较麻烦,治标不治本,对于另外一种方式其实就是修改restTemplate的bean里面的convertor转换器
通常在引入bean的时候会有如下代码:

    @Bean
    public RestTemplate restTemplate(ClientHttpRequestFactory factory) {
        RestTemplate restTemplate=new RestTemplate(factory);
        return restTemplate;
    }


通过以上代码可以获取到restTemplate的实例,通过断点debug发现以String格式接收数据时,底层采用的是StringHttpMessageConverter来处理请求。查看RestTemplate的构造方法如下:

public RestTemplate() {
    this.messageConverters = new ArrayList();
    this.errorHandler = new DefaultResponseErrorHandler();
    this.uriTemplateHandler = new DefaultUriBuilderFactory();
    this.headersExtractor = new RestTemplate.HeadersExtractor();
    this.messageConverters.add(new ByteArrayHttpMessageConverter());
    this.messageConverters.add(new StringHttpMessageConverter());
    this.messageConverters.add(new ResourceHttpMessageConverter(false));
    this.messageConverters.add(new SourceHttpMessageConverter());
    this.messageConverters.add(new AllEncompassingFormHttpMessageConverter());
    if (romePresent) {
        this.messageConverters.add(new AtomFeedHttpMessageConverter());
        this.messageConverters.add(new RssChannelHttpMessageConverter());
    }

    if (jackson2XmlPresent) {
        this.messageConverters.add(new MappingJackson2XmlHttpMessageConverter());
    } else if (jaxb2Present) {
        this.messageConverters.add(new Jaxb2RootElementHttpMessageConverter());
    }

    if (jackson2Present) {
        this.messageConverters.add(new MappingJackson2HttpMessageConverter());
    } else if (gsonPresent) {
        this.messageConverters.add(new GsonHttpMessageConverter());
    } else if (jsonbPresent) {
        this.messageConverters.add(new JsonbHttpMessageConverter());
    }

    if (jackson2SmilePresent) {
        this.messageConverters.add(new MappingJackson2SmileHttpMessageConverter());
    }

    if (jackson2CborPresent) {
        this.messageConverters.add(new MappingJackson2CborHttpMessageConverter());
    }
}


通过以上代码可以发现对于不同response类型的内容处理器是不一样的
而其中的StringHttpMessageConverter构造方法使用了默认字符集:ISO-8859-1  所以在面对响应格式为string的内容时就会出现乱码的情况,而在大部分通过json格式交互的系统中并不会出现此问题
,为了制定编码格式为UTF-8 ,网上存在一种方式是在RestTemplate的构造函数中,对messageConverters赋值时,在下标为1的位置设置的是StringHttpMessageConverter对象,如下:

RestTemplate restTemplate = new RestTemplate();
restTemplate.getMessageConverters().set(1, new StringHttpMessageConverter(StandardCharsets.UTF_8));


但是这种写死下标的方式是极为不推荐的,因为不排除Spring在后续版本中因为引入了其他转换器而导致下标变化的问题。推荐使用以下方式。
所以本人推荐以下用法:

public static void setRestTemplateEncode(RestTemplate restTemplate) {
    if (null == restTemplate || ObjectUtils.isEmpty(restTemplate.getMessageConverters())) {
        return;
    }

    List<HttpMessageConverter<?>> messageConverters = restTemplate.getMessageConverters();
    for (int i = 0; i < messageConverters.size(); i++) {
        HttpMessageConverter<?> httpMessageConverter = messageConverters.get(i);
        if (httpMessageConverter.getClass().equals(StringHttpMessageConverter.class)) {
            messageConverters.set(i, new StringHttpMessageConverter(StandardCharsets.UTF_8));
        }
    }
}


通过新增的方法,将RestTemplate对象传递进去,内部遍历messageConverters,找到StringHttpMessageConverter并替换为UTF-8格式的StringHttpMessageConverter对象即可。

此方法在restTemplate构造的时候执行就好了,如下:

@Bean
public RestTemplate restTemplate(ClientHttpRequestFactory factory) {
    RestTemplate restTemplate=new RestTemplate(factory);
    setRestTemplateEncode(restTemplate);
    return restTemplate;
}

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

alexander137

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值