欢迎来到我有一个朋友系列。坦白讲,从没想过总结什么的,但从事java开发这几年,多少还是有些要总结记录的。不会畏惧从零开始,只要够持久。
我有一个朋友开发中遇到一个问题,使用restTemplate的postForEntity方法,返回值为ResponseEntity时,发现getBody时中文为乱码以及???,怎么这个样子。 大概代码Demo如下:
public ResponseModel test(){
ResponseEntity<String> responseEntity = restTemplate.postForEntity("http://ip:port/something"
,new HttpEntity<String>("{}",new HttpHeaders(){{setContentType(MediaType.APPLICATION_JSON); }}),String.class);
return ResponseModel.ok(responseEntity.getBody());}指定了contentType APPLICATION_JSON
并且restTemplate使用的是默认配置直接注入
先说这边的两个解决方案
1.配置restTemplate,替换默认StringHttpMessageConverter
restTemplate.getMessageConverters().set(1,new StringHttpMessageConverter(StandardCharsets.UTF_8));2.Header中添加Accept,以及修改ContentType
new HttpHeaders(){{
setContentType(MediaType.APPLICATION_JSON_UTF8);
setAccept(new ArrayList<MediaType>(){{
add(MediaType.APPLICATION_JSON_UTF8);
}});
}}这边说一下自己并没有底气的个人理解:
首先,restTemplate默认配置中使用的StringConverter点进去可以看到,默认编码格式
public static final Charset DEFAULT_CHARSET = StandardCharsets.ISO_8859_1;所以我们使用一个新的UTF-8 converter替换,至于为什么set(1,x),部分空构造器代码如下
public RestTemplate() {
this.messageConverters.add(new ByteArrayHttpMessageConverter());
this.messageConverters.add(new StringHttpMessageConverter()); //在这在这在这
this.messageConverters.add(new ResourceHttpMessageConverter(false));
try {
this.messageConverters.add(new SourceHttpMessageConverter<>());
} catch (Error err) {
// Ignore when no TransformerFactory implementation is available
}第二种呢,之前只添加了一个Accept MediaType.APPLICATION_JSON_UTF8
Accept 请求头用来告知(服务器)客户端可以处理的内容类型,这种内容类型用MIME类型来表示
结果,返回第一层的message信息成功展示为中文,but,对象中的用户名依然为???
???????
修改contentType 为 MediaType.APPLICATION_JSON_UTF8, 大功告成。
这其中有两个小波折,暂存两个小问题
1. 改的时候发现header有个setAcceptCharset 想当然的使用了这个方法,然后没有任何作用,????????
Accept-Charset 请求头用来告知(服务器)客户端可以处理的字符集类型。
2.自测demo时发现
/**
* Public constant media type for {@code application/json;charset=UTF-8}.
* @deprecated Deprecated as of Spring Framework 5.2 in favor of {@link #APPLICATION_JSON}
* since major browsers like Chrome
* <a href="https://bugs.chromium.org/p/chromium/issues/detail?id=438464">
* now comply with the specification</a> and interpret correctly UTF-8 special
* characters without requiring a {@code charset=UTF-8} parameter.
*/
@Deprecated
public static final MediaType APPLICATION_JSON_UTF8; 浏览器支持可以,这边restTemplate如果去掉UTF-8貌似没有效果,有点儿方,先记下