ajax提交 返回中文乱码问题

本文详细解析了SpringMVC框架中返回中文时出现乱码的问题,通过分析StringHttpMessageConverter的字符集缺陷,提供了多种解决方案,包括配置文件调整、@RequestMapping注解设置等,确保不同客户端请求下中文正确显示。

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

使用@RequestMapping返回中文乱码

原因分析:(网上基本都是一致的答案)

首先: 确定的是(经过多次测试的结果)只有当返回值是 String时才会出现中文乱码,而当返回值是Map<String, Object>或者是其它类型时,并没有中文乱码的出现。

然后找原因: 原因是这可以说是spring mvc的一个bug,spring MVC有一系列HttpMessageConverter去处理用@ResponseBody注解的返回值,如返回list或其它则使用 MappingJacksonHttpMessageConverter,返回string,则使用 StringHttpMessageConverter,而这个convert使用的是字符集是iso-8859-1,而且是final的。所以在当返回json中有中文时会出现乱码。

public static final Charset DEFAULT_CHARSET = Charset.forName("ISO-8859-1");   

解决办法(以及是否尝试成功): 尝试了很多种网上的办法,有一些根本无用,有一些当客户端的Accep是 application/json;时无用.最终也是结合客户端的修改才成功解决问题的。

客户端分为三种不同的请求:
1.浏览器中直接Get访问,Accept是"text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,/;q=0.8"
2.用Jquery的jsonp ajax请求,Accept是"/"
3.用h5+环境下的mui ajax请求,Accept是"application/json;charset=utf-8"

注: 如果什么都不加,第一种和第二种都是返回的乱码,第三种由于手动要求了返回格式,所以没有乱码,这里之所以要第三组做对比是因为有一些方法会造成第三组不能正常访问。

尝试方法一: 在配置文件中的mvc:annotation-driven中添加如下代码

<mvc:annotation-driven >
    <!-- 消息转换器 -->
    <mvc:message-converters register-defaults="true">
      <bean class="org.springframework.http.converter.StringHttpMessageConverter">
        <property name="supportedMediaTypes" value="text/html;charset=UTF-8"/>
      </bean>
    </mvc:message-converters>
  </mvc:annotation-driven>

原理: StringHttpMessageConverter的父类里有个List supportedMediaTypes属性,用来存放 StringHttpMessageConverter支持需特殊处理的 MediaType 类型,如果需处理的 MediaType 类型不在 supportedMediaTypes列表中,则采用默认字符集。

最终结果:
请求方法1中文乱码
请求方法2返回正确的中文
请求方法3返回正确的中文

尝试方法二: 在配置文件中的mvc:annotation-driven中添加如下代码

<mvc:annotation-driven>
      <mvc:message-converters>
          <bean class="org.springframework.http.converter.StringHttpMessageConverter">
              <property name="supportedMediaTypes">
                  <list>
                   <span style="white-space:pre">	</span>  <value>text/html;charset=UTF-8</value>
                      <value>application/json;charset=UTF-8</value>
                      <value>*/*;charset=UTF-8</value>
                  </list>
              </property>
          </bean>
      </mvc:message-converters>
  </mvc:annotation-driven>

原理: 原理同上,但是这里多加了几个value。

最终结果:
请求方法1中文乱码
请求方法2返回正确的中文
请求方法3返回正确的中文

尝试方法三: 在@RequestMapping里的配置produces="text/html;charset=UTF-8;"

@RequestMapping(value = "***",produces="text/html;charset=UTF-8;")

原理: 手动给对应的Accept返回制定格式编码数据。

最终结果:
请求方法1返回正确的中文
请求方法2返回正确的中文
请求方法3无法请求,出了错,因为produces没有添加application/json;对应的头部.

尝试方法五: 在@RequestMapping里的并发配置produces={“text/html;charset=UTF-8;”,“application/json;”}

@RequestMapping(value = "***",produces={"text/html;charset=UTF-8;","application/json;"})

注意: 这里和上个方法的区别是,produces里面的顺序对调了

原理: 手动给对应的Accept返回制定格式编码数据。

最终结果:
请求方法1返回正确的中文
请求方法2返回正确的中文
请求方法3返回正确的中文

方法四和方法五对比分析:
发现produces设置多个Accept只有第一个的charset是有用的,
后面的Accept设置有效(因为不设置就无法接收对应的Accept请求),但是charset设置是无效的.需要客户端手动制定charset才行.

所以得出的结论是:

produces={“text/html;charset=UTF-8;”,“application/json;”}

这样设置,这样普通浏览器的请求就能正常显示中文,而客户端的模拟请求(可以是ajax或http)则手动指定Accept的charset,即可正常接收中文。

实例展示

解决方式一:
在这里插入图片描述
解决方式二:
在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值