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
 
 
 
 
 
 
 
 
 
 
 
 
 
 
原文地址:https://www.cnblogs.com/wq3435/p/5194144.html