近日作一個小項目,用spring mvc 作到ajax請求獲取jquery ztree 異步獲取樹返回json對象時出現了亂碼,試了各類辦法,查了各類資料,一開始覺得是數據庫的編碼有問題,經測試沒問題,又覺得是jetty須要設置下響應頭,正在查找時忽然想到多是mvc的responseBody的問題,網上一查,果真是,用了一個設置最簡單的辦法,解決了問題,特將文章轉貼於此,與我同樣遇到此問題的朋友們共享。 javascript
添加@RequestMapping註解,配置produces的值 java
@RequestMapping(value = "/add", produces = {"application/json;charset=UTF-8"})
(注:我就是用這種方法解決的,簡單實用,呵呵) jquery
SpringMVC的@ResponseBody註解能夠將請求方法返回的對象直接轉換成JSON對象,可是當返回值是String的時候,中文會亂碼,緣由是由於其中字符串轉換和對象轉換用的是兩個轉換器,而String的轉換器中固定了轉換編碼爲"ISO-8859-1",網上也不少種解決方法,有經過配置Bean編碼的,也有本身重寫轉換器的,我這裏屢次嘗試未果,只能本身解決。 ajax
有兩種解決辦法: spring
1.返回字符串時,將字符串結果轉換 數據庫
return new String("你好".getBytes(), "ISO-8859-1");
2.添加@RequestMapping註解,配置produces的值 json
@RequestMapping(value = "/add", produces = {"application/json;charset=UTF-8"})
(注:我就是用這種方法解決的,簡單實用,呵呵) spring-mvc
因爲我是爲了使用JSONP協議,須要連同callback一塊兒返回,因此我定義的是 mvc
@RequestMapping(value = "/add", params = {"callback"}, produces = {"text/javascript;charset=UTF-8"})
以上提供的方法雖然須要額外配置,但相對靈活,喜歡一次性永久搞定的,仍是應該考慮網上的方法,修改源碼,或者替換默認的字符串轉換器。 app
可是在使用<mvc:annotation-driven />配置的前提下,貌似網上的方法都不可靠,可能跟版本或者配置有關係
這邊提供一種修改方法,我這邊使用的是3.1的mvc
1.參考網上將默認的StringHttpMessageConverter重寫一遍,將其中的編碼改成UTF-8
import java.io.IOException; import java.io.InputStreamReader; import java.io.OutputStreamWriter; import java.io.UnsupportedEncodingException; import java.nio.charset.Charset; import java.util.ArrayList; import java.util.List; import org.springframework.http.HttpInputMessage; import org.springframework.http.HttpOutputMessage; import org.springframework.http.MediaType; import org.springframework.http.converter.AbstractHttpMessageConverter; import org.springframework.util.FileCopyUtils; public class UTF8StringHttpMessageConverter extends AbstractHttpMessageConverter<String> { public static final Charset DEFAULT_CHARSET = Charset.forName("UTF-8"); private final List<Charset> availableCharsets; private boolean writeAcceptCharset = true; public UTF8StringHttpMessageConverter() { super(new MediaType("text", "plain", DEFAULT_CHARSET), MediaType.ALL); this.availableCharsets = new ArrayList<Charset>(Charset.availableCharsets().values()); } /** * Indicates whether the {@code Accept-Charset} should be written to any outgoing request. * <p>Default is {@code true}. */ public void setWriteAcceptCharset(boolean writeAcceptCharset) { this.writeAcceptCharset = writeAcceptCharset; } @Override public boolean supports(Class<?> clazz) { return String.class.equals(clazz); } @Override protected String readInternal(Class clazz, HttpInputMessage inputMessage) throws IOException { Charset charset = getContentTypeCharset(inputMessage.getHeaders().getContentType()); return FileCopyUtils.copyToString(new InputStreamReader(inputMessage.getBody(), charset)); } @Override protected Long getContentLength(String s, MediaType contentType) { Charset charset = getContentTypeCharset(contentType); try { return (long) s.getBytes(charset.name()).length; } catch (UnsupportedEncodingException ex) { // should not occur throw new InternalError(ex.getMessage()); } } @Override protected void writeInternal(String s, HttpOutputMessage outputMessage) throws IOException { if (writeAcceptCharset) { outputMessage.getHeaders().setAcceptCharset(getAcceptedCharsets()); } Charset charset = getContentTypeCharset(outputMessage.getHeaders().getContentType()); FileCopyUtils.copy(s, new OutputStreamWriter(outputMessage.getBody(), charset)); } /** * Return the list of supported {@link Charset}. * * <p>By default, returns {@link Charset#availableCharsets()}. Can be overridden in subclasses. * * @return the list of accepted charsets */ protected List<Charset> getAcceptedCharsets() { return this.availableCharsets; } private Charset getContentTypeCharset(MediaType contentType) { if (contentType != null && contentType.getCharSet() != null) { return contentType.getCharSet(); } else { return DEFAULT_CHARSET; } } }
2.context配置
<beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:mvc="http://www.springframework.org/schema/mvc" xmlns:p="http://www.springframework.org/schema/p" xmlns:context="http://www.springframework.org/schema/context" xmlns:aop="http://www.springframework.org/schema/aop" xmlns:tx="http://www.springframework.org/schema/tx" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.1.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.1.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-3.1.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.1.xsd http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-3.1.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.1.xsd"> <mvc:annotation-driven> <mvc:message-converters> <bean class="yourpackage.UTF8StringHttpMessageConverter" /> </mvc:message-converters> </mvc:annotation-driven> ...... </beans>