SSM返回中文乱码问题,SpringMVC返回中文乱码,SSM返回String字符串乱码问题

红太狼 2021-09-21 15:30 595阅读 0赞

博客来源:

搭建SSM框架的过程中,发现直接返回String时出现中文乱码问题,但是返回Map、List等不会出现乱码问题……

经过查阅资料发现,这算是SpringMVC的一个bug吧,spring MVC有一系列HttpMessageConverter去处理用@ResponseBody注解的返回值,如返回list或其它则使用 MappingJacksonHttpMessageConverter,返回string,则使用 StringHttpMessageConverter,而这个convert使用的是字符集是iso-8859-1,而且是final的。所以在当返回json中有中文时会出现乱码。

发现问题就是解决了80%的问题的,下面就阐述一下解决办法吧。

(如果出现了非返回String字符串中文时的乱码问题,请检查是否配置了全局的字符编码转换器,或者是否配置正确)

解决办法有两种

  1. 全局的解决方法(略微麻烦,但是一劳永逸)
  2. 局部的解决办法(比较简单,类多时会麻烦)

下面我们进行对这两种方法的探讨

全局的解决方法(略微麻烦,但是一劳永逸)

前提知识(希望有所了解):

Spring中有处理器BeanPostProcessor,可用于bean加载前后逻辑的添加,那么我们的机会来了,我们可以实现BeanPostProcessor在bean加载后对bean中String设置字符编码。然后再注册到容器中去。

在 bean 实例化之后,String在bean 的类型为 StringHttpMessageConverter ,我们可以判断是否是String从而进行字符编码判断。

BeanPostProcessor有两个方法需要实现:postProcessorAfterInitialization、postProcessorBeforeInitialization。

首先我们新建一个类,命名随意,尽量有可读性

  1. import org.springframework.beans.BeansException;
  2. import org.springframework.beans.factory.config.BeanPostProcessor;
  3. import org.springframework.http.MediaType;
  4. import org.springframework.http.converter.StringHttpMessageConverter;
  5. import java.nio.charset.Charset;
  6. import java.util.ArrayList;
  7. import java.util.List;
  8. /**
  9. * @Descrintion: String的后置处理器,处理编码问题,继承BeanPostProcessor 实现Bean的编码转换,解决返回String对象时乱码问题
  10. * @version: 1.0
  11. */
  12. public class StringBeanPostProcessor implements BeanPostProcessor{
  13. @Override
  14. public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
  15. return bean;
  16. }
  17. //bean实例化后进行处理,判断bean是否属于StringHttpMessageConverter,如果是的话就配置字符编码
  18. @Override
  19. public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
  20. if(bean instanceof StringHttpMessageConverter){
  21. MediaType mediaType = new MediaType("text", "plain", Charset.forName("UTF-8"));
  22. List<MediaType> types = new ArrayList<MediaType>();
  23. types.add(mediaType);
  24. ((StringHttpMessageConverter) bean).setSupportedMediaTypes(types);
  25. }
  26. return bean;
  27. }
  28. }

注意:

  1. 接口中的两个方法都要将传入的bean返回、而不能返回Null。否则getBean将无法取得目标。

  2. 如将BeanPostProcessor标记为延迟初始化,则无法注册,自定义逻辑也就无法得到应用。假如你在元素的定义中使用了’default-lazy-init’属性,则各个BeanPostProcessor需标记为’lazy-init=”false”‘。

我们的类已经搞定了,那么只需要将我们的类添加到配置文件中,对于这个问题就算解决了,class中名字修改为我们的类名

  1. <!-- 加载String的管理器转化器,每当Spring返回时进行字符编码的转换 -->
  2. <bean class="xxxxxxxxx.StringBeanPostProcessor"/>

OK,全局配置搞定,其实博主也推荐这一种方法,毕竟一劳永逸,对于超级细心或者需要处理乱码不多的情况下也可以考虑下面方法

局部的解决办法(比较简单,类多时会麻烦)

前提知识:

在 @RequestMapping 中有一个属性 produces,其可指定返回的类型,以及字符编码

produces中的类别有 text/html,application/xml,application/json三种,需要准确指定返回类型,否则会出转换异常从而找不到资源的错

错误详情可移步————>传送门,因为设置返回类型而出现的资源访问异常

在方法中可添加,类似如下

  1. @ResponseBody
  2. //produces中的类别有 text/html,application/xml,application/json三种,需要准确指定返回类型,否则会出错
  3. @RequestMapping(produces = "application/json;charset=utf-8")
  4. public String test(){
  5. return "test中文";
  6. }

在类中可添加代码如下,此配置在类中都生效,但优先级没有方法中配置的高

  1. @ResponseBody
  2. //produces中的类别有 text/html,application/xml,application/json三种,需要准确指定返回类型,否则会出错
  3. @RequestMapping(produces = "application/json;charset=utf-8")
  4. @Controller
  5. public class UserLoginControler {
  6. .......
  7. .......
  8. .......
  9. }

解决奇奇怪怪的字符编码问题结束,如果其他编码问题可查看字符编码过滤器是否配置成功

续一个,不大不小的问题! 也是SpringMVC的坑……(由于问题不大,暂不另起博客了)

问题来源:

编写SSM项目的时候,由于命名问题导致的访问错误,详情看条件吧…还是很容易触发的

前置条件

  1. 1、编写一个user.html 访问路径 [http://localhost:8080/xxx项目名xxx/user.html][http_localhost_8080_xxx_xxx_user.html]
  2. 2Controler层有一个user的访问路径 [http://localhost:8080/xxx项目名xxx/user][http_localhost_8080_xxx_xxx_user.html]

细心看会发现,访问的路径很是相似,但也有不同,可是带有 .html 的,不过在SpringMVC中认为他们是相同的,并且 2 的优先级大于 1 ,导致1访问时报错

发表评论

表情:
评论列表 (有 0 条评论,595人围观)

还没有评论,来说两句吧...

相关阅读