过滤器Filter
一、过滤器
过滤器就是向web应用程序的请求和和响应添加功能的组件。过滤器能够实现客户端和目标资源之间的交互信息进行筛选和过滤,最终保留有效的数据信息。
二、过滤器的生命周期
2.1 实例化。
web容器复制创建过滤器的实例来完成过滤器的实例化,只会实例化一次。
2.2 初始化。
在进行过滤工作前会调用init()方法来实现初始化操作,也只初始化一次。
2.3 执行过滤
调用doFilter()方法来实现过滤器的特定功能
4.销毁
调用destory()方法,释放过滤器所占用的资源。
三、过滤器的应用
3.1 过滤器开发的四个步骤:
(1).创建实现Filter接口的类
(2).在doFilter()中编写实现过滤的方法。
(3).调用下一个过滤器或者web资源
(4).在web.xml文件中配置过滤器
3.2 创建Filter过滤器类
package demo.web.servlet; 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; public class CharacterEncodingFilter implements Filter { public void destroy() { } public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException { // 设置请求时的编码方法 request.setCharacterEncoding("utf-8"); // 调用web资源,也可以调用其他过滤器 chain.doFilter(request, response); // 设置响应时的编码方式 response.setCharacterEncoding("utf-8"); } public void init(FilterConfig arg0) throws ServletException { } }
再创建MyFilter过滤器类
package demo.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; public class MyFilter implements Filter { public void destroy() { // TODO Auto-generated method stub } public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException { // TODO Auto-generated method stub request.setCharacterEncoding("utf-8"); System.out.println("myFilter调用doFilter开始"); chain.doFilter(request, response); response.setCharacterEncoding("utf-8"); System.out.println("myFilter调用doFilter结束"); } public void init(FilterConfig filterConfig) throws ServletException { // TODO Auto-generated method stub } }
3.3 过滤器filter在web.xml中的配置
<filter> <filter-name>CharacterEncodingFilter</filter-name> <filter-class>demo.web.filter.CharacterEncodingFilter</filter-class> </filter> <filter-mapping> <filter-name>CharacterEncodingFilter</filter-name> <url-pattern>/*</url-pattern> <!-- 过滤站点的所有信息,配置与servlet类似可以是/xx/*或者/xx --> </filter-mapping>
<filter> <display-name>myFilter</display-name> <filter-name>myFilter</filter-name> <filter-class>demo.web.filter.MyFilter</filter-class> </filter> <filter-mapping> <filter-name>myFilter</filter-name> <url-pattern>/*</url-pattern> <!-- 过滤站点的所有信息 --> <dispatcher>REQUEST</dispatcher> </filter-mapping>
<dispatcher>指定过滤器所拦截的资源被 Servlet 容器调用的方式,可以是REQUEST,INCLUDE,FORWARD和ERROR之一,默认REQUEST。用户可以设置多个
<dispatcher> 子元素用来指定 Filter 对资源的多种调用方式进行拦截。
<dispatcher> 子元素可以设置的值及其意义:
1.REQUEST:当用户直接访问页面时,Web容器将会调用过滤器。如果目标资源是通过RequestDispatcher的include()或forward()方法访问时,那么该过滤器就不会被调用。
2.INCLUDE:如果目标资源是通过RequestDispatcher的include()方法访问时,那么该过滤器将被调用。除此之外,该过滤器不会被调用。
3.FORWARD:如果目标资源是通过RequestDispatcher的forward()方法访问时,那么该过滤器将被调用,除此之外,该过滤器不会被调用。
4.ERROR:如果目标资源是通过声明式异常处理机制调用时,那么该过滤器将被调用。除此之外,过滤器不会被调用。
3.4 过滤器链
在web应用中可以开发多个Filter过滤器,这些Filter组合起来就是一个Filter链。
web服务器根据Filter在web.xml文件中的注册顺序,决定先调用哪个Filter,当第一个Filter的doFilter方法被调用时,web服务器会创建一个代表Filter链的FilterChain对象传递
给该方法。在doFilter方法中,开发人员如果调用了FilterChain对象的doFilter方法,则web服务器会检查FilterChain对象中是否还有filter,如果有,则调用第2个filter,如果没
有,则调用目标资源。
还有创建servlet,已在上一篇servlet文章中创建
在浏览器中调用http://localhost:8080/servletDemo/myServlet,在控制台输出
有运行结果分析可知道:过滤是按照web.xml中配置的顺序先调用servlet的初始化,再调用CharacterEncodingFilter的doFilter方法,在程序执行到chain.doFilter(req,resp);
方法时会去调用web.xml中配置的characterEncodingFilter下边的Filter,也就是调用MyFilter中的doFilter()方法,过滤器这种嵌套执行完后才调用servlet的doGet()方法;
注意:这个过程servlet只会初始化一次,并且servlet初始化后不会再调用Filter的init()方法,Filter位于javax.servlet.filter包下。