zoukankan      html  css  js  c++  java
  • Filter---javaweb的过滤器

    1.Filter是什么?

    • Filter的基本功能是对Servlet容器调用Servlet的过程进行拦截,从而在Servlet进行响应处理的前后实现一些特殊的功能。
    • 在Servlet API中定义了三个接口类来供开发人员编写Filter程序:Filter,FilterChain,FilterConfig。
    • Filter程序是一个实现了Filter接口的java类,与servlet程序相似,它由servlet容器进行调用和执行。
    • Filter要在web.xml文件中进行注册和设置它所能拦截的资源:Filter程序可以拦截Jsp,Servlet,静态图片文件和静态html文件。

    2.如何创建一个Filter?

    ①创建一个Filter类:实现Filter接口(与开发Servlet不同的是,Filter接口并没有相应的实现类可供继承,要开发过滤器,只能直接实现Filter接口。)

    ②在web.xml文件中配置并映射该Filter,其中url-pattern指定该Filter可以拦截哪些资源,即可以通过哪些url访问到该Filter。

      <!-- 注册Filter -->
      <filter>
        <filter-name>filterTest</filter-name>
        <filter-class>com.javaweb.Filter.filterTest</filter-class>
      </filter>
      <!-- 映射Filter -->
      <filter-mapping>
        <filter-name>filterTest</filter-name>
        <url-pattern>/jspTest/includeTest1.jsp</url-pattern>
      </filter-mapping>
    

    3.Filter相关的API

    ①public void init(FilterConfig filterConfig):类似于Servlet的init方法,在创建Filter对象后,立即被调用,且只被调用一次,Filter对象在Servlet容器中加载当前web应用时即被创建,即Filter实例是单例的。

    FilterConfig类似于ServletConfig;可以在web.xml文件中配置当前Filter的初始化参数,配置方式和servlet的配置方式类似。

     <filter>
        <filter-name>filterTest</filter-name>
        <filter-class>com.javaweb.Filter.filterTest</filter-class>
        <init-param>
          <param-name>name</param-name>
          <param-value>root</param-value>
        </init-param>
      </filter>
    

    ②public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)

    真正Filter的逻辑代码需要编写在该方法中,每次拦截都会调用该方法。

    FilterChain:Filter链,多个Filter可以构成一个Filter链。

    doFilter(ServletRequest request, ServletResponse response):把请求传给Filter链的下一个Filter,若当前Filter是Filter链的最后一个Filter,将把请求给目标Servlet或jsp。

    多个Filter拦截的顺序和<filter-mapping>配置的顺序有关,靠前的先被调用。

    ③public void destroy():释放当前Filter所占用的资源的方法。在Filter被销毁之前被调用,且只被调用一次。

    4.示例代码

    实现的功能:

    ①login.jsp请求提交到hello.jsp。该页面中有两个text,分别为username和password。

    ②userNameFilter,passWordFilter拦截login.jsp的请求页面,即hello.jsp。

    ③userNameFilter:若username不等于Tom,则将请求转发给login.jsp,并提示用户名不正确,若等于“Tom”,则把请求转发给下一个Filter(使用FilterChain实现)。

    ④passWordFilter:若password不等于1234,则将请求转发到login.jsp,并提示密码不正确,若等于1234,则把请求转发到目标页面。

    登录页面:login.jsp

     <body>
        <font color="red">${requestScope.message}</font>
        <br><br>
        <form action="http://localhost:8080/MyWebProject/jspTest/hello.jsp" method="post">
          username:<input type="text" name="username"/>
          password:<input type="password" name="password"/>
          <input type="submit" value="Submit" />
        </form>
      </body>
    

    登录成功跳转的页面:hello.jsp

    <body>
        hello,${param.username}
    </body>
    

     用户名不正确拦截的Filter实现:userNameFilter.java

    package com.javaweb.Filter;
    
    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;
    
    public class userNameFilter implements Filter {
        @Override
        public void destroy() {
            
        }
    
        @Override
        public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
                throws IOException, ServletException {
            String initUser=filterconfig.getInitParameter("username");
            String username=request.getParameter("username");
            if(!initUser.equals(username)){
                request.setAttribute("message","用户名不正确");
                //request.getAttribute("message");
                request.getRequestDispatcher("/jspTest/login.jsp").forward(request,response);
                return;
            }
            chain.doFilter(request,response);
    
        }
        private FilterConfig filterconfig;
        @Override
        public void init(FilterConfig filterconfig) throws ServletException {
            this.filterconfig=filterconfig;
    
        }
    
    }
    

    密码不正确拦截的实现功能:passWordFilter.java

    package com.javaweb.Filter;
    
    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;
    
    public class passWordFilter implements Filter {
    
        @Override
        public void destroy() {
            // TODO Auto-generated method stub
    
        }
    
        @Override
        public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
                throws IOException, ServletException {
            String initPassWord=filterconfig.getServletContext().getInitParameter("password");
            String password=request.getParameter("password");
            if(!initPassWord.equals(password)){
                request.setAttribute("message","密码不正确");
                //request.getAttribute("message");
                request.getRequestDispatcher("/jspTest/login.jsp").forward(request,response);
                return;
            }
            chain.doFilter(request,response);
        }
        private FilterConfig filterconfig;
        @Override
        public void init(FilterConfig filterconfig) throws ServletException {
            this.filterconfig=filterconfig;
        }
    }
    

    在web.xml中进行配置:

    <?xml version="1.0" encoding="UTF-8"?>
    <web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://xmlns.jcp.org/xml/ns/javaee" xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd" id="WebApp_ID" version="3.1">
      <context-param>
        <param-name>password</param-name>
        <param-value>1234</param-value>
      </context-param>
        <filter>
        <filter-name>userNameFilter</filter-name>
        <filter-class>com.javaweb.Filter.userNameFilter</filter-class>
        <init-param>
          <param-name>username</param-name>
          <param-value>Tom</param-value>
        </init-param>
      </filter>
      <filter-mapping>
        <filter-name>userNameFilter</filter-name>
        <url-pattern>/jspTest/hello.jsp</url-pattern>
      </filter-mapping>
      <filter>
        <filter-name>passWordFilter</filter-name>
        <filter-class>com.javaweb.Filter.passWordFilter</filter-class>
      </filter>
      <filter-mapping>
        <filter-name>passWordFilter</filter-name>
        <url-pattern>/jspTest/hello.jsp</url-pattern>
      </filter-mapping>
    </web-app>
    

    注意:EL表达式中,param和requestScope的区别。

    在看param和requestScope之前,不妨先了解下request:

    1. request对象通常用来接收客户端提交到服务端的数据,如:在servlet或者action中可以用request.getParameter()的方法获取获取参数内容;

    2. requestScope通常是在servlet或者action的服务端中通过request.setAttribute()方法把数据放到request对象中供客户端获取,然后客户端获取的方法就是requestScope.getAttribute()。

    1. getParameter:

    可以获取URL中传递过来的String参数,如:http://www.baidu.com?username=abc 中的abc;

    提示:对于POST/GET提交的表单,在服务器端我们都可以通过request.getParameter获取表单中的值。

    当我们在进行一个请求重定向(redirect)的时候,我们可以通过request.setParameter传递参数,如果用request.setAttribute在重定向页面是取不到值的(重定向是两个request请求对象)。

    2. getAttribute:                                                                                                                                                                                                 

    获取的是一个对象(Object)。

    当我们进行一个请求转发(forward)的时候,可以使用request.setAttribute传递参数。

    3. requestScope:

    是EL表达式中的一个隐含对象,类似request,如:${requestScope.username} 表示在request域中取得username属性所对应的值,相当于request.getAttribute(“username”)。

    4. param:

    ${param.username} 可理解为:request.getParameter(“username”);

    结论:

    ${param.name} 等价于 request.getParamter("name"),(返回字符串)这两种方法一般用于服务器从页面或者客户端获取的内容,这些内容都是String的。

    ${requestScope.name} 等价于 request.getAttribute("name"),(返回对象)一般是从服务器传递结果到页面,在页面中取出服务器端保存的值!

  • 相关阅读:
    [Luogu P3626] [APIO2009] 会议中心
    杭电 1869 六度分离 (求每两个节点间的距离)
    杭电 1874 畅通工程续 (求某节点到某节点的最短路径)
    最短路径模板
    杭电 2544 最短路径
    POJ 1287 Networking (最小生成树模板题)
    NYOJ 1875 畅通工程再续 (无节点间距离求最小生成树)
    POJ 2485 Highways (求最小生成树中最大的边)
    杭电 1233 还是畅通工程 (最小生成树)
    杭电 1863 畅通工程 (最小生成树)
  • 原文地址:https://www.cnblogs.com/naihuangbao/p/9919261.html
Copyright © 2011-2022 走看看