如何解决SpringBoot中RestTemplate的中文乱码问题?
Posted DreamMakers
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了如何解决SpringBoot中RestTemplate的中文乱码问题?相关的知识,希望对你有一定的参考价值。
如何解决SpringBoot中RestTemplate的中文乱码问题?
背景
最近在使用SpringBoot开发新的项目,说来惭愧,工作五年了,竟然一直没有用过SpringBoot框架,之前的开发项目基本都是基于Spring和SpringMVC框架实现的,所以在SpringBoot这块也算是个新手吧。上周末抽了点时间把SpringBoot的官网说明文档从头到尾看了一遍,算是对SpringBoot有了基本的了解吧。
什么是中文乱码问题?
既然进来看这篇文章了,那你肯定是个码农了,既然是码农了,那你要说你没碰到过中文乱码的问题,那只能说明你运气太好了。简单点说,就是在处理中文时,并没有按照我们的期望拿到对应的中文,而是各种乱七八糟的字符。
在SpringBoot中有哪些发送http请求的方式?
在应用程序编写过程中,我们基本上都要和外部的服务打交道,这时候,通过我们都需要构造和发送HTTP请求,那么在SpringBoot中有哪些发送HTTP请求的方式呢?
通过阅读SpringBoot Reference页面,我们可以看到有两种方式。
- 通过RestTemplate请求
- 通过WebClient请求
关于WebClient怎么用,可以参看具体的说明。
SpringBoot中关于RestTemplate的说明
下面是我对官网14小节内容的简单翻译,大家可以凑合着看。
If you need to call remote REST services from your application, you can use the Spring Framework’s RestTemplate class. Since RestTemplate instances often need to be customized before being used, Spring Boot does not provide any single auto-configured RestTemplate bean. It does, however, auto-configure a RestTemplateBuilder, which can be used to create RestTemplate instances when needed. The auto-configured RestTemplateBuilder ensures that sensible HttpMessageConverters are applied to RestTemplate instances.
如果你需要从你的应用程序调用远程REST服务,你可以使用Spring框架的RestTemplate类。虽然RestTemplate实例经常需要定制化,但是SpringBoot并没有提供任何自定义配置的RestTemplate实例bean。然而,在SpringBoot中,通过一个自配置的RestTemplateBuilder,我们可以创建我们需要的RestTemplate实例。自动配置的RestTemplateBuilder确保将敏感的httpmessageconverter应用于RestTemplate实例。
The following code shows a typical example:
下面的代码展示了一个典型的示例:
@Service
public class MyService
private final RestTemplate restTemplate;
public MyService(RestTemplateBuilder restTemplateBuilder)
this.restTemplate = restTemplateBuilder.build();
public Details someRestCall(String name)
return this.restTemplate.getForObject("/name/details", Details.class, name);
There are three main approaches to RestTemplate customization, depending on how broadly you want the customizations to apply.
这里有三种主要的方式来进行RestTemplate的定制化,依赖于你想你的丁志远在多广的范围内生效。
To make the scope of any customizations as narrow as possible, inject the auto-configured RestTemplateBuilder and then call its methods as required. Each method call returns a new RestTemplateBuilder instance, so the customizations only affect this use of the builder.
为了使任何定制配置的作用域尽可能的窄,注入自配置的RestTemplateBuilder,并且在需要的时候调用它的方法。每个方法返回一个RestTemplateBuilder实例,所以定制化只影响到这个builder使用到的作用域。
To make an application-wide, additive customization, use a RestTemplateCustomizer bean. All such beans are automatically registered with the auto-configured RestTemplateBuilder and are applied to any templates that are built with it.
为了创建一个应用层面的附加自定义配置,使用RestTemplateCustomizer实例。所有这些bean都将自动注册到自动配置的RestTemplateBuilder中,并应用于使用它构建的任何模板。
The following example shows a customizer that configures the use of a proxy for all hosts except 192.168.0.5:
接下来的示例展示了自定义配置,用来配置给所有的主机使用代理,除了192.168.0.5。
static class ProxyCustomizer implements RestTemplateCustomizer
@Override
public void customize(RestTemplate restTemplate)
HttpHost proxy = new HttpHost("proxy.example.com");
HttpClient httpClient = HttpClientBuilder.create().setRoutePlanner(new DefaultProxyRoutePlanner(proxy)
@Override
public HttpHost determineProxy(HttpHost target, HttpRequest request, HttpContext context)
throws HttpException
if (target.getHostName().equals("192.168.0.5"))
return null;
return super.determineProxy(target, request, context);
).build();
restTemplate.setRequestFactory(new HttpComponentsClientHttpRequestFactory(httpClient));
Finally, the most extreme (and rarely used) option is to create your own RestTemplateBuilder bean. Doing so switches off the auto-configuration of a RestTemplateBuilder and prevents any RestTemplateCustomizer beans from being used.
最后,最极端的(也是最少使用的)选项就是常见自己的RestTemplateBuilder实例。这个需要关闭RestTemplateBuilder的自配置,防止任何RestTemplateCustomizer被使用。
如何解决中文乱码问题?
这里,我们使用作用范围最窄的方法,在需要使用的地方进行注入。
首先我们需要做的是,在应用程序的启动类中添加如下代码:
@Bean
public RestTemplateBuilder restTemplateBuilder()
return new RestTemplateBuilder().setConnectTimeout(Duration.ofSeconds(10)).setReadTimeout(Duration.ofSeconds(10));
然后在需要使用RestTemplate的地方进行注入,并且对RestTemplate实例进行自定义修改。
private final RestTemplate restTemplate;
@Autowired
public IflytekAiuiHandler(RestTemplateBuilder restTemplateBuilder)
this.restTemplate = restTemplateBuilder.build();
List<HttpMessageConverter<?>> messageConverters = new ArrayList<>();
messageConverters.add(new ByteArrayHttpMessageConverter());
/** 解决中文乱码的converter */
StringHttpMessageConverter stringHttpMessageConverter = new StringHttpMessageConverter(Charset.forName
("UTF-8"));
messageConverters.add(stringHttpMessageConverter);
messageConverters.add(new ResourceHttpMessageConverter());
messageConverters.add(new SourceHttpMessageConverter());
messageConverters.add(new AllEncompassingFormHttpMessageConverter());
restTemplate.setMessageConverters(messageConverters);
结语
上面对SpringBoot中的RestTemplate的使用,结合官网的说明进行了简单的介绍,并针对中文乱码问题,给出了一种解决方案,亲测可行,欢迎留言给出其他方案,谢谢。
以上是关于如何解决SpringBoot中RestTemplate的中文乱码问题?的主要内容,如果未能解决你的问题,请参考以下文章
springcloud3 编写生产服务,消费服务的调用(含RestTemplate)
如何解决SpringBoot中RestTemplate的中文乱码问题?
「解决方案」SpringBoot项目中如何解决并发导致的重复提交问题