美文网首页
filter过滤器基本使用

filter过滤器基本使用

作者: _FireFly_ | 来源:发表于2019-10-04 20:17 被阅读0次

    1.Filter Tomcat提供的一个组件
    2.Filter是一个特殊的Servlet
    3.基本使用
    创建一个类 继承HttpFilter(Tomcat9之后) 实现Filter接口(Tomcat9之前)
    重写方法doFilter方法
    三个参数HttpServletRequest HttpServletResponse FilterChain
    配置xml文件
    4.管理机制
    继承或实现的关系
    filter对象是单例 生命周期托管的方式 立即加载的方式
    发送请求 从浏览器出发 会经过filter
    从服务器内部出发 转发默认是不经过filter(设置) 重定向经过filter
    5.过滤器链
    好多个filter对象 都处理相同的请求 /*
    我们经过filter不是目的 找到真实的资源
    经过的filter会在真实资源执行之前做些事情 之后也会做事情

    1.先自定义一个class类,继承HttpFilter(在Tomcat9.0之后是继承HttpFilter,在Tomcat9.0之前是实现Filter接口)这里以Tomcat9.0为例

    package filter;
    import javax.servlet.FilterChain;
    import javax.servlet.FilterConfig;
    import javax.servlet.ServletException;
    import javax.servlet.http.HttpFilter;
    import javax.servlet.http.HttpServletRequest;
    import javax.servlet.http.HttpServletResponse;
    import javax.servlet.http.HttpSession;
    import java.io.IOException;
    import java.util.Enumeration;
    
    //小护士
    public class FilterOne extends HttpFilter {
    
        public void init(FilterConfig filterConfig) throws ServletException {
            Enumeration en = filterConfig.getInitParameterNames();
            while(en.hasMoreElements()){
                String key = (String)en.nextElement();
                String value = filterConfig.getInitParameter(key);
                System.out.println(key+"--"+value);
            }
        }
    
        protected void doFilter(HttpServletRequest request, HttpServletResponse response, FilterChain chain) throws IOException, ServletException {
            System.out.println("我是filter 找我干嘛呀");
    
            HttpSession session = request.getSession();
            String aname = (String)session.getAttribute("aname");
            //获取请求路径
            String uri = request.getRequestURI();
            //先判断大前提  请求的时候 是否包含index login
            if(uri.contains("index") || uri.contains("login")){
                 //这俩个请求是登陆请求,所以直接放行,要不然死循环,session中永远不会有值
                //放行 此时还没有真正做登录判断
                chain.doFilter(request,response);
            }else{
                //应该是登录成功之后的某一个功能
                if(aname!=null){
                    chain.doFilter(request,response);
                }else{
                    request.setAttribute("result","登录已超时,请重新登录");
                    request.getRequestDispatcher("index.jsp").forward(request,response);
                }
            }
    
            //1.直接给予响应  自己拼接字符串
            //response.getWriter().write("<>");
            //2.可以(请求)转发
            //request.getRequestDispatcher("路径").forward(request,response);
            //3.可以(请求)重定向
            //response.sendRedirect("路径");
            //4.可以放行
            //chain.doFilter(request,response);
        }
    }
    

    2.自定义一个class类,继承HttpServlet

    package controller;
    
    import service.AtmService;
    
    import javax.servlet.ServletException;
    import javax.servlet.http.HttpServlet;
    import javax.servlet.http.HttpServletRequest;
    import javax.servlet.http.HttpServletResponse;
    import javax.servlet.http.HttpSession;
    import java.io.IOException;
    
    //目标
    public class LoginController extends HttpServlet {
    
        private AtmService service = new AtmService();
    
        protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
            request.setCharacterEncoding("UTF-8");
            //1.获取请求参数
            String aname = request.getParameter("aname");
            String apassword = request.getParameter("apassword");
            //2.调用业务方法干活儿
            String result = service.login(aname,apassword);
            //3.给予响应    转发
            if(result.equals("登录成功")) {
                //将人名存储在session作用域内啦
                HttpSession session = request.getSession();
                session.setAttribute("aname",aname);
                session.setMaxInactiveInterval(8);  <!--设置session的有效期-->
                request.getRequestDispatcher("welcome.jsp").forward(request, response);
            }else {
                request.setAttribute("result",result);
                request.getRequestDispatcher("index.jsp").forward(request,response);
            }
        }
    }
    
    

    3.在web.xml中配置Filter

    <?xml version="1.0" encoding="UTF-8"?>
    <web-app xmlns="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">
    
    
           <!--处理login请求的servlet-->
        <servlet>
            <servlet-name>login</servlet-name>
            <servlet-class>controller.LoginController</servlet-class>
        </servlet>
        <servlet-mapping>
            <servlet-name>login</servlet-name>
            <url-pattern>/login</url-pattern>
        </servlet-mapping>
    
           <!--处理项目下所有请求的filter-->
        <filter>
            <filter-name>filterOne</filter-name>
            <filter-class>filter.FilterOne</filter-class>
            <init-param>
                <param-name>key1</param-name>
                <param-value>value1</param-value>
            </init-param>
            <init-param>
                <param-name>key2</param-name>
                <param-value>value2</param-value>
            </init-param>
            <init-param>
                <param-name>key3</param-name>
                <param-value>value3</param-value>
            </init-param>
        </filter>
        <filter-mapping>
            <filter-name>filterOne</filter-name>
            <url-pattern>/*</url-pattern>                  <!--/代码项目根目录的意思,/*代表项目根目录下的所有请求-->
            <!--<dispatcher>REQUEST</dispatcher>-->        <!-- 默认不填写是这个-->
            <!--<dispatcher>FORWARD</dispatcher>-->        <!-- 如果填写了这个,则只拦截forward请求-->
            <!-- 如果俩个请求都想拦截,则两个都需要写,只写一个会默认覆盖其他的-->
             <dispatcher>REQUEST</dispatcher>
             <dispatcher>FORWARD</dispatcher>
        </filter-mapping>
    </web-app>
    

    请求转发和重定向在过滤器中的过程

    转发和重定向经过过滤器的过程

    当同时存在多个filter时候:

    web.xml

    <?xml version="1.0" encoding="UTF-8"?>
    <web-app xmlns="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">
    
        <filter>
            <filter-name>three</filter-name>
            <filter-class>filter.FilterThree</filter-class>
        </filter>
        <filter-mapping>
            <filter-name>three</filter-name>
            <url-pattern>/*</url-pattern>
        </filter-mapping>
        <filter>
            <filter-name>one</filter-name>
            <filter-class>filter.FilterOne</filter-class>
        </filter>
        <filter-mapping>
            <filter-name>one</filter-name>
            <url-pattern>/*</url-pattern>
        </filter-mapping>
        <filter>
            <filter-name>two</filter-name>
            <filter-class>filter.FilterTwo</filter-class>
        </filter>
        <filter-mapping>
            <filter-name>two</filter-name>
            <url-pattern>/*</url-pattern>
        </filter-mapping>
    
        <servlet>
            <servlet-name>login</servlet-name>
            <servlet-class>controller.LoginController</servlet-class>
        </servlet>
        <servlet-mapping>
            <servlet-name>login</servlet-name>
            <url-pattern>/login</url-pattern>
        </servlet-mapping>
    </web-app>
    
    过滤器链
    在控制台的输出结果
    在控制台的输出结果

    FilterOne.java

    public class FilterOne extends HttpFilter {
    
        protected void doFilter(HttpServletRequest request, HttpServletResponse response, FilterChain chain) throws IOException, ServletException {
            System.out.println("我是FilterOne放行之前的事情,我执行啦");
            chain.doFilter(request,response);
            System.out.println("我是FilterOne放行之后的事情,啦啦啦");
        }
    }
    

    FilterTwo.java

    public class FilterTwo extends HttpFilter {
    
        protected void doFilter(HttpServletRequest request, HttpServletResponse response, FilterChain chain) throws IOException, ServletException {
            System.out.println("我是FilterTwo放行之前的事情,我执行啦");
            chain.doFilter(request,response);
            System.out.println("我是FilterTwo放行之后的事情,啦啦啦");
        }
    }
    

    FilterThree.java

    public class FilterThree extends HttpFilter {
    
        protected void doFilter(HttpServletRequest request, HttpServletResponse response, FilterChain chain) throws IOException, ServletException {
            System.out.println("我是FilterThree放行之前的事情,我执行啦");
            chain.doFilter(request,response);
            System.out.println("我是FilterThree放行之后的事情,啦啦啦");
        }
    }
    

    如果有多个过滤器,则chain.doFilter(request,response)会调用下一个过滤器,如果没有,则调用目标方法
    过滤器链在执行的时候,他的本质是方法的压栈和弹栈,也就是只有dofilter方法中的chain.doFilter(request,response)执行完之后,才会执行后续的代码。在此期间,过滤器会一个等一个。

    相关文章

      网友评论

          本文标题:filter过滤器基本使用

          本文链接:https://www.haomeiwen.com/subject/oiyayctx.html