Movatterモバイル変換


[0]ホーム

URL:


JavaWeb三大组件之过滤器

最新推荐文章于 2024-08-26 14:18:37 发布
原创最新推荐文章于 2024-08-26 14:18:37 发布·244 阅读
· 1
· 0·
CC 4.0 BY-SA版权
版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明。
本文详细介绍了JavaWeb三大组件之一的过滤器。阐述了过滤器的概念、生命周期、相关参数,说明了如何编写过滤器,分析了单个和多个过滤器的执行流程及顺序,还介绍了过滤器的四种拦截方式,并给出FORWARD拦截方式的演示案例。

过滤器

什么是过滤器

  1. 过滤器是JavaWeb三大组件之一,它与Servlet很相似!不它过滤器是用来拦截请求的,而不是处理请求的。当用户请求某个Servlet时,会先执行部署在这个请求上的Filter,如果Filter“放行”,那么会继承执行用户请求的Servlet;如果Filter不“放行”,那么就不会执行用户请求的Servlet。

  2. 它会在一组资源(jsp、servlet、.css、.html等等)的前面执行!
    它可以让请求得到目标资源,也可以不让请求达到!

  3. Filter是单例的!

Filter的生命周期

  1. void init(FilterConfig)

    创建之后,马上执行;Filter会在服务器启动时就创建!

  2. void destory()

    销毁之前执行!在服务器关闭时销毁

  3. void doFilter(ServletRequest,ServletResponse,FilterChain)

    每次过滤时都会执行

FilterConfig和FilterChain参数

  1. FilterConfig的作用:

    • 获取初始化参数:getInitParameter()
    • 获取过滤器名称:getFilterName()
    • 获取appliction:getServletContext()
  2. FilterChain的作用:

    • doFilter(ServletRequest, ServletResponse):放行!
    • 放行,就相当于调用了目标Servlet的service()方法!

    Filter中的doFilter()方法和FilterChain中的doFilter()方法有什么不同

    1. Filter中的doFilter()方法是指每次过滤都会被调用

    2. FilterChain中的doFilter()方法是放行

如何编写一个Filter

  1. 写一个类实现Filter接口

  2. 在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>

单个过滤器的执行流程

  1. 创建一个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("我在服务器关闭前执行");}}
  2. 创建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);}}
  3. 在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>
  4. 测试结果

    • 首先启动服务器,控制台输出了“我在服务器启动时立即执行”(说明执行了init方法)

    • 然后请求AServlet,控制台又先后输出了:

      • “拦截”:说明执行了doFilter方法进行拦截

      • “AServlet执行了”:说明调用filterChain.doFilter(servletRequest,servletResponse);方法后,进行了放行

      • “我又回来了”:说明当放行后执行完被拦截的Servlet中的代码后,还会到过滤器中继续执行filterChain.doFilter(servletRequest,servletResponse);之后的代码。

多过滤器的执行流程

演示案例

  1. 创建一个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);}}
  2. 创建一个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("我在服务器关闭前执行");}}
  3. 创建一个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("我在服务器关闭前执行");    }}
  4. 在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>
  5. 测试:启动服务器,并访问AServlet

    控制台输出

    AFilter####start
    BFilter####start
    AServlet执行了
    BFilter####end
    AFilter####end

  • 先进入的过滤器返回时将会后执行
  1. FilterChain的doFilter()方法:
    执行目标资源,或是执行下一个过滤器!如果没有下一个过滤器那么执行的是目标资源,如果有,那么就执行下一个过滤器!

多个Filter的执行顺序:

看web.xml中的配置顺序,哪个位置在前,哪个过滤器就先执行。

过滤器的四种拦截方式

在中进行配置!

  • REQUEST默认的!
  • FORWARD
  • INCLUDE
  • ERROR

FORWARD拦截方式的演示

  1. 创建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);}}
  2. 创建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);}}
  3. 创建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("我在服务器关闭前执行");}}
  4. 创建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("我在服务器关闭前执行");}}
  5. 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>
  6. 演示:启动服务器

    • 访问AServlet,控制台输出了

      AFilter####start
      AServlet执行了
      AFilter####end

      说明BFilter配置的拦截方式是FORWARD,所以他只拦截FORWARD转发,不会拦截request请求。执行的也自然是AFilter了

    • 然后访问BServlet,控制台输出了

      BFilter####start
      AServlet执行了
      BFilter####end

      说明BServlet发起请求转发时,被BFilter拦截了,且它只拦截FORWARD

确定要放弃本次机会?
福利倒计时
::

立减 ¥

普通VIP年卡可用
立即使用
参与评论您还未登录,请先登录后发表或查看评论

博客等级

码龄9年
29
原创
27
点赞
60
收藏
4
粉丝
关注
私信

热门文章

分类专栏

展开全部收起

上一篇:
JavaWeb三大组件之监听器
下一篇:
java面经

大家在看

最新文章

目录

展开全部

收起

目录

展开全部

收起

上一篇:
JavaWeb三大组件之监听器
下一篇:
java面经

目录

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
被折叠的  条评论为什么被折叠?到【灌水乐园】发言
查看更多评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值

[8]ページ先頭

©2009-2025 Movatter.jp