• 学习笔记_过滤器详细_2(过滤器JavaWeb三大组件之一)


     
                                                                 过滤器详细
    5 四种拦截方式

         我们来做个测试,写一个过滤器,指定过滤的资源为b.jsp,然后我们在浏览器中直接访问b.jsp,你会发现过滤器执行了!

         但是,当我们在a.jsp中request.getRequestDispathcer(“/b.jsp”).forward(request,response)时,就不会再执行过滤器了!也就是说,默认情况下,只能直接访问目标资源才会执行过滤器,而forward执行目标资源,不会执行过滤器!(跳转的不会执行F)

    public class MyFilter extends HttpFilter {
        public void doFilter(HttpServletRequest request,
               HttpServletResponse response, FilterChain chain)
               throws IOException, ServletException {
           System.out.println("myfilter...");
           chain.doFilter(request, response);
        }
    }  
        <filter>
           <filter-name>myfilter</filter-name>
           <filter-class>cn.itcast.filter.MyFilter</filter-class>
        </filter>
        <filter-mapping>
           <filter-name>myfilter</filter-name>
           <url-pattern>/b.jsp</url-pattern>
        </filter-mapping>
    <body> <h1>b.jsp</h1> </body> <h1>a.jsp</h1> <% request.getRequestDispatcher("/b.jsp").forward(request, response); %> </body>

    http://localhost:8080/filtertest/b.jsp -->直接访问b.jsp时,会执行过滤器内容; 

    http://localhost:8080/filtertest/a.jsp --> 访问a.jsp,但a.jsp会forward到b.jsp,这时就不会执行过滤器!

     

           其实过滤器有四种拦截方式!分别是:REQUEST、FORWARD、INCLUDE、ERROR

           l  REQUEST:直接访问目标资源时执行过滤器。包括:在地址栏中直接访问、表单提交、超链接、重定向,只要在地址栏中可以看到目标资源的路径,就是REQUEST;

          l  FORWARD:转发访问执行过滤器。包括RequestDispatcher#forward()方法、<jsp:forward>标签都是转发访问;

          l  INCLUDE:包含访问执行过滤器。包括RequestDispatcher#include()方法、<jsp:include>标签都是包含访问;

          l  ERROR:当目标资源在web.xml中配置为<error-page>中时,并且真的出现了异常,转发到目标资源时,会执行过滤器。

     

          可以在<filter-mapping>中添加0~n个<dispatcher>子元素,来说明当前访问的拦截方式。

        <filter-mapping>

           <filter-name>myfilter</filter-name>

           <url-pattern>/b.jsp</url-pattern>

           <dispatcher>REQUEST</dispatcher>[崔1] 

           <dispatcher>FORWARD</dispatcher>[崔2] 

        </filter-mapping>

        <filter-mapping>

           <filter-name>myfilter</filter-name>

           <url-pattern>/b.jsp</url-pattern>

        </filter-mapping>[崔3] 

        <filter-mapping>

           <filter-name>myfilter</filter-name>

           <url-pattern>/b.jsp</url-pattern>

           <dispatcher>FORWARD</dispatcher>[崔4] 

        </filter-mapping>

           

     [崔1]b.jsp为目标资源,当直接请求b.jsp时,会执行过滤器

     [崔2]当转发到b.jsp页面时,会执行过滤器(这种申明了就可以转发的也执行过滤器

     [崔3]当没有给出拦截方式时,那么默认为REQUEST

     [崔4]当转发到b.jsp页面时,会执行过滤器!因为已经给出了<dispatcher>FORWARD</dispatcher>了,那么就没有默认的REQUEST了!所以只有在转发到b.jsp时才会执行过滤,而转发到b.jsp时,不会执行b.jsp

         其实最为常用的就是REQUEST和FORWARD两种拦截方式,而INCLUDE和ERROR都比较少用!其中INCLUDE比较好理解,我们这里不再给出代码,可以通过FORWARD方式修改,来自己测试。而ERROR方式不易理解,下面给出ERROR拦截方式的例子:

        <filter-mapping>

           <filter-name>myfilter</filter-name>

           <url-pattern>/b.jsp</url-pattern>

           <dispatcher>ERROR</dispatcher>[崔5] 

        </filter-mapping>

        <error-page>

           <error-code>500</error-code>

           <location>/b.jsp</location>[崔6] 

        </error-page>

      <body>

      <h1>a.jsp</h1>

       <%

       if(true)

       throw new RuntimeException("嘻嘻~");[崔7] 

       %>

      </body>

     

     [崔5]拦截方式为ERROR

     [崔6]把b.jsp执行为500的错误页面

     [崔7]当用户访问a.jsp页面时会抛出异常,即500了!

    这时服务器会转发到b.jsp,在这之前会执行过滤器!

    6 过滤器的应用场景

        过滤器的应用场景:

       l  执行目标资源之前做预处理工作,例如设置编码,这种试通常都会放行,只是在目标资源执行之前做一些准备工作;[c8] 

       l  通过条件判断是否放行,例如校验当前用户是否已经登录,或者用户IP是否已经被禁用;

       l  在目标资源执行后,做一些后续的特殊处理工作,例如把目标资源输出的数据进行处理[c9] ;

     

     [c8]几乎是的Sevlet中都需要写request.setCharacterEndoing() 可以把它入到一个Filter中(中文乱码必须添加,因为架构后面影藏了一些编码分方式,只能在过滤器中去声明)

     [c9]回程拦截!

    7 设置目标资源

         在web.xml文件中部署Filter时,可以通过“*”来执行目标资源:

        <filter-mapping>

           <filter-name>myfilter</filter-name>

           <url-pattern>/*</url-pattern>[崔10] 

        </filter-mapping>

     

         这一特性与Servlet完全相同!通过这一特性,我们可以在用户访问敏感资源时,执行过滤器,例如:<url-pattern>/admin/*<url-pattern>,可以把所有管理员才能访问的资源放到/admin路径下,这时可以通过过滤器来校验用户身份。

         还可以为<filter-mapping>指定目标资源为某个Servlet,例如:

        <servlet>

           <servlet-name>myservlet</servlet-name>

           <servlet-class>cn.itcast.servlet.MyServlet</servlet-class>

        </servlet>

        <servlet-mapping>

           <servlet-name>myservlet</servlet-name>

           <url-pattern>/abc</url-pattern>

        </servlet-mapping>

        <filter>

           <filter-name>myfilter</filter-name>

           <filter-class>cn.itcast.filter.MyFilter</filter-class>

        </filter>

        <filter-mapping>

           <filter-name>myfilter</filter-name>

           <servlet-name>myservlet</servlet-name>[崔11] 

        </filter-mapping>

     

      当用户访问http://localhost:8080/filtertest/abc时,会执行名字为myservlet的Servlet,这时会执行过滤器。

     [崔10]表示过滤所有资源

     [崔11]这里没有指定<url-pattern>,而是指定<servlet-name>!注意,它与某个Servlet的配置名称相同!

    每天都做更好的自己,不纠结于输赢成败
  • 相关阅读:
    linux---集群架构初探(14)静态、动态、流量术语
    linux---集群架构初探(13)http与www服务基础介绍
    linux---集群架构初探(12)ansible剧本模式(playbook)
    linux---集群架构初探(11) 实践:一键部署nfs
    linux---集群架构初探(10)Ansible常用模块
    试题一 讲解
    aws 试题
    linux 常用命令。
    nohub命令简单介绍。
    Linux 系统conda环境,pip文件的导出和安装。
  • 原文地址:https://www.cnblogs.com/snowwhite/p/4639463.html
Copyright © 2020-2023  润新知