SpringMVC3的ResponseBody返回字符串(JSON)亂碼問題解決

近日作一個小項目,用spring mvc 作到ajax請求獲取jquery ztree 異步獲取樹返回json對象時出現了亂碼,試了各類辦法,查了各類資料,一開始覺得是數據庫的編碼有問題,經測試沒問題,又覺得是jetty須要設置下響應頭,正在查找時忽然想到多是mvc的responseBody的問題,網上一查,果真是,用了一個設置最簡單的辦法,解決了問題,特將文章轉貼於此,與我同樣遇到此問題的朋友們共享。 javascript

添加@RequestMapping註解,配置produces的值 java

@RequestMapping(value = "/add", produces = {"application/json;charset=UTF-8"})

 (注:我就是用這種方法解決的,簡單實用,呵呵 jquery

SpringMVC3的ResponseBody返回字符串亂碼問題解決

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>
相關文章
相關標籤/搜索