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,但是替換之后之前的靜態資源文件會被攔截,導致無法可用。需要重新添加

代碼如下

 

@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);
}

 

 

 

  


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM