javaWeb实战教程
2.4 过滤器Filters
我们在访问http://localhost/javaWeb/lesson2_post.html
提交的表单,如果内容里输入了中文,servlet内取到的值就是乱码,如提交你好
,后台打印的却是??????
。
这是因为浏览器使用的编码和我们后台使用的编码不相同导致。我们可以在取值之前修改编码req.setCharacterEncoding("utf-8");
,这样再取值就不会乱码了。但每次取值前都要执行一遍很麻烦,我们可以使用过滤器Filters来统一处理编码问题。
我们先来了解一下什么是过滤器Filters。
过滤器是一个实现了 javax.servlet.Filter 接口的 Java 类。可以实现以下目的:
- 在客户端的请求访问后端资源之前,拦截这些请求。
- 在服务器的响应发送回客户端之前,处理这些响应。
在我们的项目里新建一个包:cn.funsoftware.Lesson.filter,再在包内新建一个类:Lesson3Filter.java,让该类实现接口javax.servlet.Filter:
public class Lesson3Filter implements Filter{
@Override
public void destroy() {
}
@Override
public void doFilter(ServletRequest request,
ServletResponse response, FilterChain chain) throws IOException,
ServletException {
}
@Override
public void init(FilterConfig arg0) throws ServletException {
}
}
filter的生命周期和servlet非常相同,不同的地方是,doFilter方法会在拦截到servlet前执行,并在servlet执行后再次执行,分割是chain.doFilter(request, response);
,
@Override
public void doFilter(ServletRequest request,
ServletResponse response, FilterChain chain) throws IOException,
ServletException {
//运行servlet前
chain.doFilter(request, response);
//运行servlet后
}
想要让这个filter发挥作用,我们还需要配置一下;和servlet一样,配置filter也有两种方法:
可以在类前加上注解@WebFilter(“/*”);
也可以在web.xml内配置:
<filter>
<filter-name>Lesson3Filter</filter-name>
<filter-class>cn.funsoftware.Lesson.filter.Lesson3Filter</filter-class>
</filter>
<filter-mapping>
<filter-name>Lesson3Filter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
其中/*
设置 filter 所拦截的请求路径。
我们在Lesson3Filter里输出一些话,看看访问servlet是否会打印出来:
@Override
public void doFilter(ServletRequest request,
ServletResponse response, FilterChain chain) throws IOException,
ServletException {
//调用servlet前
System.out.println("filter被调用啦");
chain.doFilter(request, response);
System.out.println("filter又被调用啦");
//调用servlet后
}
当我们再次提交刚刚的表单http://localhost/javaWeb/lesson2_post.html
时,控制台打印
filter被调用啦
你好
value2
filter又被调用啦
我们下面来做一个统一编码拦截器;新建一个拦截器,命名为EncodingFilter.java
,在doFilter方法里设置编码格式为utf-8
:request.setCharacterEncoding("utf-8");
:
@Override
public void doFilter(ServletRequest request,
ServletResponse response, FilterChain chian) throws IOException,
ServletException {
request.setCharacterEncoding("utf-8");
chian.doFilter(request, response);
response.setCharacterEncoding("utf-8");
}
再把Lesson2.java
中的req.setCharacterEncoding("utf-8");
删除,提交带中文的表单看看,已经不会出现乱码了。
过滤器filter除了可以做统一编码以外,还可以做其他的功能:
- 身份验证过滤器(Authentication Filters)。
- 数据压缩过滤器(Data compression Filters)。
- 加密过滤器(Encryption Filters)。
- 触发资源访问事件过滤器。
- 图像转换过滤器(Image Conversion Filters)。
- 日志记录和审核过滤器(Logging and Auditing Filters)。
- MIME-TYPE 链过滤器(MIME-TYPE Chain Filters)。
- 标记化过滤器(Tokenizing Filters)。
- XSL/T 过滤器(XSL/T Filters),转换 XML 内容。