处理SpringMVC中乱码问题
处理原生Servlet中请求和响应的乱码问题,参考文章
Servlet中的过滤器的实现及其原理,参考文章
配置CharacterEncodingFilter
在Servlet规范中要求request和response对象设置编码之前不能有获取请求参数和响应数据的操作
,否则后续设置的编码都将不起作用
- 但是DispatcherServlet给控制器方法注入request时一定是已经获取了所有的请求参数,否则我们不能直接在控制器方法上声明形参获取请求参数的值
在web.xml中注册SpringMVC提供的编码过滤器CharacterEncodingFilter
, 要想在DispatcherServlet获取参数前设置编码必须在其他过滤器之前配置它否则无效
- 使用
init-param初始化参数标签
设置encoding属性
的值指定POST请求的编码格式,如UTF-8 - 使用
init-param初始化参数标签
设置forceEncoding属性
的值指定响应的编码格式,true表示响应和请求的编码格式一致,fasle表示默认编码格式
xml
<!--配置一个字符编码的Filter,一定注意字符编码filter一般都在其他Filter之前-->
<filter>
<filter-name>CharacterEncodingFilter</filter-name>
<filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class>
<!--设置encoding属性的值解决POST请求乱码-->
<init-param>
<param-name>encoding</param-name>
<param-value>UTF-8</param-value>
</init-param>
<init-param>
<!--设置forceEncoding属性的值解决响应乱码-->
<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>
CharacterEncodingFilter
继承的OncePerRuquestFilter重写了doFilter(request,response,filter)并调用doFilterInternal(request,response,filter)方法执行过滤
java
// CharacterEncodingFilter的构造方法
public CharacterEncodingFilter(String encoding, boolean forceEncoding) {
// encoding属性的值是我们在配置文件中设置的编码格式
// forceEncoding属性的值就是我们在配置文件中设置的布尔值true
this(encoding,forceEncoding,forceEncoding);
}
public CharacterEncodingFilter(string encoding, boolean forceRequestEncoding, boolean forceResponseEncoding){
Assert.hasLength(encoding,"Encoding must not be empty");
this.encoding = encoding;
this.forceRequestEncoding = forceRequestEncoding;
this.forceResponseEncoding = forceResponseEncoding;
}
// OncePerRuquestFilter重写了doFilter(request,response,filter)
@override
public final void doFilter(ServletRequest request, ServletResponse response, FilterChain filterChain)
throws servletException, IOException {
//.............
// 满足条件放行
filterChain.doFilter(request,response);
// 不满足条件执行过滤规则
doFilterInternal(httprequest,httpresponse,filterChain);
}
// CharacterEncodingFilter重写的doFilterInternal方法
protected void doFilterInternal(HttpservletRequest request,
HttpservletResponse response, FilterChain filtel)throws ServletException,IOException {
string encoding = getEncoding();
// 判断我们在是否在web.xml文件中设置了编码格式
if (encoding != null) {
// 如果设置了编码格式,并且forceRequestEncoding的属性值为true或request对象之前没有设置过编码(确实没有设置过),此时就可以设置请求的编码
if (isForceRequestEncoding() || request.getcharacterEncoding() == null){
// 设置请求的编码
request.setCharacterEncoding(encoding);
}
// 如果设置了编码格式,并且forceResponseEncoding属性值为true,此时就可以设置响应的编码
if (isForceResponseEncoding()){
response.setcharacterEncoding(encoding);
}
}
// 放行
filterchain.dofilter(reauest. response);
}