首先,我们来回顾下,当我们打开浏览器访问服务器的时候如果传送过去一些数据,如果发过去的数据有中文,我们不可避免的都要解决乱码(不管其是get请求还是post请求。)
类似的我们总要调用如下的代码:
Get请求时:
String username = request.getParameter(“username”);
new String(username.getBytes(“ISO8859-1”),”UTF-8”);
Post请求时:
request.setCharacterEncoding(“UTF-8”);
由于我们的过滤器是在执行servlet之前执行的,然后调用filterChain.doFilter(request,response) 方法才放行,那么我们就可以在配置一个过滤器,这个过滤器对任何请求都拦截,那么在拦截的时候就对request的编码进行处理,然后再放行,就可以解决所有的乱码问题了。
使用Decorator模式包装request对象,完全解决get、post请求方式下的乱码问题。
1.创建处理get/post请求参数乱码问题的MyHttpServletRequestWrapper
package blog.csdn.net.web.filter;
import java.util.Map;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletRequestWrapper;
/**
* HttpServletRequest增强类
*
* @author mChenys
*
*/
public class MyHttpServletRequestWrapper extends HttpServletRequestWrapper {
private HttpServletRequest request;
public MyHttpServletRequestWrapper(HttpServletRequest request) {
super(request);
this.request = request;
}
@Override
public String getParameter(String name) {
String[] values = this.getParameterValues(name);
return values == null ? null : values[0];
}
@Override
public String[] getParameterValues(String name) {
Map<String, String[]> map = this.getParameterMap();
String[] values = map.get(name);
return values;
}
private boolean hasEncode;// 避免重复编码
/**
* 上面2个方法最终是调用这个方法,所有统一在这个方法处理请求参数乱码问题
*/
@Override
public Map<String, String[]> getParameterMap() {
Map<String, String[]> map = super.getParameterMap();
String method = this.request.getMethod();
try {
if (method.equalsIgnoreCase("post")) {
// post请求,直接设置这句话即可
this.request.setCharacterEncoding("utf-8");
} else if (method.equalsIgnoreCase("get")) {
// 通过遍历参数名获取说有的参数值
if (!hasEncode) {
hasEncode = true;
for (String name : map.keySet()) {
String[] values = map.get(name);
for (int i = 0; i < values.length; i++) {
// 在这里处理编码
values[i] = new String(values[i].getBytes("iso8859-1"), "utf-8").trim();
}
}
}
}
} catch (Exception e) {
}
return map;
}
}
2.创建GenericEncodingFilter
package blog.csdn.net.web.filter;
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;
/**
* 处理全站乱码问题的filter
* @author mChenys
*
*/
public class GenericEncodingFilter implements Filter{
@Override
public void init(FilterConfig filterConfig) throws ServletException {
}
@Override
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
throws IOException, ServletException {
//强转
HttpServletRequest httpServletRequest = (HttpServletRequest) request;
HttpServletResponse httpServletResponse = (HttpServletResponse) response;
//统一处理响应编码
httpServletResponse.setCharacterEncoding("utf-8");
//统一处理请求参数编码,使用增强后的request包装httpServletRequest
MyHttpServletRequestWrapper req = new MyHttpServletRequestWrapper(httpServletRequest);
//放行
chain.doFilter(req, httpServletResponse);
}
@Override
public void destroy() {
}
}
3.注册filter
<!-- 全站乱码处理-->
<filter>
<filter-name>GenericEncodingFilter</filter-name>
<filter-class>blog.csdn.net.web.filter.GenericEncodingFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>GenericEncodingFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>