zoukankan      html  css  js  c++  java
  • Springboot @ResponseBody返回中文乱码

    最近我在把Spring 项目改造Springboot,遇到一个问题@ResponseBody返回中文乱码,因为response返回的content-type一直是application/json;charset=ISO-8859-1。经过几天的努力,终于找到最终原因,希望能帮助大家!

    推荐1:在@ResponseBody的方法中加入produces="application/json;charset=utf-8" 这样绝对能保证返回的字符串绝对是application/json; charset=utf-8,不会出现ISO-8859-1

    @ResponseBody
    @RequestMapping(value="/getUsersByPage",produces = "application/json; charset=utf-8")
    public String getUsersByPage(){
    return "张三";
    }


    推荐2:因为我们在项目中,是Spring项目改造Sringboot ,所以在Springboot 引入了一些Spring.xml文件,然后就是因为这些spring.xml文件才会导致这次问题的产生,也让我对Spring更加了解

    复制代码
     <mvc:annotation-driven>
            <mvc:message-converters> 
    <bean class="org.springframework.http.converter.StringHttpMessageConverter"> <property name="supportedMediaTypes"> <list> <value>text/plain;charset=utf-8</value> <value>text/html;charset=UTF-8</value> </list> </property> </bean> <bean class="org.springframework.http.converter.json.MappingJacksonHttpMessageConverter"/> </mvc:message-converters>
    </mvc:annotation-driven>
    复制代码

    网上都很多都是这种写法,个人不是特别推荐,因为我看过源码,发现发现spring 接头部时,会加入默认的字符集!个人推荐写法如下——

    复制代码
    <mvc:annotation-driven>
            <mvc:message-converters> 
    <bean class="org.springframework.http.converter.StringHttpMessageConverter">
      <constructor-arg value="UTF-8"/>
    </bean>
    <bean class="org.springframework.http.converter.json.MappingJacksonHttpMessageConverter"/>
           </mvc:message-converters>
    </mvc:annotation-driven>
    复制代码

    如果没有什么大的问题,一般这样就可以解决问题!但是我发现无论我怎么加,怎么改!前端返回的response的application/json;charset=ISO-8859-1!后面我跟踪源码、推理、实验才发现问题。

    Spring能识别json,xml转换我们需要的格式数据,是通过一个非常重要接口HttpMessageConverter 进行我们需要的格式转换,而StringHttpMessageConverter和 MappingJacksonHttpMessageConverter 则是HttpMessageConverter 实现类。

    StringHttpMessageConverter的作用:负责读取字符串格式的数据和写出二进制格式的数据(当返回值时或者接受值是String类型时,是由这个处理)

    MappingJacksonHttpMessageConverter:  负责读取和写入json格式的数据;(当返回值是对象或者List,就由这个处理)

    ByteArrayHttpMessageConverter: 负责读取二进制格式的数据和写出二进制格式的数据;

    FormHttpMessageConverter:负责读取form提交的数据(能读取的数据格式为 application/x-www-form-urlencoded,不能读取multipart/form-data格式数据);负责写入application/x-www-from-urlencoded和multipart/form-data格式的数据;ResourceHttpMessageConverter:负责读取资源文件和写出资源文件数据; 

    SourceHttpMessageConverter:                   负责读取和写入 xml 中javax.xml.transform.Source定义的数据;
    Jaxb2RootElementHttpMessageConverter:  负责读取和写入xml 标签格式的数据;
    AtomFeedHttpMessageConverter:              负责读取和写入Atom格式的数据;
    RssChannelHttpMessageConverter:           负责读取和写入RSS格式的数据;

    转载这篇文章https://www.jb51.net/article/88091.htm

    其中<mvc:annotation>非常重要
    <mvc:annotation-driven />会自动注册DefaultAnnotationHandlerMapping与AnnotationMethodHandlerAdapter 两个bean,是spring MVC为@Controllers分发请求所必须的。
    并提供了数据绑定支持,@NumberFormatannotation支持,@DateTimeFormat支持,@Valid支持,读写XML的支持(JAXB),读写JSON的支持(Jackson)。
    后面,我们处理响应ajax请求时,就使用到了对json的支持。

    当我们需要controller返回一个map的json对象时,可以设定<mvc:annotation-driven />,同时设定<mvc:message-converters> 标签,设定字符集和json处理类。

    转载 https://www.cnblogs.com/shuo1208/p/5552134.html

    一直困扰我很多天原因就是这个注解,在我们项目原本已经加入如下注解,可是又在后面加上<mvc:annotation-driven />,导致Spring 在加载自定义的转换器以后又加载一次,还覆盖原来的配置,导致一直content-type 是ISO-8859-1,然后原项目是Spring项目还没问题,改成Springboot 就出问题了!当我发现这个问题,竟然波澜不惊,心态越来越好了。

    复制代码
    <mvc:annotation-driven>
            <mvc:message-converters> 
    <bean class="org.springframework.http.converter.StringHttpMessageConverter">
      <constructor-arg value="UTF-8"/>
    </bean>
    <bean class="org.springframework.http.converter.json.MappingJacksonHttpMessageConverter"/>
           </mvc:message-converters>
    </mvc:annotation-driven>

    <mvc:annotation-driven />
    复制代码

    推荐三 java配置@Configuration

    复制代码
    @EnableWebMvc
    @Configuration public class WebMvcConfig extends WebMvcConfigurerAdapter { @Bean public HttpMessageConverter<String> responseBodyConverter() { StringHttpMessageConverter converter = new StringHttpMessageConverter(Charset.forName("UTF-8")); return converter; } @Override public void configureMessageConverters(List<HttpMessageConverter<?>> converters) { super.configureMessageConverters(converters); converters.add(responseBodyConverter());
    converters.add(new MappingJacksonHttpMessageConverter());
    }
        @Override
        public void configureContentNegotiation(ContentNegotiationConfigurer configurer) {
            configurer.favorPathExtension(false); //支持后缀匹配
        }
    复制代码

    其中@EnableWebMvc相当于<mvc:annotation-driven> 如果不加,会有一点小小的问题!请注意以下。

    推荐4、SpringBoot2.0及Spring 5.0 WebMvcConfigurerAdapter已被废弃,有两种可以添加控制转换器

    直接实现WebMvcConfigurer 和继承WebMvcConfigurationSupport

    WebMvcConfigurerAdapter不太推荐,因为如果要继承WebMvcConfigurationSupport,但是替换之后之前的静态资源文件会被拦截,导致无法可用。需要重新添加

    代码如下

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    @Configuration
    public class MyWebAppConfigurer extends WebMvcConfigurationSupport{
         
         @Override 
           protected void configureMessageConverters(List> converters) {
            // TODO Auto-generated method stub     
            super.configureMessageConverters(converters);      
            converters.add(responseBodyConverter());   
    }  
       @Bean
        public HttpMessageConverter responseBodyConverter() {
         StringHttpMessageConverter converter = new StringHttpMessageConverter(Charset.forName("UTF-8"));
         return converter;
       }
     
        // 如果不加,则静态资源会被拦截,导致访问不到静态资源
       @Override
       protected void addResourceHandlers(ResourceHandlerRegistry registry){
                      registry.addResourceHandler("/**")
                      .addResourceLocations("classpath:/META-INF/resources/")
                      .addResourceLocations("classpath:/resources/")
                      .addResourceLocations("classpath:/static/")
                      .addResourceLocations("classpath:/public/");
                       super.addResourceHandlers(registry);
       }
     
    }

      

    方式二

    复制代码
    @Configuration
    public class WebConfig implements WebMvcConfigurer {
    
    
        /**
         * 跨域支持
         * @param registry
         */
        @Override
        public void addCorsMappings(CorsRegistry registry) {
            registry.addMapping("/**")
                    .allowedOrigins("*")
                    .allowCredentials(true)
                    .allowedMethods("GET", "POST", "DELETE", "PUT")
                    .maxAge(3600 * 24);
        }    
    
        /**
         * 
         * @param converters
         */
        @Override
        public void configureMessageConverters(List<HttpMessageConverter<?>> converters) {
          StringHttpMessageConverter converter = new StringHttpMessageConverter(Charset.forName("UTF-8"));
          converters.add(converter);
    }
    复制代码
  • 相关阅读:
    项目实战之天天酷跑(三):缓冲加载游戏界面
    项目实战之天天酷跑(二):开始游戏界面
    项目实战之天天酷跑(一):登录界面
    DBeaver安装
    基于SpringBoot+Vue开发的前后端分离博客项目完整教学
    freemarker教程
    ftl 常用指令及语法详解
    FTL 入门
    IDEA右侧Maven消失解决方法
    nodejs和npm的关系
  • 原文地址:https://www.cnblogs.com/javalinux/p/14341354.html
Copyright © 2011-2022 走看看