Spring RestTemplate出现乱码解决方法

本文详细介绍了在Spring框架中如何解决HTTP请求中出现的中文乱码问题,通过配置RestTemplate及其消息转换器来确保不同类型的请求都能正确处理中文。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

发起Http请求有很多方法,Spring本身提供了RestTemplate类,简化了发起HTTP请求以及处理响应的过程,并且支持REST

我们一般都是在xml配置文件中注入RestTemplate实现单例,一般初始化时会指定一些Converter用于不同的请求解析,下面是我之前的配置

<bean id="restTemplate" class="org.springframework.web.client.RestTemplate">
        <property name="messageConverters">
            <list>
                <bean class="org.springframework.http.converter.FormHttpMessageConverter"/>
                <bean
                        class="org.springframework.http.converter.StringHttpMessageConverter"/>
                <bean id="mappingJacksonHttpMessageConverter"
                      class="org.springframework.http.converter.json.MappingJackson2HttpMessageConverter">
                    <property name="supportedMediaTypes">
                        <list>
                            <bean class="org.springframework.http.MediaType">
                                <constructor-arg index="0" value="text"/>
                                <constructor-arg index="1" value="plain"/>
                                <constructor-arg index="2" value="UTF-8"/>
                            </bean>
                            <bean class="org.springframework.http.MediaType">
                                <constructor-arg index="0" value="application"/>
                                <constructor-arg index="1" value="json"/>
                                <constructor-arg index="2" value="UTF-8"/>
                            </bean>
                        </list>
                    </property>
                </bean>
            </list>
        </property>
    </bean>

出现中文乱码的原因一般都是因为StringHttpMessageConverter这个类,查看源码可以知道它的默认编码是ISO-8859-1,但是有提供给我们一个构造方法来初始化编码

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;

    public StringHttpMessageConverter() {
        this(DEFAULT_CHARSET);
    }

    public StringHttpMessageConverter(Charset defaultCharset) {
        super(new MediaType[]{new MediaType("text", "plain", defaultCharset), MediaType.ALL});
        this.writeAcceptCharset = true;
        this.defaultCharset = defaultCharset;
        this.availableCharsets = new ArrayList(Charset.availableCharsets().values());
    }
    .......
}

因此配置成下面这样可以使用于大部分情况

<bean id="stringHttpMessageConverter"
                      class="org.springframework.http.converter.StringHttpMessageConverter">
  <constructor-arg value="UTF-8"/>
</bean>

之所以说是大部分情况,是因为我如此修改以后发现乱码的问题并没有解决,原因我使用的是multipartform/data的请求,也就是表单提交,使用的是FormHttpMessageConverter,查看源码可知

public class FormHttpMessageConverter implements HttpMessageConverter<MultiValueMap<String, ?>> {
    public static final Charset DEFAULT_CHARSET = Charset.forName("UTF-8");
    private Charset charset;
    private Charset multipartCharset;
    private List<MediaType> supportedMediaTypes;
    private List<HttpMessageConverter<?>> partConverters;

    public FormHttpMessageConverter() {
        this.charset = DEFAULT_CHARSET;
        this.supportedMediaTypes = new ArrayList();
        this.partConverters = new ArrayList();
        this.supportedMediaTypes.add(MediaType.APPLICATION_FORM_URLENCODED);
        this.supportedMediaTypes.add(MediaType.MULTIPART_FORM_DATA);
        this.partConverters.add(new ByteArrayHttpMessageConverter());
        StringHttpMessageConverter stringHttpMessageConverter = new StringHttpMessageConverter();
        stringHttpMessageConverter.setWriteAcceptCharset(false);
        this.partConverters.add(stringHttpMessageConverter);
        this.partConverters.add(new ResourceHttpMessageConverter());
    }
    ....
}

FormHttpMessageConverter默认使用的是ISO-8859-1编码的StringHttpMessageConverter,并且没有提供方法修改,方法就是手动注入UTF-8格式的StringHttpMessageConverter.对上面的配置文件进行修改,修改后的配置基本就可以适用所有的情况了

<bean id="restTemplate" class="org.springframework.web.client.RestTemplate">
        <property name="messageConverters">
            <list>
                <bean class="org.springframework.http.converter.support.AllEncompassingFormHttpMessageConverter">
                    <property name="supportedMediaTypes">
                        <list>
                            <value>application/x-www-form-urlencoded;charset=UTF-8</value>
                            <value>multipart/form-data;charset=UTF-8</value>
                            <value>text/plain;charset=UTF-8</value>
                            <value>text/html;charset=UTF-8</value>
                            <value>application/xml;charset=UTF-8</value>
                            <value>application/json;charset=UTF-8</value>
                        </list>
                    </property>
                    <property name="partConverters">
                        <list>
                            <bean class="org.springframework.http.converter.StringHttpMessageConverter">
                                <property name="supportedMediaTypes">
                                    <list>
                                        <value>application/x-www-form-urlencoded;charset=UTF-8</value>
                                        <value>multipart/form-data;charset=UTF-8</value>
                                        <value>text/plain;charset=UTF-8</value>
                                        <value>text/html;charset=UTF-8</value>
                                        <value>application/xml;charset=UTF-8</value>
                                        <value>application/json;charset=UTF-8</value>
                                    </list>
                                </property>
                            </bean>
                            <bean class="org.springframework.http.converter.ByteArrayHttpMessageConverter"/>
                            <bean class="org.springframework.http.converter.ResourceHttpMessageConverter"/>
                            <bean class="org.springframework.http.converter.xml.SourceHttpMessageConverter"/>
                            <bean class="org.springframework.http.converter.xml.Jaxb2RootElementHttpMessageConverter"/>
                            <bean class="org.springframework.http.converter.json.MappingJackson2HttpMessageConverter">
                                <property name="supportedMediaTypes">
                                    <list>
                                        <bean class="org.springframework.http.MediaType">
                                            <constructor-arg index="0" value="text"/>
                                            <constructor-arg index="1" value="plain"/>
                                            <constructor-arg index="2" value="UTF-8"/>
                                        </bean>
                                        <bean class="org.springframework.http.MediaType">
                                            <constructor-arg index="0" value="application"/>
                                            <constructor-arg index="1" value="json"/>
                                            <constructor-arg index="2" value="UTF-8"/>
                                        </bean>
                                        <bean class="org.springframework.http.MediaType">
                                            <constructor-arg index="0" value="multipart"/>
                                            <constructor-arg index="1" value="form-data"/>
                                            <constructor-arg index="2" value="UTF-8"/>
                                        </bean>
                                    </list>
                                </property>
                            </bean>
                        </list>
                    </property>
                </bean>
                <bean class="org.springframework.http.converter.json.MappingJackson2HttpMessageConverter">
                    <property name="supportedMediaTypes">
                        <list>
                            <bean class="org.springframework.http.MediaType">
                                <constructor-arg index="0" value="text"/>
                                <constructor-arg index="1" value="plain"/>
                                <constructor-arg index="2" value="UTF-8"/>
                            </bean>
                            <bean class="org.springframework.http.MediaType">
                                <constructor-arg index="0" value="application"/>
                                <constructor-arg index="1" value="json"/>
                                <constructor-arg index="2" value="UTF-8"/>
                            </bean>
                            <bean class="org.springframework.http.MediaType">
                                <constructor-arg index="0" value="multipart"/>
                                <constructor-arg index="1" value="form-data"/>
                                <constructor-arg index="2" value="UTF-8"/>
                            </bean>
                        </list>
                    </property>
                </bean>
                <bean class="org.springframework.http.converter.StringHttpMessageConverter">
                    <property name="supportedMediaTypes">
                        <list>
                            <value>application/x-www-form-urlencoded;charset=UTF-8</value>
                            <value>multipart/form-data;charset=UTF-8</value>
                            <value>text/plain;charset=UTF-8</value>
                            <value>text/html;charset=UTF-8</value>
                            <value>application/xml;charset=UTF-8</value>
                            <value>application/json;charset=UTF-8</value>
                        </list>
                    </property>
                </bean>
            </list>
        </property>
    </bean>

这里的配置还有需要注意的:

MappingJackson2HttpMessageConverter
和名字一样,用于json数据转换的,我当前的环境是spring4,spring3及之前版本中使用的是MappingJacksonHttpMessageConverter,并且最好对支持的MediaType进行配置,指定text/plain,application/json形式的请求编码为UTF-8

并且不仅在AllEncompassingFormHttpMessageConverter的partConverter中需要指定MappingJackson2HttpMessageConverter,在外层RestTemplate的messageConverters中也需要配置这个Converter,因为AllEncompassingFormHttpMessageConverter只对上传的数据进行转换,获取返回数据的时候如果刚好是json格式的就报错了

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值