利用Filter解决全站编码问题(复习)
在不使用filter之前,要想处理编码问题我们需要依据不同的请求方式,做出不同的编码处理
例如
1.一个请求方式为post的表单传入了servlet,需要设置编码格式对传入参数重新编码
public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
request.setCharacterEncoding("utf-8"); //需要设置编码格式对传入参数重新编码
response.setContentType("text/html;charset=utf-8");
}
2.而如果为get请求,那么步骤就更加繁琐,我们需要先将传入的表单数据先解码然后在编码
public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
String value = request.getParameter("name");
String newValue = new String(value.getBytes("iso-8859-1"), "utf-8");
doPost(request, response);
}
综上所述,如果我们像以上办法一样处理编码问题也是可以的,但是可以看出是很不方便的,每新增一个servlet都要写一遍重复的设置编码的内容,特别是get请求,如果传入的参数过多,就需要写很多解码转码的重复代码,很不方便,所以我们就要使用filter(过滤器).
Filter能干啥
可以对Jsp, Servlet, 静态图片文件或静态 html 文件等进行拦截,从而实现一些特殊的功能。例如实现URL级别的权限访问控制、过滤敏感词汇、压缩响应信息等一些高级功能。
它主要用于对用户请求进行预处理,也可以对HttpServletResponse 进行后处理。使用Filter 的完整流程:Filter 对用户请求进行预处理,接着将请求交给Servlet 进行处理并生成响应,最后Filter 再对服务器响应进行后处理。
filter咋用
使用filter就需要实现javax.servlet.Filter接口,该接口就三个方法需要实现
以处理编码的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;
public class CharsetEncodingFilter implements Filter {
private FilterConfig fconfig;
public void destroy() {
}
public void doFilter(ServletRequest req, ServletResponse resp, FilterChain chain)
throws IOException, ServletException {
HttpServletRequest request = (HttpServletRequest) req;
HttpServletResponse response = (HttpServletResponse) resp;
//编码从web.xml初始化参数中获取,没有配置就默认为utf-8
String encoding = fconfig.getInitParameter("CharsetEncoding");
if(encoding == null '' encoding.trim().isEmpty()) {
encoding = "UTF-8";
}
if(request.getMethod().equalsIgnoreCase("GET")) {
EncodingRequest er = new EncodingRequest(request, encoding); //使用重写之后的request
chain.doFilter(er, response);
} else if(request.getMethod().equalsIgnoreCase("POST")) {
req.setCharacterEncoding(encoding);
chain.doFilter(request, response);
}
}
@Override
public void init(FilterConfig filtercfg) throws ServletException {
this.fconfig = filtercfg;
}
}
重写request实现HttpServletRequestWrapper类,其目的就是为了重写其中的getParameter()方法
import java.io.UnsupportedEncodingException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletRequestWrapper;
public class EncodingRequest extends HttpServletRequestWrapper {
private HttpServletRequest req;
private String charsetEncoding;
public EncodingRequest(HttpServletRequest request, String encoding) {
super(request);
this.req = request;
this.charsetEncoding = encoding;
}
public String getParameter(String name) {
try {
String value = req.getParameter(name);
return new String(value.getBytes("iso-8859-1"), charsetEncoding); //java编码为iso-8859-1
} catch (UnsupportedEncodingException e) {
throw new RuntimeException(e);
}
}
}
filter和servlet一样,还需要在web.xml中注册才能使用,而配置的方法也和servlet大同小异
如
<filter>
<filter-name>CharsetEncodingFilter</filter-name>
<filter-class>com.infosys.filter.CharsetEncodingFilter</filter-class>
<init-param>
<param-name>CharsetEncoding</param-name> ---初始化参数,可以再filter初始化的使用读取
<param-value>UTF-8</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>CharsetEncodingFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>