Sping Mvc中Http请求返回String中文乱码问题深度解析

前言

  • SpringMVC中,可以使用@RequestBody@ResponseBody两个注解,分别完成请求报文到对象和对象到响应报文的转换,底层这种灵活的消息转换机制,就是Spring3.x中新引入的HttpMessageConverter即消息转换器机制。而这种消转换机制的原理是什么,大家可以去具体的分析一下SpringMvc的源码。

HttpMessageConverter机制大致原理

  • 当我们在Handler的某个方法上加上注解@ResponseBody后,服务器可以给客户端返回json格式的数据,当然,其本质就是字符串。因为Http请求和响应报文本质上都是一串字符串,当请求报文来到java世界,它会被封装成为一个ServletInputStream的输入流,供我们读取报文。响应报文则是通过一个ServletOutputStream的输出流,来输出响应报文。
  • 我们从输入流中,只能读取到原始的字符串报文,同样,我们在输出流中,也只能写原始的字符。而在java世界中,处理业务逻辑,都是以一个个有业务意义的对象为处理维度的,那么在报文到达SpringMVC和从SpringMVC出去,都存在一个字符串到java对象的阻抗问题。这一过程,不可能由开发者手工转换。
  • -

下面是原理的大致流程图

这里写图片描述

遇到的问题

@ResponseBody加到某个返回String的方法上时,当方法返回字符串中有汉字时,客户端接收到就会产生乱码问题,具体Demo如下所示。

@ResponseBody
@RequestMapping(value="/queryJson")
public String queryJson(HttpServletRequest request,HttpServletResponse response,Model model) throws Exception {
    //将学生信息列表在页面上展示
    List<Student> list = new ArrayList<Student>();
    Student student = new Student();
    student.setId("id1");
    student.setName("小学生");
    student.setAge(8);
    student.setAddress("北京市海淀区");
    list.add(student);  
    return list.toString();
}

返回效果图

这里写图片描述

  • 本来name应该显示为“小学生”,address显示成”北京市海淀区”,但是现在全部变成了? 这是怎么一回事那?

问题的原因

  • 这个问题的原因是HttpMessageConverte机制在处理请求和响应的时候出现的问题,Springmvc有一系列HttpMessageConverter去处理用@ResponseBody注解的返回值,如返回list或其它则使用 MappingJacksonHttpMessageConverter,若返回String,则使用 StringHttpMessageConverter,而返回String这个convert使用的是字符集是iso-8859-1,而且是final的。所以在当返回String中有中文时会出现乱码。下面是源码。
public static final Charset DEFAULT_CHARSET = Charset.forName("ISO-8859-1");      

解决方法

在@RequestMapping中设置一下MediaType

@RequestMapping(value="/queryJson", produces =MediaType.APPLICATION_JSON_VALUE)

或者这样

@RequestMapping(value="/queryJson", produces ="application/json" + ";charset=utf-8")

这两个效果是一样的

在springmvc配置文件设置

<mvc:annotation-driven>
    <mvc:message-converters>
        <bean id="mappingJacksonHttpMessageConverter" class="org.springframework.http.converter.json.MappingJackson2HttpMessageConverter">

    <property name="supportedMediaTypes">
        <list>
            <value>text/plain;charset=utf-8</value>
            <value>text/html;charset=UTF-8</value>
            <value>text/json;charset=UTF-8</value>
            <value>application/json;charset=utf-8</value>
        </list>
    </property>
   </bean>
  </mvc:message-converters>
</mvc:annotation-driven>

小结

  • 解决方式不止一种,个人推荐第二种方式,这种方式一劳永逸,方便程序员开发。
评论 8
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值