JavaWeb三大组件之过滤器

1
0·
本文详细介绍了JavaWeb三大组件之一的过滤器。阐述了过滤器的概念、生命周期、相关参数,说明了如何编写过滤器,分析了单个和多个过滤器的执行流程及顺序,还介绍了过滤器的四种拦截方式,并给出FORWARD拦截方式的演示案例。过滤器
什么是过滤器
过滤器是JavaWeb三大组件之一,它与Servlet很相似!不它过滤器是用来拦截请求的,而不是处理请求的。当用户请求某个Servlet时,会先执行部署在这个请求上的Filter,如果Filter“放行”,那么会继承执行用户请求的Servlet;如果Filter不“放行”,那么就不会执行用户请求的Servlet。
它会在一组资源(jsp、servlet、.css、.html等等)的前面执行!
它可以让请求得到目标资源,也可以不让请求达到!Filter是单例的!
Filter的生命周期
void init(FilterConfig)
创建之后,马上执行;Filter会在服务器启动时就创建!
void destory()
销毁之前执行!在服务器关闭时销毁
void doFilter(ServletRequest,ServletResponse,FilterChain)
每次过滤时都会执行
FilterConfig和FilterChain参数
FilterConfig的作用:
- 获取初始化参数:getInitParameter()
- 获取过滤器名称:getFilterName()
- 获取appliction:getServletContext()
FilterChain的作用:
- doFilter(ServletRequest, ServletResponse):放行!
- 放行,就相当于调用了目标Servlet的service()方法!
Filter中的doFilter()方法和FilterChain中的doFilter()方法有什么不同
Filter中的doFilter()方法是指每次过滤都会被调用
FilterChain中的doFilter()方法是放行
如何编写一个Filter
写一个类实现Filter接口
在web.xml中进行配置
<filter><filter-name>xxx</filter-name><filter-class>cn.itcast.web.filter.AFitler</fitler-class></filter><fitler-mapping><filter-name>xxx</filter-name><url-pattern>/*</url-pattern></filter-mapping>
单个过滤器的执行流程
创建一个AFilter类,实现Filter接口
package cn.andios.test;import javax.servlet.*;import java.io.IOException;publicclassAFilterimplementsFilter{@Overridepublicvoidinit(FilterConfig filterConfig)throws ServletException{ System.out.println("我在服务器启动时立即执行");}@OverridepublicvoiddoFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain)throws IOException, ServletException{ System.out.println("拦截"); filterChain.doFilter(servletRequest,servletResponse);//放行,相当于调用了目标Servlet的service()方法! System.out.println("我又回来了");}@Overridepublicvoiddestroy(){ System.out.println("我在服务器关闭前执行");}}创建AServlet
package cn.andios.test;import javax.servlet.ServletException;import javax.servlet.http.HttpServlet;import javax.servlet.http.HttpServletRequest;import javax.servlet.http.HttpServletResponse;import java.io.IOException;publicclassAServletextendsHttpServlet{protectedvoiddoPost(HttpServletRequest request, HttpServletResponse response)throws ServletException, IOException{ System.out.println("AServlet执行了");}protectedvoiddoGet(HttpServletRequest request, HttpServletResponse response)throws ServletException, IOException{doPost(request,response);}}在web.xml中对过滤器进行配置
<?xml version="1.0" encoding="UTF-8"?><web-appxmlns="http://xmlns.jcp.org/xml/ns/javaee"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd"version="4.0"><!--配置servlet--><servlet><servlet-name>AServlet</servlet-name><servlet-class>cn.andios.test.AServlet</servlet-class></servlet><servlet-mapping><servlet-name>AServlet</servlet-name><url-pattern>/AServlet</url-pattern></servlet-mapping><!--配置过滤器--><filter><filter-name>AFilter</filter-name><filter-class>cn.andios.test.AFilter</filter-class></filter><filter-mapping><filter-name>AFilter</filter-name><url-pattern>/*</url-pattern></filter-mapping></web-app>测试结果
首先启动服务器,控制台输出了“我在服务器启动时立即执行”(说明执行了init方法)
然后请求AServlet,控制台又先后输出了:
“拦截”:说明执行了doFilter方法进行拦截
“AServlet执行了”:说明调用filterChain.doFilter(servletRequest,servletResponse);方法后,进行了放行
“我又回来了”:说明当放行后执行完被拦截的Servlet中的代码后,还会到过滤器中继续执行filterChain.doFilter(servletRequest,servletResponse);之后的代码。
多过滤器的执行流程
演示案例
创建一个AServlet
package cn.andios.test;import javax.servlet.ServletException;import javax.servlet.http.HttpServlet;import javax.servlet.http.HttpServletRequest;import javax.servlet.http.HttpServletResponse;import java.io.IOException;publicclassAServletextendsHttpServlet{protectedvoiddoPost(HttpServletRequest request, HttpServletResponse response)throws ServletException, IOException{ System.out.println("AServlet执行了");}protectedvoiddoGet(HttpServletRequest request, HttpServletResponse response)throws ServletException, IOException{doPost(request,response);}}创建一个AFilter
package cn.andios.test;import javax.servlet.*;import java.io.IOException;publicclassAFilterimplementsFilter{@Overridepublicvoidinit(FilterConfig filterConfig)throws ServletException{ System.out.println("我在服务器启动时立即执行");}@OverridepublicvoiddoFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain)throws IOException, ServletException{ System.out.println("AFilter####start"); filterChain.doFilter(servletRequest,servletResponse);//放行,相当于调用了目标Servlet的service()方法! System.out.println("AFilter####end");}@Overridepublicvoiddestroy(){ System.out.println("我在服务器关闭前执行");}}创建一个BFilter
package cn.andios.test;import javax.servlet.*;import java.io.IOException;public class BFilter implements Filter { @Override public void init(FilterConfig filterConfig) throws ServletException { System.out.println("我在服务器启动时立即执行"); } @Override public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException { System.out.println("BFilter####start"); filterChain.doFilter(servletRequest,servletResponse);//放行,相当于调用了目标Servlet的service()方法! System.out.println("BFilter####end"); } @Override public void destroy() { System.out.println("我在服务器关闭前执行"); }}在web.xml中完成配置
<?xml version="1.0" encoding="UTF-8"?><web-appxmlns="http://xmlns.jcp.org/xml/ns/javaee"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd"version="4.0"><servlet><servlet-name>AServlet</servlet-name><servlet-class>cn.andios.test.AServlet</servlet-class></servlet><servlet-mapping><servlet-name>AServlet</servlet-name><url-pattern>/AServlet</url-pattern></servlet-mapping><!--配置过滤器--><filter><filter-name>AFilter</filter-name><filter-class>cn.andios.test.AFilter</filter-class></filter><filter-mapping><filter-name>AFilter</filter-name><url-pattern>/AServlet</url-pattern></filter-mapping><!--配置过滤器--><filter><filter-name>BFilter</filter-name><filter-class>cn.andios.test.BFilter</filter-class></filter><filter-mapping><filter-name>BFilter</filter-name><url-pattern>/*</url-pattern></filter-mapping></web-app>测试:启动服务器,并访问AServlet
控制台输出
AFilter####start
BFilter####start
AServlet执行了
BFilter####end
AFilter####end
- 先进入的过滤器返回时将会后执行
- FilterChain的doFilter()方法:
执行目标资源,或是执行下一个过滤器!如果没有下一个过滤器那么执行的是目标资源,如果有,那么就执行下一个过滤器!
多个Filter的执行顺序:
看web.xml中的配置顺序,哪个位置在前,哪个过滤器就先执行。
过滤器的四种拦截方式
在中进行配置!
- REQUEST默认的!
- FORWARD
- INCLUDE
- ERROR
FORWARD拦截方式的演示
创建AServlet
package cn.andios.test;import javax.servlet.ServletException;import javax.servlet.http.HttpServlet;import javax.servlet.http.HttpServletRequest;import javax.servlet.http.HttpServletResponse;import java.io.IOException;publicclassAServletextendsHttpServlet{protectedvoiddoPost(HttpServletRequest request, HttpServletResponse response)throws ServletException, IOException{ System.out.println("AServlet执行了");}protectedvoiddoGet(HttpServletRequest request, HttpServletResponse response)throws ServletException, IOException{doPost(request,response);}}创建BServlet
package cn.andios.test;import javax.servlet.ServletException;import javax.servlet.http.HttpServlet;import javax.servlet.http.HttpServletRequest;import javax.servlet.http.HttpServletResponse;import java.io.IOException;publicclassBServletextendsHttpServlet{protectedvoiddoPost(HttpServletRequest request, HttpServletResponse response)throws ServletException, IOException{ request.getRequestDispatcher("/AServlet").forward(request,response);}protectedvoiddoGet(HttpServletRequest request, HttpServletResponse response)throws ServletException, IOException{doPost(request,response);}}创建AFilter
package cn.andios.test;import javax.servlet.*;import java.io.IOException;publicclassAFilterimplementsFilter{@Overridepublicvoidinit(FilterConfig filterConfig)throws ServletException{ System.out.println("我在服务器启动时立即执行");}@OverridepublicvoiddoFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain)throws IOException, ServletException{ System.out.println("AFilter####start"); filterChain.doFilter(servletRequest,servletResponse);//放行,相当于调用了目标Servlet的service()方法! System.out.println("AFilter####end");}@Overridepublicvoiddestroy(){ System.out.println("我在服务器关闭前执行");}}创建BFilter
package cn.andios.test;import javax.servlet.*;import java.io.IOException;publicclassBFilterimplementsFilter{@Overridepublicvoidinit(FilterConfig filterConfig)throws ServletException{ System.out.println("我在服务器启动时立即执行");}@OverridepublicvoiddoFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain)throws IOException, ServletException{ System.out.println("BFilter####start"); filterChain.doFilter(servletRequest,servletResponse);//放行,相当于调用了目标Servlet的service()方法! System.out.println("BFilter####end");}@Overridepublicvoiddestroy(){ System.out.println("我在服务器关闭前执行");}}web.xml配置
<?xml version="1.0" encoding="UTF-8"?><web-appxmlns="http://xmlns.jcp.org/xml/ns/javaee"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd"version="4.0"><servlet><servlet-name>AServlet</servlet-name><servlet-class>cn.andios.test.AServlet</servlet-class></servlet><servlet-mapping><servlet-name>AServlet</servlet-name><url-pattern>/AServlet</url-pattern></servlet-mapping><servlet><servlet-name>BServlet</servlet-name><servlet-class>cn.andios.test.BServlet</servlet-class></servlet><servlet-mapping><servlet-name>BServlet</servlet-name><url-pattern>/BServlet</url-pattern></servlet-mapping><!--配置过滤器--><filter><filter-name>AFilter</filter-name><filter-class>cn.andios.test.AFilter</filter-class></filter><filter-mapping><filter-name>AFilter</filter-name><url-pattern>/AServlet</url-pattern></filter-mapping><!--配置过滤器--><filter><filter-name>BFilter</filter-name><filter-class>cn.andios.test.BFilter</filter-class></filter><filter-mapping><filter-name>BFilter</filter-name><url-pattern>/*</url-pattern><dispatcher>FORWARD</dispatcher></filter-mapping></web-app>演示:启动服务器
访问AServlet,控制台输出了
AFilter####start
AServlet执行了
AFilter####end说明BFilter配置的拦截方式是FORWARD,所以他只拦截FORWARD转发,不会拦截request请求。执行的也自然是AFilter了
然后访问BServlet,控制台输出了
BFilter####start
AServlet执行了
BFilter####end说明BServlet发起请求转发时,被BFilter拦截了,且它只拦截FORWARD

















1392


























