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);
    }
    复制代码
  • 相关阅读:
    Codeforces Round #344 (Div. 2) C. Report 其他
    Codeforces Round #344 (Div. 2) B. Print Check 水题
    Codeforces Round #344 (Div. 2) A. Interview 水题
    8VC Venture Cup 2016
    CDOJ 1280 772002画马尾 每周一题 div1 矩阵快速幂 中二版
    CDOJ 1280 772002画马尾 每周一题 div1 矩阵快速幂
    CDOJ 1279 班委选举 每周一题 div2 暴力
    每周算法讲堂 快速幂
    8VC Venture Cup 2016
    Educational Codeforces Round 9 F. Magic Matrix 最小生成树
  • 原文地址:https://www.cnblogs.com/javalinux/p/14341354.html
Copyright © 2011-2022 走看看