zoukankan      html  css  js  c++  java
  • java过滤器filter使用

    一:filter:过滤器,拦截servlet的请求和响应。

    1、

     1 package jd.com.filter;
     2 
     3 import javax.servlet.*;
     4 import java.io.IOException;
     5 
     6 public class MyFilter implements Filter {
     7     @Override
     8     public void destroy() {
     9 
    10     }
    11 
    12     @Override
    13     public void init(FilterConfig filterConfig) {
    14 
    15     }
    16 
    17     @Override
    18     public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) {
    19 
    20         try {
    21             System.out.println("请求到拦截器。");
    22             //放行请求和响应。
    23             filterChain.doFilter(servletRequest,servletResponse);
    24             System.out.println("响应到拦截器。");
    25         }catch (Exception ex){
    26             ex.printStackTrace();
    27             throw new RuntimeException(ex+"run  ereror");
    28         }
    29 
    30     }
    31 }

     需要继承抽象类Filter,需要重写init和destory方法以及doFilter()方法。如果想放行请求和响应需要调用类FilterChain的方法doFilter(servletRequest,serletRespone)。

    servlet:

     1 package jd.com.filter;
     2 
     3 import javax.servlet.ServletException;
     4 import javax.servlet.annotation.WebServlet;
     5 import javax.servlet.http.HttpServlet;
     6 import javax.servlet.http.HttpServletRequest;
     7 import javax.servlet.http.HttpServletResponse;
     8 import java.io.IOException;
     9 
    10 @WebServlet(name = "ServletFilter")
    11 public class ServletFilter extends HttpServlet {
    12     protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
    13 
    14     }
    15 
    16     protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
    17             System.out.println("请求到servlet。");
    18     }
    19 }

    2、注册serlet和Filter。

     1 <?xml version="1.0" encoding="UTF-8"?>
     2 <web-app xmlns="http://java.sun.com/xml/ns/javaee"
     3            xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
     4            xsi:schemaLocation="http://java.sun.com/xml/ns/javaee
     5           http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
     6            version="2.5">
     7     <servlet>
     8         <servlet-name>ServletFilter</servlet-name>
     9         <servlet-class>jd.com.filter.ServletFilter</servlet-class>
    10     </servlet>
    11     <servlet-mapping>
    12         <servlet-name>ServletFilter</servlet-name>
    13         <url-pattern>/test/</url-pattern>
    14     </servlet-mapping>
    15     <filter>
    16         <filter-name>MyFilter</filter-name>
    17         <filter-class>jd.com.filter.MyFilter</filter-class>
    18     </filter>
    19     <filter-mapping>
    20         <filter-name>MyFilter</filter-name>
    21         <url-pattern>/test/</url-pattern>
    22     </filter-mapping>
    23 
    24 </web-app>

    想flter过滤那个url需要在url-pattern里写那个url!

    图示:

     2、FilterChain 过滤链

    当我们的jsp或者servlet被多个过滤器使用的时候,整个请求和响应形成的链叫做过滤链。

    通过过滤链FilterChain的doFilter方法,将一个请求从一个过滤器放行到下一个过滤器,直到最后一个过滤器被调用放行的时候,才到达最后的servlet或者jsp。

    doFilter()放行方法。区别于咱们重写抽象方法Filter的doFiltter()方法,一个是服务器调用一个是FilterChain调用。

    3、多个过滤器作用一个url的执行顺序(filter-mapping在web.xml的顺序决定):

    url匹配规则:

      1)完全匹配 : 必须以"/"开头  例如:"/a"

      2)目录匹配:  必须以"/"开头,以"*"结束,例如:"/a/*"

      3)后缀名匹配: 以“*”开头,以"jsp、do、action"结束的。例如:“”*.jsp  *.do *.action“”

    匹配规则:

      以精确匹配>最长路径匹配>后缀名匹配>默认匹配

    例1:比如servletA 的url-pattern为 /test,servletB的url-pattern为 /* ,这个时候,如果我访问的url为http://localhost/test ,这个时候容器就会先进行精确路径匹配,发现/test正好被servletA精确匹配,那么就去调用servletA,不会去管servletB。

    例2:比如servletA的url-pattern为/test/*,而servletB的url-pattern为/test/a/*,此时访问http://localhost/test/a时,容器会选择路径最长的servlet来匹配,也就是这里的servletB。 

    例3: 比如servletA的url-pattern:*.action ,servletB的url-pattern为 /* ,这个时候,如果我访问的url为http://localhost/test.action,这个时候容器就会优先进行路径匹配,而不是去匹配扩展名,这样就去调用servletB。

    filter匹配规则:

      例子:Afilter urlpattern:/*

         Bfilter urlpattern::/a/c

    servlet的url为:/a/c的时候,如上filter都会被使用,那Afilterr和Bfilter执行顺序是什么呢?

     web.xml注册顺序:

            <filter-name>FilterA</filter-name>
            <filter-class>jd.com.mapFilter.FilterA</filter-class>
        </filter>
        <filter-mapping>
            <filter-name>FilterA</filter-name>
            <url-pattern>/*</url-pattern>
        </filter-mapping>
        <filter>
            <filter-name>FilterB</filter-name>
            <filter-class>jd.com.mapFilter.FilterB</filter-class>
        </filter>
        <filter-mapping>
            <filter-name>FilterB</filter-name>
            <url-pattern>/a/c</url-pattern>
        </filter-mapping> 

    实际输出结果:

    (响应回来的时候先经过B在经过A)

    也就是说,执行filter的顺序是按照,在web.xml中的filter-mapping的顺序来决定,我们的这个2个顺序调换,看下输出:

     1     <filter>
     2         <filter-name>FilterA</filter-name>
     3         <filter-class>jd.com.mapFilter.FilterA</filter-class>
     4     </filter>
     5     <filter-mapping>
     6         <filter-name>FilterB</filter-name>
     7         <url-pattern>/a/c</url-pattern>
     8     </filter-mapping>
     9     <filter-mapping>
    10         <filter-name>FilterA</filter-name>
    11         <url-pattern>/*</url-pattern>
    12     </filter-mapping>
    13     <filter>
    14         <filter-name>FilterB</filter-name>
    15         <filter-class>jd.com.mapFilter.FilterB</filter-class>
    16     </filter>

     4)filter在web.xml其他标签:

      1、<servlet-name>Servletdemo1</servlet-name>位置 <filter-mapping>内表示匹配那个servlet。是servletname不是相对路径。

    注意:

      如果一个filter-mapping其中已经存在url-pattern 不要在存在servlet-name,在不同的版本中会重复执行2次过滤器!!

      2、<dispatcher></dispatcher> dispatch filter作用那种请求。

        请求(3和4了解):1、REQUEST:从浏览器发送过来的请求,这个filter的默认作用请求。

           2、FORWARD:转发过来的请求。

           3、ERROR:因为服务器错误而发送过来的请求。

           4、INCLUDE:包含过来的请求。

    1)默认情况(request)

    demo1:

     1 package jd.com.otherTag;
     2 
     3 import javax.servlet.ServletException;
     4 import javax.servlet.annotation.WebServlet;
     5 import javax.servlet.http.HttpServlet;
     6 import javax.servlet.http.HttpServletRequest;
     7 import javax.servlet.http.HttpServletResponse;
     8 import java.io.IOException;
     9 
    10 @WebServlet(name = "Servletdemo1")
    11 public class Servletdemo1 extends HttpServlet {
    12     protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
    13 
    14     }
    15 
    16     protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
    17             System.out.println("请求进入Servletdemo1");
    18             request.getRequestDispatcher("/a/b").forward(request,response);
    19     }
    20 }

    demo2:

     1 package jd.com.otherTag;
     2 
     3 import javax.servlet.ServletException;
     4 import javax.servlet.annotation.WebServlet;
     5 import javax.servlet.http.HttpServlet;
     6 import javax.servlet.http.HttpServletRequest;
     7 import javax.servlet.http.HttpServletResponse;
     8 import java.io.IOException;
     9 
    10 @WebServlet(name = "Servletdemo2")
    11 public class Servletdemo2 extends HttpServlet {
    12     protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
    13 
    14     }
    15 
    16     protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
    17         System.out.println("进入Servletdemo2 请求");
    18     }
    19 }

    web.xml

     1     <servlet>
     2         <servlet-name>Servletdemo1</servlet-name>
     3         <servlet-class>jd.com.otherTag.Servletdemo1</servlet-class>
     4     </servlet>
     5     <servlet-mapping>
     6         <servlet-name>Servletdemo1</servlet-name>
     7         <url-pattern>/a</url-pattern>
     8     </servlet-mapping>
     9     <filter>
    10         <filter-name>demoFilter</filter-name>
    11         <filter-class>jd.com.otherTag.demoFilter</filter-class>
    12     </filter>
    13     <filter-mapping>
    14         <filter-name>demoFilter</filter-name>
    15         <url-pattern>/*</url-pattern>
    16     </filter-mapping>
    17     <servlet>
    18         <servlet-name>Servletdemo2</servlet-name>
    19         <servlet-class>jd.com.otherTag.Servletdemo2</servlet-class>
    20     </servlet>
    21     <servlet-mapping>
    22         <servlet-name>Servletdemo2</servlet-name>
    23         <url-pattern>/a/b</url-pattern>
    24     </servlet-mapping>

    注意:

      因为filter的匹配url为/*所有 如果匹配的不是所有的话 需要注意的是filter的url和其他2个demo的url是包含关系。

     1     <servlet>
     2         <servlet-name>Servletdemo1</servlet-name>
     3         <servlet-class>jd.com.otherTag.Servletdemo1</servlet-class>
     4     </servlet>
     5     <servlet-mapping>
     6         <servlet-name>Servletdemo1</servlet-name>
     7         <url-pattern>/a/c</url-pattern>
     8     </servlet-mapping>
     9     <filter>
    10         <filter-name>demoFilter</filter-name>
    11         <filter-class>jd.com.otherTag.demoFilter</filter-class>
    12     </filter>
    13     <filter-mapping>
    14         <filter-name>demoFilter</filter-name>
    15         <url-pattern>/a/*</url-pattern>
    16     </filter-mapping>
    17     <servlet>
    18         <servlet-name>Servletdemo2</servlet-name>
    19         <servlet-class>jd.com.otherTag.Servletdemo2</servlet-class>
    20     </servlet>
    21     <servlet-mapping>
    22         <servlet-name>Servletdemo2</servlet-name>
    23         <url-pattern>/a/b</url-pattern>
    24     </servlet-mapping>

    结果:

    在转发的时候,没有经过demofilter,直接转发到servletdemo2.

    解决方法:

      默认情况下走的是请求是REQUEST,所以需要添加FORWARD的请求。注意需要写REQUEST请求,因为如果写其他请求默认请求不会生效。

     1     <filter>
     2         <filter-name>demoFilter</filter-name>
     3         <filter-class>jd.com.otherTag.demoFilter</filter-class>
     4     </filter>
     5     <filter-mapping>
     6         <filter-name>demoFilter</filter-name>
     7         <url-pattern>/a/*</url-pattern>
     8         <dispatcher>REQUEST</dispatcher>
     9         <dispatcher>FORWARD</dispatcher>
    10     </filter-mapping>

     结果:

     2)设置错误页。

     1     <servlet>
     2         <servlet-name>ServletError</servlet-name>
     3         <servlet-class>jd.com.coding.ServletError</servlet-class>
     4     </servlet>
     5     <servlet-mapping>
     6         <servlet-name>ServletError</servlet-name>
     7         <url-pattern>/c</url-pattern>
     8     </servlet-mapping>
     9     <error-page>
    10         <error-code>404</error-code>
    11         <location>/c</location>
    12     </error-page>
     1 package jd.com.coding;
     2 
     3 import javax.servlet.ServletException;
     4 import javax.servlet.annotation.WebServlet;
     5 import javax.servlet.http.HttpServlet;
     6 import javax.servlet.http.HttpServletRequest;
     7 import javax.servlet.http.HttpServletResponse;
     8 import java.io.IOException;
     9 
    10 @WebServlet(name = "ServletError")
    11 public class ServletError extends HttpServlet {
    12     protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
    13 
    14     }
    15 
    16     protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
    17         response.setContentType("text/html;charset=UTF-8");
    18         response.getWriter().print("亲访问的资源不存在!");
    19     }
    20 }
  • 相关阅读:
    ML(5)——神经网络1(神经元模型与激活函数)
    ML(4)——逻辑回归
    ML(附录3)——过拟合与欠拟合
    多变量微积分笔记24——空间线积分
    iOS开发--横向流水布局实现
    李洪强和你一起学习前端之面试题
    前端面试题 -- JS篇
    很强大的HTML+CSS+JS面试题(附带答案)
    李洪强iOS之集成极光推送三iOS集成指南
    李洪强iOS之集成极光推送二iOS 证书 设置指南
  • 原文地址:https://www.cnblogs.com/evilliu/p/8686467.html
Copyright © 2011-2022 走看看