RestTemplate中文乱码完美解决方案

40次阅读

共计 1558 个字符,预计需要花费 4 分钟才能阅读完成。

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 对象即可。

以上方式自己亲测可用,如果使用了上述方式还是乱码的话,可以排查下是不是后端没有设置编码格式

正文完
 0