RestTemplate編碼格式改為UTF-8,防止亂碼
我是在調用微信的API 的時候發現微信給我返回的用戶數據不能夠正常顯示昵稱,昵稱都是亂碼。
1
2
3
4
5
6
7
8
9
10
|
//修改RestTemplate的編碼格式為UTF-8 RestTemplate restTemplate = new RestTemplate(); List<HttpMessageConverter<?>> httpMessageConverters = restTemplate.getMessageConverters(); httpMessageConverters.stream().forEach(httpMessageConverter -> { if (httpMessageConverter instanceof StringHttpMessageConverter){ StringHttpMessageConverter messageConverter = (StringHttpMessageConverter) httpMessageConverter; messageConverter.setDefaultCharset(Charset.forName( "UTF-8" )); } //發送請求 String jsonStr = restTemplate.getForEntity(url, String. class ).getBody(); |
上面的代碼中很簡單的寫出來了,直接自己分裝成一個方法就好。這樣就解決了中文的亂碼問題了
RestTemplate 中文亂碼配置
restTemplate作為spring web client下的一個工具類 對http請求做了一層封裝,用起來也更加簡潔容易,但最近遇到一個問題就是在發送請求時由于請求中包含中文導致亂碼,都變成???????一堆問號,網上很多解決方案,但很多都比較…..
先看說如何解決
@Bean配置方法:
1
2
3
4
5
6
|
@Bean public RestTemplate restTemplate() { RestTemplate restTemplate = new RestTemplate(); restTemplate.getMessageConverters().set( 1 , new StringHttpMessageConverter(StandardCharsets.UTF_8)); return restTemplate; } |
applicationContext.xml配置方法:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
|
<? xml version = "1.0" encoding = "UTF-8" ?> < beans xmlns = "http://www.springframework.org/schema/beans" xmlns:xsi = "http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation = "http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd" default-autowire = "byName" default-lazy-init = "true" > <!--方式一、使用jdk的實現--> < bean id = "ky.requestFactory" class = "org.springframework.http.client.SimpleClientHttpRequestFactory" > < property name = "readTimeout" value = "10000" /> < property name = "connectTimeout" value = "5000" /> </ bean > < bean id = "simpleRestTemplate" class = "org.springframework.web.client.RestTemplate" > < constructor-arg ref = "ky.requestFactory" /> < property name = "messageConverters" > < list > < bean class = "org.springframework.http.converter.FormHttpMessageConverter" /> < bean class = "org.springframework.http.converter.xml.MappingJackson2XmlHttpMessageConverter" /> < bean class = "org.springframework.http.converter.json.MappingJackson2HttpMessageConverter" /> < bean class = "org.springframework.http.converter.StringHttpMessageConverter" > < property name = "supportedMediaTypes" > < list > < value >text/plain;charset=UTF-8</ value > </ list > </ property > </ bean > </ list > </ property > </ bean > </ beans > |
然后在使用的地方自動注入就好啦~~
再看看為什么會亂碼
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
|
public RestTemplate() { this .messageConverters.add( new ByteArrayHttpMessageConverter()); this .messageConverters.add( new StringHttpMessageConverter()); this .messageConverters.add( new ResourceHttpMessageConverter()); this .messageConverters.add( new SourceHttpMessageConverter<Source>()); this .messageConverters.add( new AllEncompassingFormHttpMessageConverter()); if (romePresent) { this .messageConverters.add( new AtomFeedHttpMessageConverter()); this .messageConverters.add( new RssChannelHttpMessageConverter()); } if (jaxb2Present) { this .messageConverters.add( new Jaxb2RootElementHttpMessageConverter()); } if (jackson2Present) { this .messageConverters.add( new MappingJackson2HttpMessageConverter()); } else if (jacksonPresent) { this .messageConverters.add( new MappingJacksonHttpMessageConverter()); } } |
從RestTemplate 構造方法可以看出restTemplate默認的messageConverters有好幾個,這次的主角是StringHttpMessageConverter:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
|
public class StringHttpMessageConverter extends AbstractHttpMessageConverter<String> { public static final Charset DEFAULT_CHARSET = Charset.forName( "ISO-8859-1" ); private final Charset defaultCharset; private final List<Charset> availableCharsets; private boolean writeAcceptCharset = true ; /** * A default constructor that uses {@code "ISO-8859-1"} as the default charset. * @see #StringHttpMessageConverter(Charset) */ public StringHttpMessageConverter() { this (DEFAULT_CHARSET); } /** * A constructor accepting a default charset to use if the requested content * type does not specify one. */ public StringHttpMessageConverter(Charset defaultCharset) { super ( new MediaType( "text" , "plain" , defaultCharset), MediaType.ALL); this .defaultCharset = defaultCharset; this .availableCharsets = new ArrayList<Charset>(Charset.availableCharsets().values()); } /** * Indicates whether the {@code Accept-Charset} should be written to any outgoing request. * <p>Default is {@code true}. */ public void setWriteAcceptCharset( boolean writeAcceptCharset) { this .writeAcceptCharset = writeAcceptCharset; } @Override public boolean supports(Class<?> clazz) { return String. class .equals(clazz); } @Override protected String readInternal(Class<? extends String> clazz, HttpInputMessage inputMessage) throws IOException { Charset charset = getContentTypeCharset(inputMessage.getHeaders().getContentType()); return StreamUtils.copyToString(inputMessage.getBody(), charset); } @Override protected Long getContentLength(String s, MediaType contentType) { Charset charset = getContentTypeCharset(contentType); try { return ( long ) s.getBytes(charset.name()).length; } catch (UnsupportedEncodingException ex) { // should not occur throw new IllegalStateException(ex); } } @Override protected void writeInternal(String s, HttpOutputMessage outputMessage) throws IOException { if ( this .writeAcceptCharset) { outputMessage.getHeaders().setAcceptCharset(getAcceptedCharsets()); } Charset charset = getContentTypeCharset(outputMessage.getHeaders().getContentType()); StreamUtils.copy(s, charset, outputMessage.getBody()); } /** * Return the list of supported {@link Charset}. * <p>By default, returns {@link Charset#availableCharsets()}. Can be overridden in subclasses. * @return the list of accepted charsets */ protected List<Charset> getAcceptedCharsets() { return this .availableCharsets; } private Charset getContentTypeCharset(MediaType contentType) { if (contentType != null && contentType.getCharSet() != null ) { return contentType.getCharSet(); } else { return this .defaultCharset; } } } |
可以看到StringHttpMessageConverter默認是ISO-8859-1編碼(有空可以看下別的MessageConverter其實都是UTF-8的),所以就把它改了就好啦~
以上為個人經驗,希望能給大家一個參考,也希望大家多多支持服務器之家。
原文鏈接:https://blog.csdn.net/myhAini/article/details/106280085