zoukankan      html  css  js  c++  java
  • 1.7(学习笔记)过滤器(Fliter)

    一、过滤器(Fliter)简介

      过滤器是位于客户端与服务器之间的滤网,在访问资源时会经过一系列的过滤器,

      满足条件则放行,不满足条件的将其拦截。

      

      过滤器可以看做是一个特殊的Servlet,设置了过滤器及其过滤范围后,

      访问处于过滤器过滤范围的资源,会先经过滤器,如果满足过滤条件就会被过滤器放行。

      一系列过滤器的组合称为过滤链,但某一资源满处于多个过滤器的过滤范围时,

      会执行完一个过滤器后进入下一个过滤器,执行顺序和web.xml中的过滤器的配置顺序有关。

      

      过滤器不仅有过滤作用,在过滤过程中可以对调用的请求进行一些操作,

      也可以调用完资源后的响应进行一些操作。

      

    二、过滤器实例

      2.1编码过滤

      不适用过滤器进行编码过滤的话,每一个页面都要设置编码格式,这样显然是不方便的。

      使用过滤器和创建Servlet差不多。

      首先我们创建一个Class,然后继承Fliter接口。

      实现里面的init,doFilter,destroy方法,其中init,destroy如无特殊需要可不进行添加或修改。

      主要是里面的deFilter方法,当request或response进入过滤器时,主要是指向doFilter中的内容。

      doFilter方法中携带有一个参数FilterChain chain,FiterChain中还有一个比较重要的方法:

      void javax.servlet.FilterChain.doFilter(ServletRequest request, ServletResponse response)
      //调用过滤链中下一个过滤器,如果后续没有过滤器则访问对应资源

      一般在Filter接口下doFilter()方法里面的FilterChain.doFilter()方法前面为请求过滤,后面为响应过滤。

      

    import java.io.IOException;
    
    import javax.servlet.Filter;
    import javax.servlet.FilterChain;
    import javax.servlet.FilterConfig;
    import javax.servlet.ServletException;
    import javax.servlet.ServletRequest;
    import javax.servlet.ServletResponse;
    import javax.servlet.http.HttpServletRequest;
    import javax.servlet.http.HttpServletResponse;
    
    public class SimpleFilter implements Filter{
    
        @Override
        public void init(FilterConfig filterConfig) throws ServletException {
            // TODO Auto-generated method stub
        }
    
        @Override
        public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
                throws IOException, ServletException {
            //请求过滤,
            request.setCharacterEncoding("utf-8");
         response.setCharacterEncoding("utf-8");  System.out.println(
    "Request"); //调用过滤链中后一过滤器,如果后续没有过滤器则访问对应资源。(放行) chain.doFilter(request, response); //响应过滤 System.out.println("Response"); } @Override public void destroy() { // TODO Auto-generated method stub } }

    这里的过滤器并没有对资源进行过滤,而只是对请求和响应进行了编码格式的改变防止乱码问题。

    这里也可以设置满足一定的条件才放行(调用chain.doFilter(.....))。

    设置完过滤器后,我们还需要在web.xml中配置过滤器。

    配置方法和Servlet大同小异,只是在url地址这一块和Servlet的含义不一样。

    <filter>
          <filter-name> CharacterFilter</filter-name>
          <filter-class>com.filter.SimpleFilter</filter-class>
      </filter>
      <filter-mapping>
          <filter-name> CharacterFilter</filter-name>
          <url-pattern>/*</url-pattern>
      </filter-mapping>

    主要是url-pattern中,这里面配置的是过滤器过滤的范围,‘/*’就代表过滤器过滤范围为当前项目下所有资源。

    即当前项目下所有资源的reques和respons都要设置为“utf-8”编码格式。

    过滤器也可以过滤某一类文件,例如所有的jsp文件,则可以这样写“*.jsp”

    这样就代表过滤器范围为该资源下所有.jps文件。

    当然也可以指定过滤范围为当前项目下某一部分资源,

    例如“/test/*”代表过滤器过滤范围为test文件夹下所有资源。

    一个过滤器在web.xml中可以设置多个映射(过滤范围),

    这样就可以根据自己要求灵活调整过滤范围。 

    过滤器的执行顺序是依照web.xml中的配置来的,先经过配置在前面的过滤器,后面的依次通过。

    LoginServlet

    import java.io.IOException;
    import java.io.PrintWriter;
    
    import javax.servlet.ServletException;
    import javax.servlet.annotation.WebServlet;
    import javax.servlet.http.HttpServlet;
    import javax.servlet.http.HttpServletRequest;
    import javax.servlet.http.HttpServletResponse;
    import com.util.HttpPageUtil;;
    
    public class LoginServlet extends HttpServlet {
        protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
            PrintWriter out = response.getWriter();
            String username = request.getParameter("username");
         //输出HTML头部代码 HttpPageUtil.printHtmlPage(out,
    true); out.println("<h2>" + username + "李四" + "</h2>");
         //输出HTML尾部代码 HttpPageUtil.printHtmlPage(out,
    false); System.out.println("Servlet"); } /** * @see HttpServlet#doPost(HttpServletRequest request, HttpServletResponse response) */ protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { // TODO Auto-generated method stub doGet(request, response); } }

    HTTPUtil

    import java.io.PrintWriter;
    
    public class HttpPageUtil {
        //打印HTML页面,head为True打印HTML头部代码,为false打印尾部HTML代码
        public static void printHtmlPage(PrintWriter out, boolean head) {
            if(head) {
                out.println("<!DOCTYPE html>
    " + 
                        "<html>
    " + 
                        "<head>
    " + 
                        "<meta charset="UTF-8">
    " + 
                        "<title>Insert title here</title>
    " + 
                        "</head>
    " + 
                        "<body>");
            }else {
                out.println("</body>
    " + 
                        "</html>");
            }
        }
    }

    login.jsp

    <%@ page language="java" contentType="text/html; charset=UTF-8"
        pageEncoding="UTF-8"%>
    <!DOCTYPE html>
    <html>
    <head>
    <meta charset="UTF-8">
    <title>Login</title>
    </head>
    <body>
        <form name = f1 action ="Filter/Login" method = "post">
            username:<input type = "text" name = "username" value = "${un}"></input><br>
            password:<input type = "password" name = "password" value = "${pw}"></input><br>
            <input type = "submit" value = "登录">
        </form>
    </body>
    </html>

     

     我们来看下控制台输出的信息。

    Request
    Servlet
    Response

    我们来分析下整个流程:

    首先进入过滤器,执行编码转换,然后输出“Request”,接着放行

    执行chain.doFilter();然后进入LoginServlet中输出“Servlet”,

    然后再进入过滤器中输出"Response"。

    可以看出过滤器的执行流程,就是最开始画的图的流程,

    主要注意一点chain.doFilter()前面的是对应客户端到服务器这个方向的,

    后面的是chain.doFilter()后面的是服务器到客户端这个方向的。

      2.2登录验证。

      在WebContext目录下新建一个文件夹Page,将要访问的资源文件都放在里面。

      设置一个过滤器,过滤范围为Page文件下所有文件。如果登录则可正常访问

      资源,如果没有登录则跳转到登录界面,并且提示登录。

      

      

    LgoinFilter

    import java.io.IOException;
    
    import javax.servlet.Filter;
    import javax.servlet.FilterChain;
    import javax.servlet.FilterConfig;
    import javax.servlet.ServletException;
    import javax.servlet.ServletRequest;
    import javax.servlet.ServletResponse;
    import javax.servlet.http.HttpServletRequest;
    import javax.servlet.http.HttpServletResponse;
    import javax.servlet.http.HttpSession;
    
    public class LoginFilter implements Filter{
    
        @Override
        public void init(FilterConfig filterConfig) throws ServletException {
            // TODO Auto-generated method stub
            
        }
    
        @Override
        public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
                throws IOException, ServletException {
            // TODO Auto-generated method stub
            HttpServletRequest req = (HttpServletRequest)request;
            HttpSession session = req.getSession();
            String username = (String)session.getAttribute("username");
            //如果Session中已有username则认为已登录,(sesson在LgoinServlet中设置)
            if(username != null && ! "".equals(username)) {
                System.out.println("LgoinFilterRequest");
                //登录则放行
                chain.doFilter(request, response);
                System.out.println("LgoinFilterResponse");
            }else {//反之则重定向到登录页面
                request.setAttribute("error", "未登录,无法访问资源!");
                //加 / 代表绝对 前缀为localhost:8080
                request.getRequestDispatcher("/login.jsp").forward(request, response);
            }
        }
    
        @Override
        public void destroy() {
            // TODO Auto-generated method stub
        }
    }

    LoginServlet:

    import java.io.IOException;
    import java.io.PrintWriter;
    
    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 com.util.HttpPageUtil;;
    public class LoginServlet extends HttpServlet {
        protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
            PrintWriter out = response.getWriter();
            String username = request.getParameter("username");
            HttpSession session = request.getSession();
            session.setAttribute("username", username);
            HttpPageUtil.printHtmlPage(out, true);
            out.println("<h2>" + username + "</h2>");
            HttpPageUtil.printHtmlPage(out, false);
            System.out.println("Servlet");
        }
    
        
    /**
         * @see HttpServlet#doPost(HttpServletRequest request, HttpServletResponse response)
         */
        protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
            // TODO Auto-generated method stub
            doGet(request, response);
        }
        
    }

    login.jsp

    <%@ page language="java" contentType="text/html; charset=UTF-8"
        pageEncoding="UTF-8"%>
    <!DOCTYPE html>
    <html>
    <head>
    <meta charset="UTF-8">
    <title>Login</title>
    </head>
    <body>
        ${error}
      
        <form name = f1 action ="/TestServlet/Filter/Login" method = "post">
            username:<input type = "text" name = "username" value = "${un}"></input><br>
            password:<input type = "password" name = "password" value = "${pw}"></input><br>
        
            <input type = "submit" value = "登录">
        </form>
    </body>
    </html>

    可以看到没有登录时无法访问资源,登录后可以访问资源。

    登录过程中在LoginServlet中创建了session并将用户名放入Session,

    访问Page下的资源时过滤器会判断session中是否有用户名,

    有用户名则可以访问资源,反之则不能。 

    我们来看下能访问资源时控制台输出的信息:(session已被创建)

    Request
    LgoinFilterRequest
    LgoinFilterResponse
    Response

    客户端访问服务器资源,首先request会经过第一个字符编码过滤器,执行编码格式的转换。

    打印出Request,然后放行到LoginFilter过滤器,LoginFilter检测到用户已登录会放行。

    由于后续没有过滤器,所以到达访问资源。到达资源后response首先通过LoginFilter

    中chain.doFilter()方法后面的语句,打印出LoginFilterResponse,然后执行字符编码过滤器

    后面的Response。

    执行顺序就是按下图执行的。

     

    参考资料:

    https://www.cnblogs.com/xdp-gacl/p/3948353.html

    https://www.cnblogs.com/ygj0930/p/6374212.html

      

  • 相关阅读:
    Python学习---IO的异步[tornado模块]
    Python学习---IO的异步[twisted模块]
    Python学习---IO的异步[gevent+Grequests模块]
    Python学习---IO的异步[asyncio +aiohttp模块]
    Python学习---IO的异步[asyncio模块(no-http)]
    Python学习---Python的异步IO[all]
    Python学习---爬虫学习[scrapy框架初识]
    Python学习---Django关于POST的请求解析源码分析
    Python学习---爬虫学习[requests模块]180411
    Python实例---CRM管理系统分析180331
  • 原文地址:https://www.cnblogs.com/huang-changfan/p/10317281.html
Copyright © 2011-2022 走看看