RestTemplate中文亂碼完美解決方案

RestTemplate中對字符串使用的是StringHttpMessageConverter中默認的編碼

public class StringHttpMessageConverter extends AbstractHttpMessageConverter<String> {
    //省略其他代碼
    public static final Charset DEFAULT_CHARSET = StandardCharsets.ISO_8859_1;
}

ISO_8859_1編碼格下,中文是亂碼的。因此我們需要將編碼格式設置爲UTF-8的格式才能支持中文。
網絡上大部分的教程都是通過以下方式來修改編碼格式

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

原因是在RestTemplate的構造函數中,對messageConverters賦值時,在下標爲1的位置設置的是StringHttpMessageConverter對象。

public class RestTemplate extends InterceptingHttpAccessor implements RestOperations {
    public RestTemplate() {
        this.messageConverters.add(new ByteArrayHttpMessageConverter());
        this.messageConverters.add(new StringHttpMessageConverter());//此處設置
        this.messageConverters.add(new ResourceHttpMessageConverter(false));
        //省略其他代碼
    }
}

但是這種寫死下標的方式是極爲不推薦的,因爲不排除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對象即可。

以上方式自己親測可用,如果使用了上述方式還是亂碼的話,可以排查下是不是後端沒有設置編碼格式
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章