一、springmvc请求中文乱码
1、post请求乱码
在web.xml加入filter过滤,注意,只能解决浏览器端发送post请求,controller接收中文乱码的情况。
<!-- POST字符编码过滤 -->
<filter>
<description>字符集过滤器</description>
<filter-name>characterEncodingFilter</filter-name>
<filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class>
<init-param>
<description>字符集编码</description>
<param-name>encoding</param-name>
<param-value>UTF-8</param-value>
</init-param>
<init-param>
<param-name>forceEncoding</param-name>
<param-value>true</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>characterEncodingFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
2、get请求乱码
浏览器端发送get请求,controller接收中文乱码,需要在tomcat的server.xml文件中加入添加URIEncoding="utf-8"。如下图:
二、springmvc返回中文乱码
1、解决返回实体类包含中文乱码
返回实体类中的属性包含中文,返回到前端页面上中文显示??等乱码数据,采用此方法解决,顺便解决springmvc返回日期格式数据不能正常显示的问题。需要在spring-mvc的配置上解决。
<mvc:annotation-driven>
<mvc:message-converters>
<!-- mvc返回非String数据转换json -->
<bean class="org.springframework.http.converter.json.MappingJackson2HttpMessageConverter">
<!-- json日期转换 -->
<property name="objectMapper">
<bean class="com.fasterxml.jackson.databind.ObjectMapper">
<property name="dateFormat">
<bean class="java.text.SimpleDateFormat">
<constructor-arg type="java.lang.String" value="yyyy-MM-dd HH:mm:ss" />
</bean>
</property>
</bean>
</property>
<!-- 避免IE执行AJAX时,返回JSON出现下载文件 -->
<property name="supportedMediaTypes">
<list>
<value>application/json;charset=UTF-8</value>
<value>text/html;charset=UTF-8</value>
</list>
</property>
</bean>
</mvc:message-converters>
</mvc:annotation-driven>
这里需要注意这个类org.springframework.http.converter.json.MappingJackson2HttpMessageConverter:
spring3.x使用的是org.springframework.http.converter.json.MappingJacksonHttpMessageConverter;
spring4.x使用的是org.springframework.http.converter.json.MappingJackson2HttpMessageConverter
2、解决返回String类型数据包含中文乱码
对于controller返回类型为String类型的数据,如果返回的字符串中包含中文出现乱码的情况,还需要使用下面的方式解决,其中第一种方法和第二种方法,现在的主流浏览器和IE11测试返回中文无乱码。第三种方法使用myeclipse2016自带的浏览器测试时返回中文乱码,主流常用浏览器无乱码情况。
第一种方法,重写StringHttpMessageConverter:
先将spring自带的org.springframework.http.converter.StringHttpMessageConverter类复制一份出来,修改DEFAULT_CHARSET的值为Charset.forName("UTF-8")。代码如下:
package com.jeeweb.core.HttpMessageConverter;
import java.io.IOException;
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.StreamUtils;
/**
* 类简述
* <p>
* spring mvc返回中文乱码解决
* </p>
* @author wangcf:1643655989@qq.com
* @since 2019年1月7日 下午1:27:43
* @version 1.0.0
*/
public class StringHttpMessageConverter extends AbstractHttpMessageConverter<String> {
public static final Charset DEFAULT_CHARSET = Charset.forName("UTF-8");
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(defaultCharset, MediaType.TEXT_PLAIN, 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 == clazz;
}
@Override
protected String readInternal(Class<? extends String> clazz, HttpInputMessage inputMessage) throws IOException {
Charset charset = getContentTypeCharset(inputMessage.getHeaders().getContentType());
return StreamUtils.copyToString(inputMessage.getBody(), charset);
}
@Override
protected Long getContentLength(String str, MediaType contentType) {
Charset charset = getContentTypeCharset(contentType);
try {
return (long) str.getBytes(charset.name()).length;
}
catch (UnsupportedEncodingException ex) {
// should not occur
throw new IllegalStateException(ex);
}
}
@Override
protected void writeInternal(String str, HttpOutputMessage outputMessage) throws IOException {
if (this.writeAcceptCharset) {
outputMessage.getHeaders().setAcceptCharset(getAcceptedCharsets());
}
Charset charset = getContentTypeCharset(outputMessage.getHeaders().getContentType());
StreamUtils.copy(str, charset, outputMessage.getBody());
}
/**
* Return the list of supported {@link Charset}s.
* <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 getDefaultCharset();
}
}
}
然后在前面修改的spring mvc配置文件中的<mvc:message-converters>追加配置
<bean class="com.jeeweb.core.HttpMessageConverter.StringHttpMessageConverter" />
<mvc:annotation-driven>
<mvc:message-converters>
<!-- mvc返回String数据转换json -->
<bean class="com.jeeweb.core.HttpMessageConverter.StringHttpMessageConverter" />
<!-- mvc返回非String数据转换json -->
<bean class="org.springframework.http.converter.json.MappingJackson2HttpMessageConverter">
<!-- json日期转换 -->
<property name="objectMapper">
<bean class="com.fasterxml.jackson.databind.ObjectMapper">
<property name="dateFormat">
<bean class="java.text.SimpleDateFormat">
<constructor-arg type="java.lang.String" value="yyyy-MM-dd HH:mm:ss" />
</bean>
</property>
</bean>
</property>
<!-- 避免IE执行AJAX时,返回JSON出现下载文件 -->
<property name="supportedMediaTypes">
<list>
<value>application/json;charset=UTF-8</value>
<value>text/html;charset=UTF-8</value>
</list>
</property>
</bean>
</mvc:message-converters>
</mvc:annotation-driven>
第二种方法、修改spring mvc的配置,配置转换器StringHttpMessageConverter:
在spring中创建一个bean,id设置为utf8Charset,然后应用这个bean,下面是配置文件:
<bean id="utf8Charset" class="java.nio.charset.Charset" factory-method="forName">
<constructor-arg value="UTF-8"/>
</bean>
<mvc:annotation-driven>
<mvc:message-converters>
<!-- mvc返回String数据转换json -->
<bean id="stringHttpMessageConverter" class="org.springframework.http.converter.StringHttpMessageConverter">
<constructor-arg ref="utf8Charset"/>
</bean>
<!-- mvc返回非String数据转换json -->
<bean class="org.springframework.http.converter.json.MappingJackson2HttpMessageConverter">
<!-- json日期转换 -->
<property name="objectMapper">
<bean class="com.fasterxml.jackson.databind.ObjectMapper">
<property name="dateFormat">
<bean class="java.text.SimpleDateFormat">
<constructor-arg type="java.lang.String" value="yyyy-MM-dd HH:mm:ss" />
</bean>
</property>
</bean>
</property>
<!-- 避免IE执行AJAX时,返回JSON出现下载文件 -->
<property name="supportedMediaTypes">
<list>
<value>application/json;charset=UTF-8</value>
<value>text/html;charset=UTF-8</value>
</list>
</property>
</bean>
</mvc:message-converters>
</mvc:annotation-driven>
第三种方法、配置StringHttpMessageConverter:
<mvc:annotation-driven>
<!-- mvc返回数据转换成json -->
<mvc:message-converters>
<!-- mvc返回String乱码解决 -->
<bean id="stringHttpMessageConverter" class="org.springframework.http.converter.StringHttpMessageConverter">
<property name="supportedMediaTypes">
<list>
<value>text/plain;charset=UTF-8</value>
<value>text/html;charset=UTF-8</value>
<value>text/json;charset=UTF-8</value>
<value>application/json;charset=UTF-8</value>
</list>
</property>
</bean>
<!-- mvc返回非String数据转换json -->
<bean class="org.springframework.http.converter.json.MappingJackson2HttpMessageConverter">
<property name="objectMapper">
<bean class="com.fasterxml.jackson.databind.ObjectMapper">
<property name="dateFormat">
<bean class="java.text.SimpleDateFormat">
<constructor-arg type="java.lang.String" value="yyyy-MM-dd HH:mm:ss" />
</bean>
</property>
</bean>
</property>
<!-- 避免IE执行AJAX时,返回JSON出现下载文件 -->
<property name="supportedMediaTypes">
<list>
<value>application/json;charset=UTF-8</value>
<value>text/html;charset=UTF-8</value>
</list>
</property>
</bean>
</mvc:message-converters>
</mvc:annotation-driven>