zoukankan      html  css  js  c++  java
  • Filter

    1.什么是Filter

    ① JavaWeb的一个重要组件,可以对发送到Servlet的请求进行拦截,并对响应也进行拦截。

    ② Filter是实现了Filter接口的Java类

    ③ Filter 需要在web.xml文件中进行配置和映射

    2.如何创建一个Filter,并跑起来

    ①.创建一个Filter类:实现Filter接口:public class MyFilter implements Filter 

    ②.在web.xml文件中配置并映射该Filter

    <!-- 注册Filter -->
        <filter>
            <filter-name>firstFilter</filter-name>
            <filter-class>com.java.testFilter.MyFilter</filter-class>
        </filter>
        <!-- 映射Filter -->
        <filter-mapping>
            <filter-name>firstFilter</filter-name>
            <url-pattern>/test.jsp</url-pattern>
        </filter-mapping>

    3.Filter的API

    Filter接口:

    @Override
    public void destroy() 

    释放当前Filter 所占用的资源的方法.在Filter被销毁之前调用,且只被调用一次.   

    @Override
    public void doFilter(ServletRequest arg0, ServletResponse arg1,
    FilterChain filterChain) throws IOException, ServletException 

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

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

                          filterChain.doFilter(ServletRequest arg0, ServletResponse arg1) 把请求传给Filter链的下一个

            Filter,若当前Filter是Filter链的最后一个Filter,将把请求给到目标Servlet(或JSP)

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

    @Override
    public void init(FilterConfig arg0) throws ServletException {
    System.out.println("init...");
    }

    //类似于Servlet的init方法.在创建Filter对象(Filter对象被web应用加载时立即被调用,
      且只被调用一次.该方法对于当前的Filter进行初始化操作.Filter实例是单例的)

    *FilterConfig 类似于 ServletConfig

    *可以在web.xml文件中配置当前Filter 的初始化参数.配置方式也和Servlet类似.

    <!-- 注册Filter -->
        <filter>
            <filter-name>firstFilter</filter-name>
            <filter-class>com.java.testFilter.MyFilter</filter-class>
            <init-param>
                <param-name>name</param-name>
                <param-value>java</param-value>
            </init-param>
        </filter>

    *与开发Servlet不同的是,Filter 接口并没有相应的实现类可以继承,要开发过滤器只能实现接口 

    同一个web.xml文件中可以为同一个Filter设置多个映射    

    example:

    一个登陆界面

    <font color="red">${message }</font>
    
        <br><br>
        <form action="${pageContext.request.contextPath }/hello.jsp" method="post">
            UserName:<input type="text" name="username" value="${param.username }">
            <br>
            Password :<input type="password" name="password">
            <br>
            <input type="submit" value="submit">
        </form>

    两个过滤器

    package com.java.testFilter;
    
    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;
    
    /**
     * 拦截/hello.jsp,如果username 不是Tom 则转发到login.jsp,否则放行
     */
    public class UserNameFilter implements Filter {
    
        public UserNameFilter() {
        }
    
        public void destroy() {
        }
    
        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.getRequestDispatcher("/login.jsp").forward(request, response);
                return;
            }
            chain.doFilter(request, response);
        }
        
        private FilterConfig filterConfig;
        public void init(FilterConfig fConfig) throws ServletException {
            this.filterConfig = fConfig;
        }
    
    }
    package com.java.testFilter;
    
    import java.io.IOException;
    
    import javax.servlet.Filter;
    import javax.servlet.FilterChain;
    import javax.servlet.FilterConfig;
    import javax.servlet.ServletContext;
    import javax.servlet.ServletException;
    import javax.servlet.ServletRequest;
    import javax.servlet.ServletResponse;
    import javax.servlet.http.HttpServletRequest;
    
    /**
     * 若密码不是1234,则把请求给login.jsp,否则给目标页面
     */
    public class PasswordFilter implements Filter {
    
        public PasswordFilter() {
            // TODO Auto-generated constructor stub
        }
    
        public void destroy() {
            // TODO Auto-generated method stub
        }
    
        public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
            ServletContext servletContext = filterConfig.getServletContext();
            String initPass = servletContext.getInitParameter("password");
            String password = request.getParameter("password");
            if(!initPass.equals(password)){
                request.setAttribute("message", "密码错误!");
                request.getRequestDispatcher("/login.jsp").forward(request, response);
                return;
            }
    
            chain.doFilter(request, response);
        }
    
        /**
         * @see Filter#init(FilterConfig)
         */
        private FilterConfig filterConfig;
        public void init(FilterConfig fConfig) throws ServletException {
            this.filterConfig = fConfig;
        }
    
    }

    web.xml配置

    <context-param>
        <param-name>password</param-name>
        <param-value>1234</param-value>
      </context-param>
    <filter>
        <display-name>UserNameFilter</display-name>
        <filter-name>UserNameFilter</filter-name>
        <filter-class>com.java.testFilter.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>/hello.jsp</url-pattern>
      </filter-mapping>
      <filter>
        <display-name>PasswordFilter</display-name>
        <filter-name>PasswordFilter</filter-name>
        <filter-class>com.java.testFilter.PasswordFilter</filter-class>
      </filter>
      <filter-mapping>
        <filter-name>PasswordFilter</filter-name>
        <url-pattern>/hello.jsp</url-pattern>
      </filter-mapping>
      <servlet>
        <description></description>
        <display-name>TestServlet2</display-name>
        <servlet-name>TestServlet2</servlet-name>
        <servlet-class>com.java.testFilter.TestServlet2</servlet-class>
      </servlet>
      <servlet-mapping>
        <servlet-name>TestServlet2</servlet-name>
        <url-pattern>/TestServlet2</url-pattern>
      </servlet-mapping>

    hello.jsp

    <h4>Hello Page</h4>
        Hello:${param.username }

     写一个HttpFilter类 实现Filter

     1 package com.java.testFilter;
     2 
     3 import java.io.IOException;
     4 
     5 import javax.servlet.Filter;
     6 import javax.servlet.FilterChain;
     7 import javax.servlet.FilterConfig;
     8 import javax.servlet.ServletException;
     9 import javax.servlet.ServletRequest;
    10 import javax.servlet.ServletResponse;
    11 import javax.servlet.http.HttpServletRequest;
    12 import javax.servlet.http.HttpServletResponse;
    13 
    14 public abstract class HttpFilter implements Filter{
    15 
    16     @Override
    17     public void destroy() {
    18     }
    19 
    20     @Override
    21     public void doFilter(ServletRequest arg0, ServletResponse arg1,
    22             FilterChain filterChain) throws IOException, ServletException {
    23         HttpServletRequest request = (HttpServletRequest)arg0;
    24         HttpServletResponse response = (HttpServletResponse)arg1;
    25         doFilter(request,response,filterChain);
    26     }
    27     
    28     public abstract void doFilter(HttpServletRequest request,HttpServletResponse response,
    29             FilterChain filterChain);
    30 
    31     private FilterConfig filterConfig;
    32     @Override
    33     public void init(FilterConfig arg0) throws ServletException {
    34         this.filterConfig = arg0;
    35         init();
    36     }
    37 
    38     protected void init() {
    39     }
    40 }

    下次写Filter可以直接继承HttpFiter

    ** 多个Filter 的代码执行顺序 理解Filter链

    前边的例子 login.jsp --> hello.jsp  通过两个过滤器 UserNameFilter.java , PasswordFilter.java

    在过滤器前后分别加上标记

     1 public class UserNameFilter implements Filter {
     2 
     3     public UserNameFilter() {
     4     }
     5 
     6     public void destroy() {
     7     }
     8 
     9     public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
    10         String initUser = filterConfig.getInitParameter("username");
    11         String username = request.getParameter("username");
    12         if(!initUser.equals(username)){
    13             request.setAttribute("message", "用户名错误!");
    14             request.getRequestDispatcher("/login.jsp").forward(request, response);
    15             return;
    16         }
    17         System.out.println("1...");
    18         chain.doFilter(request, response);
    19         System.out.println("2...");
    20     }
    21     
    22     private FilterConfig filterConfig;
    23     public void init(FilterConfig fConfig) throws ServletException {
    24         this.filterConfig = fConfig;
    25     }
    26 
    27 }
     1 public class PasswordFilter implements Filter {
     2 
     3     public PasswordFilter() {
     4         // TODO Auto-generated constructor stub
     5     }
     6 
     7     public void destroy() {
     8         // TODO Auto-generated method stub
     9     }
    10 
    11     public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
    12         ServletContext servletContext = filterConfig.getServletContext();
    13         String initPass = servletContext.getInitParameter("password");
    14         String password = request.getParameter("password");
    15         if(!initPass.equals(password)){
    16             request.setAttribute("message", "密码错误!");
    17             request.getRequestDispatcher("/login.jsp").forward(request, response);
    18             return;
    19         }
    20         System.out.println("3...");
    21         chain.doFilter(request, response);
    22         System.out.println("4...");
    23     }
    24 
    25     /**
    26      * @see Filter#init(FilterConfig)
    27      */
    28     private FilterConfig filterConfig;
    29     public void init(FilterConfig fConfig) throws ServletException {
    30         this.filterConfig = fConfig;
    31     }
    32 
    33 }

    hello.jsp 页面

     1 <%@ page language="java" contentType="text/html; charset=UTF-8"
     2     pageEncoding="UTF-8"%>
     3 <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
     4 <html>
     5 <head>
     6 <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
     7 <title>Insert title here</title>
     8 </head>
     9 <body>
    10 
    11     <h4>Hello Page</h4>
    12     Hello:${param.username }
    13     <%
    14         System.out.println("5...");
    15     %>
    16 </body>
    17 </html>

    执行后控制台输出为

    1...
    3...
    5...
    4...
    2...

    chain.doFilter()是放行当前过滤器,交给下个过滤器处理

    **<dispatcher>节点  指定过滤器所拦截资源被Servlet容器调用的方式

    可以是 REQUEST(直接请求的方式,包括GET或POST),INCLUDE,FORWARD(请求转发的方式),ERROR

     <filter-mapping>

      <dispatcher>

    </filter-mapping>

     
    一个跳转test.jsp的页面,通过过滤器
     
    <a href="test.jsp">Test</a>
    public class MyFilter implements Filter {
        
        @Override
        public void destroy() {
            System.out.println("destroy...");
        }
    
        @Override
        public void doFilter(ServletRequest arg0, ServletResponse arg1,
                FilterChain arg2) throws IOException, ServletException {
            System.out.println("doFilter...");
        }
    
        @Override
        public void init(FilterConfig arg0) throws ServletException {
            System.out.println("init...");
        }
    
    }
    <filter>
        <filter-name>firstFilter</filter-name>
        <filter-class>com.java.testFilter.MyFilter</filter-class>
        <init-param>
          <param-name>name</param-name>
          <param-value>java</param-value>
        </init-param>
      </filter>
      <filter-mapping>
        <filter-name>firstFilter</filter-name>
        <url-pattern>/test.jsp</url-pattern>
      </filter-mapping>

    在<filter-mapping>中如果不配置<dispatcher>,默认是请求的方式,即get或post的方式,直接请求

    若修改页面为

    index.jsp

    <a href="dispatcher.jsp">Test</a>

    dispatcher.jsp

    <jsp:forward page="test.jsp"></jsp:forward>

    则拦截器会不起作用,如果需要拦截转发的方式,需要配置

     
    <filter-mapping>
        <filter-name>firstFilter</filter-name>
        <url-pattern>/test.jsp</url-pattern>
        <dispatcher>FORWARD</dispatcher>
      </filter-mapping>

    配置<dispatcher>FORWARD</dispatcher>后,默认的请求方式会无法拦截,若需同时起作用需啊哟两个同时配置

    <filter-mapping>
        <filter-name>firstFilter</filter-name>
        <url-pattern>/test.jsp</url-pattern>
        <dispatcher>FORWARD</dispatcher>
        <dispatcher>REQUEST</dispatcher>
      </filter-mapping>

    配置<dispatcher>INCLUDE</dispatcher>道理相同

    <dispatcher>ERROR</dispatcher>:

     如果目标资源是通过生命式异常处理机制调用时,那么该过滤器将被调用.除此之外过滤器不会被调用
     
     如果页面报错,有两种方式跳转到 错误页面
    1.<%@ page errorPage="test.jsp" %>
    指定页面出错后去往test.jsp页面,这种方式不会被默认的过滤器拦截,会被配置了
    <dispatcher>FORWARD</dispatcher>拦截到.
     
    2.在 web.xml中配置了
    <error-page>
          <exception-type>java.lang.ArithmeticException</exception-type>
          <location>/test.jsp</location>
      </error-page>

    此时需要在过滤器中配置

    <filter-mapping>
        <filter-name>firstFilter</filter-name>
        <url-pattern>/test.jsp</url-pattern>
        <dispatcher>FORWARD</dispatcher>
        <dispatcher>REQUEST</dispatcher>
        <dispatcher>ERROR</dispatcher>
      </filter-mapping>

    才能正确跳转到定义的错误页面

    应用1:禁用浏览器缓存的过滤器

    有3个HTTP响应头字段都可以禁止浏览器缓存当前页面,他们在Servlet中的示例代码如下:

    response.setDateHeader("Expires", -1);
    response.setHeader("Cache-Control", "no-cache");
    response.setHeader("Pragma", "no-cache");

    并不是所有浏览器都能完全支持上面的三个响应头,因此最好是同时使用上面的三个响应头

    cache目录中有

    a.html  ,  b.html    ,  a.jpg,   b.jpg

    a.html

    <a href="b.html">To BBB Page</a>
    <img alt="" src="b.jpg">

    b.html

    <a href="a.html">To AAA Page</a>

    在ie中运行a.html后,修改src="a.jpg",不刷新浏览器再次点击跳转链接时,由于缓存原因,显示的图片

    没有刷新过来,在配置 禁用浏览器缓存后可以 可以禁止缓存

    public class NoCacheFilter extends HttpFilter {
    
        @Override
        public void doFilter(HttpServletRequest request,
                HttpServletResponse response, FilterChain filterChain) throws IOException, ServletException {
            response.setDateHeader("Expires", -1);
            response.setHeader("Cache-Control", "no-cache");
            response.setHeader("Pragma", "no-cache");
            
            filterChain.doFilter(request, response);
        }
    }

    其中HttpFilter是自己实现Filter的一个抽象类,为了简便直接使用,在之前已经说过。

    <filter>
          <filter-name>noCacheFilter</filter-name>
          <filter-class>com.java.testNoCache.NoCacheFilter</filter-class>
      </filter>
      <filter-mapping>
          <filter-name>noCacheFilter</filter-name>
          <url-pattern>/cache/*</url-pattern>
      </filter-mapping>

    典型应用2:自己写一个字符编码过滤器(虽然Spring已经提供了),为了更好的理解

    两个jsp页面跳转时,如果没有字符编码的处理,传递中文会出现乱码问题

    login.jsp

    <form action="hello.jsp" method="post">
            Hello:<input type="text" name="username">
            <input type="submit" value="Submit">
        </form>

    hello.jsp

    Hello:${param.username }

    输入中文时会出现乱码:

    Hello:过滤器

    ------------------------------

    第1种做法:之前的做法是在目标页面写一个字符编码处理

    <%
    request.setCharacterEncoding("UTF-8");
    %>

    Hello:${param.username }

    如果是通过Servlet处理,则这句可以再Servlet里写,若一个工程有100个页面,则这种办法行不通

    第二种做法通过过滤器处理:

    package com.java.encoding;
    
    import java.io.IOException;
    
    import javax.servlet.FilterChain;
    import javax.servlet.ServletException;
    import javax.servlet.http.HttpServletRequest;
    import javax.servlet.http.HttpServletResponse;
    
    import com.java.testFilter.HttpFilter;
    
    public class EncodingFilter extends HttpFilter {
    
        private String encoding;
        
        @Override
        protected void init() {
            encoding = getFilterConfig().getServletContext().getInitParameter("encoding");
        }
        
        @Override
        public void doFilter(HttpServletRequest request,
                HttpServletResponse response, FilterChain filterChain)
                throws IOException, ServletException {
            request.setCharacterEncoding(encoding);
            filterChain.doFilter(request, response);
        }
    
    }

    这里依旧使用之前写的HttpFilter,并且这里从web.xml中获取web应用的初始化参数

    web.xml中过滤器的配置

    <context-param>
          <param-name>encoding</param-name>
          <param-value>UTF-8</param-value>
      </context-param>
      
      <filter>
          <filter-name>encodingFilter</filter-name>
          <filter-class>com.java.encoding.EncodingFilter</filter-class>
      </filter>
      <filter-mapping>
          <filter-name>encodingFilter</filter-name>
          <url-pattern>/encoding/*</url-pattern>
      </filter-mapping>

    如果使用Spring,可以直接使用Spring提供的Filter

    典型应用3:检查用户是否登录的过滤器

    需求:系统中的某些页面登录后才能访问,用户请求这些页面时要检查session中有无该用户信息,但在所有的页面上添加session判断太麻烦.

    解决方案:写一个检测用户是否登录的过滤器,如果用户未登录,则重定向到指定的登录页面

    要求:需检查在Session中保存的关键字、如果用于未登录需重定向到指定的页面、不做检查的URL列表(URL不包括ContextPath)都要采取可配置的方式;

    有些页面只用用户登录后才能访问,有些页面用户没有登录不能访问

    不用过滤器最直接的做法:

    不需要登录可以访问的页面

    a.jsp

    <h4>AAA Page</h4>
        <br>
        
        <a href="list.jsp">List Page</a>

    需要登录才能访问的页面:(不使用过滤器,所有的目标页面都要做出session的判断)

    b.jsp

    <%
            //检查用户是否登录,若没有登录则重定向到login.jsp
            Object user = session.getAttribute("user");
            if(null == user){
                response.sendRedirect("login.jsp");
            }
        %>
        <h4>BBB Page</h4>
        <br>
        
        <a href="list.jsp">List Page</a>

    登录页面(写的简单) login.jsp

    <form action="doLogin.jsp" method="post">
            username:<input type="text" name="username">
            <input type="submit" value="submit">
        </form>

    需要将用户信息写入到sesison的处理,简单用jsp代替servlet,  doLogin.jsp

    <%
            //1.获取用户登录信息
            String username = request.getParameter("username");
            //2.将用户登录信息写入session
            session.setAttribute("user", username);
            //3.重定向到list.jsp
            response.sendRedirect("list.jsp");
        %>

    用户访问的首页  list.jsp

    <a href="a.jsp">AAA</a>
        <br><br>
        
        <a href="b.jsp">BBB</a>
        <br><br>
        
        <a href="c.jsp">CCC</a>
        <br><br>
        
        <a href="d.jsp">DDD</a>
        <br><br>
        
        <a href="e.jsp">EEE</a>
        <br><br>

    使用过滤器

    修改b.jsp

    <%--
            //检查用户是否登录,若没有登录则重定向到login.jsp
            Object user = session.getAttribute("user");
            if(null == user){
                response.sendRedirect("login.jsp");
            }
        --%>
        <h4>BBB Page</h4>
        <br>
        
        <a href="list.jsp">List Page</a>

    LoginFilter.java

    package com.java.login;
    
    import java.io.IOException;
    import java.util.Arrays;
    import java.util.List;
    
    import javax.servlet.FilterChain;
    import javax.servlet.ServletContext;
    import javax.servlet.ServletException;
    import javax.servlet.http.HttpServletRequest;
    import javax.servlet.http.HttpServletResponse;
    
    import com.java.testFilter.HttpFilter;
    
    public class LoginFilter extends HttpFilter {
    
        private String sessionKey;
        private String redirectURL;
        private String uncheckURLs;
        
        @Override
        protected void init() {
            ServletContext servletContext = getFilterConfig().getServletContext();
            sessionKey = servletContext.getInitParameter("sessionKey");
            redirectURL = servletContext.getInitParameter("redirectURL");
            uncheckURLs = servletContext.getInitParameter("uncheckURLs");
        }
        
        @Override
        public void doFilter(HttpServletRequest request,
                HttpServletResponse response, FilterChain filterChain)
                throws IOException, ServletException {
            String requestURL = request.getRequestURL().toString();
            String requestURI = request.getRequestURI();
            String servletPath1 = request.getServletPath();
            System.out.println(requestURL);
            System.out.println(requestURI);
            System.out.println(servletPath1);
            /*http://localhost:8080/testFilter/login/a.jsp
            /testFilter/login/a.jsp
            /login/a.jsp*/
            
            //1.获取请求的ServletPath
            String servletPath = request.getServletPath();
            
            //2.判断uncheckURLs里是否包含ServletPath,若包含,则直接放行,方法结束
            List<String> urls = Arrays.asList(uncheckURLs.split(","));
            if(urls.contains(servletPath)){
                filterChain.doFilter(request, response);
                return;
            }
            
            //3.从session中获取sessionKey对应的值,若不存在,则重定向到redirectURL
            Object user = request.getSession().getAttribute(sessionKey);
            if(null == user){
                response.sendRedirect(request.getContextPath()+redirectURL);
                return;
            }
            //4.若存在,放行
            filterChain.doFilter(request, response);
    
        }
    
    }

    web.xml

    <!-- 将参数变为可配置的 -->
      <!-- 存储session的关键字 -->
      <context-param>
          <param-name>sessionKey</param-name>
          <param-value>SESSIONKEY</param-value>
      </context-param>
      <!-- 如果没有登录,则重定向到的页面 -->
      <context-param>
          <param-name>redirectURL</param-name>
          <param-value>/login/login.jsp</param-value>
      </context-param>
      <!-- 不需要检查的url-->
      <context-param>
          <param-name>uncheckURLs</param-name>
          <param-value>/login/a.jsp,/login/list.jsp,/login/login.jsp,/login/doLogin.jsp</param-value>
      </context-param>
      
      <!-- 配置检查用户登录的过滤器 -->
      <filter>
          <filter-name>loginFilter</filter-name>
          <filter-class>com.java.login.LoginFilter</filter-class>
      </filter>
      <filter-mapping>
          <filter-name>loginFilter</filter-name>
          <url-pattern>/login/*</url-pattern>
      </filter-mapping>

    修改doLogin.jsp

    <%
            //1.获取用户登录信息
            String username = request.getParameter("username");
            
            //3.若登录信息完整重定向到list.jsp
            if(null != username && !username.trim().equals("")){
                //2.将用户登录信息写入session
                session.setAttribute(application.getInitParameter("sessionKey"), username);
                response.sendRedirect("list.jsp");
            }else{
                response.sendRedirect("login.jsp");
            }
            
        %>

    通过测试

     
    典型应用4:权限管理及过滤
    1.权限管理:
    权限管理的页面:authority-manager.jsp
     
     
    输入用户名后,提交 即可查看AAA用户的权限
     
    authority-manager.jsp
    <%@ page language="java" contentType="text/html; charset=UTF-8"
        pageEncoding="UTF-8"%>
    <%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
    <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
    <html>
    <head>
    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
    <title>Insert title here</title>
    </head>
    <body>
    
        <center>
            <form action="authorityServlet?method=getAuthority" method="post">
                name:<input type="text" name="userName"/>
                <input type="submit" value="Submit"/>
            </form>
        </center>
        <br><br>
        
        <center>
        <c:if test="${requestScope.user.userName != null}">
        
        ${requestScope.user.userName }的权限是:
        
        <br><br>
            <form action="authorityServlet?method=updateAuthority" method="post">
                <input type="hidden" name="userName" value="${requestScope.user.userName }"/>
                <c:forEach items="${authorities}" var="auth">
                    <c:set var="flag" value="false"></c:set>
                    <c:forEach items="${user.authorities }" var="au">
                        <c:if test="${au.url == auth.url  }">
                            <c:set var="flag" value="true"></c:set>
                        </c:if>
                    </c:forEach>
                    <c:if test="${flag == true }">
                        <input type="checkbox" name="authorities" value="${auth.url }" checked="checked"/>${auth.authorityName }<br><br>
                    </c:if>
                    <c:if test="${flag == false }">
                        <input type="checkbox" name="authorities" value="${auth.url }"/>${auth.authorityName }<br><br>
                    </c:if>
                </c:forEach>
                
                <input type="submit" value="Update"/>
            </form>
        </c:if>
        </center>
        
    
    </body>
    </html>

    AuthorityServlet.java

    package com.java.authority.servlet;
    
    import java.io.IOException;
    import java.lang.reflect.Method;
    import java.util.List;
    
    import javax.servlet.ServletException;
    import javax.servlet.http.HttpServlet;
    import javax.servlet.http.HttpServletRequest;
    import javax.servlet.http.HttpServletResponse;
    
    import com.java.authority.dao.AuthorityDao;
    import com.java.authority.entity.Authority;
    import com.java.authority.entity.User;
    
    
    public class AuthorityServlet extends HttpServlet {
        private static final long serialVersionUID = 1L;
        
        AuthorityDao authorityDao = new AuthorityDao();
    
        protected void doPost(HttpServletRequest request,
                HttpServletResponse response) throws ServletException, IOException {
            String methodName = request.getParameter("method");
            
            try {
                Method method = getClass().getMethod(methodName,
                        HttpServletRequest.class,HttpServletResponse.class);
                method.invoke(this, request,response);
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
        
        public void getAuthority(HttpServletRequest request,
                HttpServletResponse response) throws ServletException, IOException {
            String userName = request.getParameter("userName");
            User user = authorityDao.getUser(userName);
            request.setAttribute("user", user);
            
            List<Authority> authorities = authorityDao.getAuthority();
            request.setAttribute("authorities", authorities);
            
            request.getRequestDispatcher("/authority/authority-manager.jsp").forward(request, response);
        }
        
        public void updateAuthority(HttpServletRequest request,
                HttpServletResponse response) throws IOException{
            String userName = request.getParameter("userName");
            String [] urls = request.getParameterValues("authorities");
            List<Authority> auths = authorityDao.getAuthorities(urls);
            authorityDao.update(userName, auths);
            response.sendRedirect(request.getContextPath()+"/authority/authority-manager.jsp");
        }
    
    }
    这里的两个entity
    User.java
    package com.java.authority.entity;
    
    import java.util.List;
    
    public class User {
    
        private String userName;
        private List<Authority> authorities;
    
        public String getUserName() {
            return userName;
        }
    
        public void setUserName(String userName) {
            this.userName = userName;
        }
    
        public List<Authority> getAuthorities() {
            return authorities;
        }
    
        public void setAuthorities(List<Authority> authorities) {
            this.authorities = authorities;
        }
    
        public User(String userName, List<Authority> authorities) {
            super();
            this.userName = userName;
            this.authorities = authorities;
        }
    
        public User() {
            super();
        }
    
    }

    Authority.java

    package com.java.authority.entity;
    
    public class Authority {
    
        private String authorityName;
        private String url;
    
        public String getAuthorityName() {
            return authorityName;
        }
    
        public void setAuthorityName(String authorityName) {
            this.authorityName = authorityName;
        }
    
        public String getUrl() {
            return url;
        }
    
        public void setUrl(String url) {
            this.url = url;
        }
    
        public Authority(String authorityName, String url) {
            super();
            this.authorityName = authorityName;
            this.url = url;
        }
    
        public Authority() {
            super();
        }
    
        @Override
        public int hashCode() {
            final int prime = 31;
            int result = 1;
            result = prime * result + ((url == null) ? 0 : url.hashCode());
            return result;
        }
    
        @Override
        public boolean equals(Object obj) {
            if (this == obj)
                return true;
            if (obj == null)
                return false;
            if (getClass() != obj.getClass())
                return false;
            Authority other = (Authority) obj;
            if (url == null) {
                if (other.url != null)
                    return false;
            } else if (!url.equals(other.url))
                return false;
            return true;
        }
        
        
    
    }
    这里不连接数据库,数据初始化在AuthorityDao.java里
    AuthorityDao.java
    package com.java.authority.dao;
    
    import java.util.ArrayList;
    import java.util.HashMap;
    import java.util.List;
    import java.util.Map;
    
    import com.java.authority.entity.Authority;
    import com.java.authority.entity.User;
    
    public class AuthorityDao {
        
        private static Map<String,User> users;
        private static List<Authority> authorities;
        
        static{
            users = new HashMap<>();
            authorities = new ArrayList<>();
            authorities.add(new Authority("article-1", "/authority/article-1.jsp"));
            authorities.add(new Authority("article-2", "/authority/article-2.jsp"));
            authorities.add(new Authority("article-3", "/authority/article-3.jsp"));
            authorities.add(new Authority("article-4", "/authority/article-4.jsp"));
            
            users.put("AAA", new User("AAA", authorities.subList(0, 2)));
            users.put("BBB", new User("BBB", authorities.subList(2, 4)));
        }
        
        public List<Authority> getAuthority(){
            return authorities;
        }
        
        public User getUser(String userName){
            return users.get(userName);
        }
        
        public void update(String userName,List<Authority> authorities){
            users.get(userName).setAuthorities(authorities);
        }
    
        public List<Authority> getAuthorities(String[] urls) {
            List<Authority> authorities2 = new ArrayList<>();
            for(Authority authority : authorities){
                for(String url:urls){
                    if(authority.getUrl().equals(url)){
                        authorities2.add(authority);
                    }
                }
            }
            return authorities2;
        }
    
    }

    servlet 的配置

     <servlet>
        <description></description>
        <display-name>AuthorityServlet</display-name>
        <servlet-name>AuthorityServlet</servlet-name>
        <servlet-class>com.java.authority.servlet.AuthorityServlet</servlet-class>
      </servlet>
      <servlet-mapping>
        <servlet-name>AuthorityServlet</servlet-name>
        <url-pattern>/authority/authorityServlet</url-pattern>
      </servlet-mapping>

    以上是权限管理,以下是权限的过滤结合权限管理

    文件结构目录:

    入口login.jsp
     
    登录页面直接到LoginServlet.java
    package com.java.authority.servlet;
    
    import java.io.IOException;
    import java.lang.reflect.Method;
    
    import javax.servlet.ServletException;
    import javax.servlet.http.HttpServlet;
    import javax.servlet.http.HttpServletRequest;
    import javax.servlet.http.HttpServletResponse;
    
    import com.java.authority.dao.AuthorityDao;
    import com.java.authority.entity.User;
    
    
    public class LoginServlet extends HttpServlet {
        private static final long serialVersionUID = 1L;
    
        private AuthorityDao authorityDao = new AuthorityDao();
        
        protected void doGet(HttpServletRequest request,
                HttpServletResponse response) throws ServletException, IOException {
            doPost(request, response);
        }
    
        protected void doPost(HttpServletRequest request,
                HttpServletResponse response) throws ServletException, IOException {
            String methodName = request.getParameter("method");
            try {
                Method method = getClass().getMethod(methodName, 
                        HttpServletRequest.class,HttpServletResponse.class);
                method.invoke(this,request, response);
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
        
        public void login(HttpServletRequest request,
                HttpServletResponse response) throws ServletException, IOException {
            String username = request.getParameter("username");
            User user = authorityDao.getUser(username);
            request.getSession().setAttribute("user", user);
            //重定向到articles.jsp
            response.sendRedirect(request.getContextPath()+"/authority/articles.jsp");
            
        }
        public void logout(HttpServletRequest request,
                HttpServletResponse response) throws ServletException, IOException {
            request.getSession().invalidate();
            response.sendRedirect(request.getContextPath()+"/authority/login.jsp");
        }
    
    }

    在Servlet之前会有一个过滤器

    AuthorityFilter.java

    package com.java.authority;
    
    import java.io.IOException;
    import java.util.Arrays;
    import java.util.List;
    
    import javax.servlet.FilterChain;
    import javax.servlet.ServletException;
    import javax.servlet.http.HttpServletRequest;
    import javax.servlet.http.HttpServletResponse;
    
    import com.java.authority.entity.Authority;
    import com.java.authority.entity.User;
    import com.java.testFilter.HttpFilter;
    
    public class AuthorityFilter extends HttpFilter {
    
        @Override
        public void doFilter(HttpServletRequest request,
                HttpServletResponse response, FilterChain filterChain)
                throws IOException, ServletException {
    
            String servletPath = request.getServletPath();
            List<String> uncheckURL = Arrays.asList("/authority/login.jsp", "/authority/logout.jsp",
                    "/authority/articles.jsp", "/authority/authority-manager.jsp", "/authority/403.jsp");
            // 检查不过滤的页面
            if (uncheckURL.contains(servletPath)) {
                filterChain.doFilter(request, response);
                return;
            }
    
            User user = (User) request.getSession().getAttribute("user");
            //若用户没有登录,重定向到login.jsp
            if (user == null) {
                response.sendRedirect(request.getContextPath()
                        + "/authority/login.jsp");
                return;
            }
            //获取用户拥有的 权限
            List<Authority> authorities = user.getAuthorities();
            //检查用户是否有请求servletPath的权限,遍历以外的方法
            Authority authority = new Authority(null, servletPath);
            if(authorities.contains(authority)){
                filterChain.doFilter(request, response);
                return;
            }
            //没有权限
            response.sendRedirect(request.getContextPath()+"/authority/403.jsp");
            return;
    
        }
    
    }

    web.xml配置

    <filter>
        <display-name>AuthorityFilter</display-name>
        <filter-name>AuthorityFilter</filter-name>
        <filter-class>com.java.authority.AuthorityFilter</filter-class>
      </filter>
      <filter-mapping>
        <filter-name>AuthorityFilter</filter-name>
        <url-pattern>*.jsp</url-pattern>
      </filter-mapping>
     
    登录后显示所有的链接和页面
    有的页面AAA用户可以访问,有的没有权限访问
     
    ariticle1-ariticle4.jsp页面类似
    <%@ page language="java" contentType="text/html; charset=UTF-8"
        pageEncoding="UTF-8"%>
    <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
    <html>
    <head>
    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
    <title>Insert title here</title>
    </head>
    <body>
    
        <h4>Ariticle-1 Page</h4>
        <br>
        <a href="articles.jsp">返回</a>
    
    </body>
    </html>

    403.jsp页面

    <%@ page language="java" contentType="text/html; charset=UTF-8"
        pageEncoding="UTF-8"%>
    <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
    <html>
    <head>
    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
    <title>Insert title here</title>
    </head>
    <body>
    
        <h4>您没有权限访问,</h4><a href="${pageContext.request.contextPath }/authority/403.jsp">返回</a>
    
    </body>
    </html>

    典型应用5:论坛中关键字的拦截及过滤(例如 fuck... 等)

    可以使用 过滤器+HttpServletRequestWrapper
     
     
     
     
     
     
     
     
     
     
     
     
     
     
  • 相关阅读:
    【极角排序、扫描线】UVa 1606
    【计算几何】是时候知道这些函数了
    【技巧性(+递归运用)】UVa 1596
    【策略】UVa 11389
    【策略】UVa 1344
    夏季吃西瓜,会勤上厕所,会导致体内缺水,导致便秘,,会长豆豆
    Alt+Shift+R组合键,用来在一个java文件中批量的重命名变量。
    Pycharm-professional-2017.2.3破解安装
    通过反编译深入理解Java String及intern
    转:MyEclipse安装Eclipse Memory Analyzer插件,并进行错误文件分析流程
  • 原文地址:https://www.cnblogs.com/wq3435/p/5194144.html
Copyright © 2011-2022 走看看