首先由下图看一下filter的原理图
javaWeb解决中文乱码的配置网上一大推,此处不再赘述;此处只实现自定义的filter来对request请求和response响应做相应的编码控制,详见下列代码package com.medicine.web;
import java.io.IOException;
import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
/**
* 字符编码过滤器
*
* @author wk
*
*/
public class CharacterEncodingFilter implements Filter {
protected String encoding = null;
protected String resType = null;
protected FilterConfig filterConfig = null;
protected boolean ignore = true;
@Override
public void destroy() {
// 销毁所有全局变量的值,设为null
this.encoding = null;
this.filterConfig = null;
this.resType = null;
}
@Override
public void doFilter(ServletRequest request, ServletResponse response,
FilterChain filterChain) throws IOException, ServletException {
// 从web.xml中得到过滤器的字符串编码
if (ignore || (request.getCharacterEncoding() == null)) {
if (encoding != null) {
request.setCharacterEncoding(encoding);
response.setCharacterEncoding(encoding);
response.setContentType(resType);
}
}
filterChain.doFilter(request, response);
}
@Override
public void init(FilterConfig filterConfig) throws ServletException {
this.filterConfig = filterConfig;
this.encoding = filterConfig.getInitParameter("encoding");
this.resType = filterConfig.getInitParameter("resType") == null ? "text/html; charset=utf-8"
: filterConfig.getInitParameter("resType");
String value = filterConfig.getInitParameter("ignore");
if (value == null)
this.ignore = true;
else if (value.equalsIgnoreCase("true"))
this.ignore = true;
else
this.ignore = false;
}
}
web.xml中配置如下:
package com.medicine.web;
import java.io.IOException;
import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
/**
* 字符编码过滤器
*
* @author wk
*
*/
public class CharacterEncodingFilter implements Filter {
protected String encoding = null;
protected String resType = null;
protected FilterConfig filterConfig = null;
protected boolean ignore = true;
@Override
public void destroy() {
// 销毁所有全局变量的值,设为null
this.encoding = null;
this.filterConfig = null;
this.resType = null;
}
@Override
public void doFilter(ServletRequest request, ServletResponse response,
FilterChain filterChain) throws IOException, ServletException {
// 从web.xml中得到过滤器的字符串编码
if (ignore || (request.getCharacterEncoding() == null)) {
if (encoding != null) {
request.setCharacterEncoding(encoding);
response.setCharacterEncoding(encoding);
response.setContentType(resType);
}
}
filterChain.doFilter(request, response);
}
@Override
public void init(FilterConfig filterConfig) throws ServletException {
this.filterConfig = filterConfig;
this.encoding = filterConfig.getInitParameter("encoding");
this.resType = filterConfig.getInitParameter("resType") == null ? "text/html; charset=utf-8"
: filterConfig.getInitParameter("resType");
String value = filterConfig.getInitParameter("ignore");
if (value == null)
this.ignore = true;
else if (value.equalsIgnoreCase("true"))
this.ignore = true;
else
this.ignore = false;
}
}
<span style="white-space:pre"> </span><filter>
<filter-name>CharacterEncodingFilter</filter-name>
<filter-class>com.medicine.web.CharacterEncodingFilter</filter-class>
<init-param>
<param-name>encoding</param-name>
<param-value>UTF-8</param-value>
</init-param>
<init-param>
<param-name>resType</param-name>
<param-value>text/html; charset=utf-8</param-value>
</init-param>
<init-param>
<param-name>ignore</param-name>
<param-value>true</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>CharacterEncodingFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
当然其实Spring中已经为我们提供了org.springframework.web.filter.CharacterEncodingFilter来专门解决中文乱码的问题,但是查看它的源码
<span style="white-space:pre"> </span>@Override
protected void doFilterInternal(
HttpServletRequest request, HttpServletResponse response, FilterChain filterChain)
throws ServletException, IOException {
if (this.encoding != null && (this.forceEncoding || request.getCharacterEncoding() == null)) {
request.setCharacterEncoding(this.encoding);
if (this.forceEncoding) {
response.setCharacterEncoding(this.encoding);
}
}
filterChain.doFilter(request, response);
}
可以发现它只对response进行了相应编码却没有对响应头进行处理,所以这也是我选择自定义filter的原因