前提介绍
在Java web中,实现Filter接口,可以自定义Filetr(即拦截器),在实际业务逻辑处理之前拦截请求并做出处理。这样的模式可以实现包括编码、请求加密解密、日志、监控等一些和实际业务逻辑没有太多关联的操作,从而做到系统代码的低耦合,使得后期维护起来更加方便。
实现功能
通过自定义Filter,对请求的中文编码进行操作,可以解决浏览器GET请求参数中文乱码问题。
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;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
/**
* modified by xuyihao on 2016/4/3
*
* @description: 用来解决post,get请求乱码问题
*/
/**
* 用来解决post,get请求乱码问题
*
* @Author Xuyh created on 2016/4/3
*
*/
public class CharacterEncodingFilter implements Filter {
// 定义编码格式变量
protected String encoding = null;
// 定义过滤器配置对象
protected FilterConfig filterConfig = null;
public void init(FilterConfig filterConfig) throws ServletException {
// 初始化过滤器配置对象
this.filterConfig = filterConfig;
this.encoding = filterConfig.getInitParameter("encoding");
}
/**
* 实现执行过滤方法
*/
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
throws IOException, ServletException {
HttpServletRequest req = (HttpServletRequest) request;
HttpServletResponse res = (HttpServletResponse) response;
if (encoding != null) {
// 设置请求的编码
req.setCharacterEncoding(encoding);
// 设置应答对象的内容类型(包括编码格式)
res.setCharacterEncoding(encoding);
res.setContentType("text/html; charset=" + encoding);
}
MyCharacterEncodingRequest requestWrapper = new MyCharacterEncodingRequest(req);
// 传递给下一个过滤器
chain.doFilter(requestWrapper, res);
}
public void destroy() {
this.encoding = null;
this.filterConfig = null;
}
}
这是自定义的Filter,其中用到了类MyCharacterEncodingRequest,这是重写了javax.servlet.http.HttpServletRequestWrapper的类,在servlet使用到request对象时候此类的对象就会充当request对象的角色,代码实现如下:
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletRequestWrapper;
import java.util.Properties;
/**
* 重写HttpServletRequest的部分方法实现post,get请求中文乱码问题
*
* @Author Xuyh created on 2016/4/3
*
*/
public class MyCharacterEncodingRequest extends HttpServletRequestWrapper {
private HttpServletRequest request;
public MyCharacterEncodingRequest(HttpServletRequest req) {
super(req);
this.request = req;
}
/**
* 重写需要增强的getParameter方法
* 使其具有GET请求转码功能
*/
@Override
public String getParameter(String name) {
try {
String value = this.request.getParameter(name);
if (value == null) {
return null;
}
if (!this.request.getMethod().equalsIgnoreCase("get")) {// 不是get方法请求
return value;
} else {// 是get方法请求
value = new String(value.getBytes("ISO-8859-1"), "UTF-8");
return value;
}
} catch (Exception e) {
throw new RuntimeException(e);
}
}
}
实现了HttpServletRequestWrapper 之后,拦截器将request对象传递给servlet,在servlet中调用request对象的getParameter方法之,如果是GET请求则会将请求参数以UTF-8编码,中文乱码问题就会解决了。
下面是web.xml中注册的Filter
<filter>
<filter-name>CharacterEncodingFilter</filter-name>
<filter-class>filter.CharacterEncodingFilter</filter-class>
<init-param>
<param-name>encoding</param-name>
<param-value>UTF-8</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>CharacterEncodingFilter</filter-name>
<url-pattern>/*</url-pattern>
<dispatcher>REQUEST</dispatcher>
<dispatcher>FORWARD</dispatcher>
</filter-mapping>