SpringBoot restTemplate中文乱码问题

转载自:https://blog.csdn.net/zhanshenzhi2008/article/details/79186663

在网上尝试了多种方案,最终这个可以有效解决,为了避免大家走弯路,在此分享下。

前一段时间接触SpringBoot,要搭建访问其他系统的架构,于是用Rest技术访问其他系统。

问题

用String res = restTemplate.postForObject(url, param, String.class获取String类型的时候,发现乱码。

原因

通过源码Debug发现,主要是StringHttpMessageConverter这个类默认类型并不是utf-8,而是ISO-8859-8,所以要解决这个问题,就得修改这个类的字符集。

错误的解决方案

之前看过网上的解决方案: 
1. 通过restTemplate.getMessageConverters方法获取List<HttpMessageConverter<?>> , 
2. 然后循环并将StringHttpMessageConverter移出掉,然后再循环体外add一个newHttpMessageConverter类且字符集已设为utf-8

以上方案的问题所在

这种方案其实在调用restTemplate.postForObject(url, param, String.class获取String类型的时候会报错,因为RestTemplatefor循环messageConverters,依次去处理String类型的response,而StringHttpMessageConverter是属于第二个,最后一个是jackson转换类,那么add进去的是最后一个转换类,那么string类型的过去在jackson转换类里就会报错,jackson要求的类型JsonArray类型的参数。

最终解决方案:

循环体内获取对应的对应的转换类,然后调用自己的setDefaultCharset(StandardCharset.UTF-8)即可。代码如下(以下有些代码是刚刚自己手动敲的,还没有检查语法问题,不过方案在公司已经测试过,不会有问题。):

      @Configuration 
public class RestConfiguration { 
    @Bean 
    @ConditionalOnMissingBean({RestOperations.class, RestTemplate.class}) 
    public RestOperations restOperations() { 

//        SimpleClientHttpRequestFactory requestFactory = new SimpleClientHttpRequestFactory(); 
//        requestFactory.setReadTimeout(5000); 
//        requestFactory.setConnectTimeout(5000); 

        CloseableHttpClient httpClient = null; 
        try { 
            httpClient = HttpClientUtils.acceptsUntrustedCertsHttpClient(); 
        } catch (KeyManagementException e) { 
            // TODO Auto-generated catch block 
            e.printStackTrace(); 
        } catch (KeyStoreException e) { 
            // TODO Auto-generated catch block 
            e.printStackTrace(); 
        } catch (NoSuchAlgorithmException e) { 
            // TODO Auto-generated catch block 
            e.printStackTrace(); 
        } 
        HttpComponentsClientHttpRequestFactory clientHttpRequestFactory = new HttpComponentsClientHttpRequestFactory(httpClient); 

        RestTemplate restTemplate = new RestTemplate(clientHttpRequestFactory); 

        // 使用 utf-8 编码集的 conver 替换默认的 conver(默认的 string conver 的编码集为 "ISO-8859-1") 
        ****List<HttpMessageConverter<?>> messageConverters = restTemplate.getMessageConverters(); 
        Iterator<HttpMessageConverter<?>> iterator = messageConverters.iterator(); 
        while (iterator.hasNext()) { 
            HttpMessageConverter<?> converter = iterator.next(); 
            if (converter instanceof StringHttpMessageConverter) { 
                ((StringHttpMessageConverter)converter).setDefaultCharset(StandardCharset.UTF_8)
            } 
        }  
        // 解决text/plain的,比如微信等
        restTemplate.getMessageConverter().add(new NewMappingJackJson2HttpMessageConverter())
        return restTemplate; 
    }**** 
}
/**
* 由于默认构造的MappingJackson2HttpMessageConverter中的supportedMediaTypes只支持:applicantion/json的,所以再添加MediaType.TEXT_PLAIN的MediaType的支持
*/
public static finanl class NewMappingJackson2HttpMessageConverter extends MappingJackon2HttpMessageConverter{
     public NewMappingJackson2HttpMessageConverter(){
     List<MediaType> mediaTypes = new ArrayList<>();
     mediaTypes.add(MediaType.TEXT_PLAIN);
     setSupportedMediaTypes(mediaTypes);
}
}
  •  

猜你喜欢

转载自blog.csdn.net/meng19910117/article/details/81558187