问题:在 Controller 层的方法中,加入 @ResponseBody 注解后,可以直接回复字符串,但是如果回复的内容中, 存在中文,则会出现乱码????;
原因:
因为我们返回的是字符串,所以Spring在通过AnnotationMethodHandlerAdapter去寻找对应的HttpMessageConverter时,会找到StringHttpMessageConverter,通过查看源码得知,该类的默认编码格式是 ISO-8859-1,部分源码如下:
public class StringHttpMessageConverter extends AbstractHttpMessageConverter<String> {
public static final Charset DEFAULT_CHARSET = Charset.forName("ISO-8859-1");
private final Charset defaultCharset;
private final List<Charset> availableCharsets;
private boolean writeAcceptCharset = true;
/**
* A default constructor that uses {@code "ISO-8859-1"} as the default charset.
* @see #StringHttpMessageConverter(Charset)
*/
public StringHttpMessageConverter() {
this(DEFAULT_CHARSET);
}
/**
* A constructor accepting a default charset to use if the requested content
* type does not specify one.
*/
public StringHttpMessageConverter(Charset defaultCharset) {
super(new MediaType("text", "plain", defaultCharset), MediaType.ALL);
this.defaultCharset = defaultCharset;
this.availableCharsets = new ArrayList<Charset>(Charset.availableCharsets().values());
}
解决方案:
(推荐)方案一:
在 spring mvc 配置文件中,添加如下配置:
<mvc:annotation-driven>
<mvc:message-converters register-defaults="true">
<bean class="org.springframework.http.converter.StringHttpMessageConverter">
<constructor-arg value="UTF-8" />
</bean>
</mvc:message-converters>
</mvc:annotation-driven>
说明:其实是指定 StringHttpMessageConverter 类构造函数的参数值为 UTF-8,该方法对代码侵入性低,且一劳永逸,故推荐!
方案二:
在 @RequestMapping 中添加 produces 字段,如下:
@RequestMapping(value = "/xxxx.do", produces = "text/html;charset=UTF-8")
方案三:
采用原始的做法,在方法中,增加 HttpServletResponse 参数,然后由 HttpServletResponse 对象输出回复内容,如下:
@RequestMapping(value = "/xxxx.do")
@ResponseBody
public String fetchFlowPackage(@RequestParam(required = true) String param, HttpServletResponse response) {
response.setHeader("Cache-Control", "no-cache");
response.setContentType("text/html;charset=UTF-8");
response.setCharacterEncoding("UTF-8");
try {
PrintWriter out = null;
out = response.getWriter();
out.write("回复的内容xxxx");
} catch (IOException e) {
e.printStackTrace();
}
return null;
}
谢谢~~~