1. 程式人生 > >Springboot @ResponseBody返回中文亂碼

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> 如果不加,會有一點小小的問題!請注意以下。