JavaWeb学习笔记(一):Filter过滤器的理解、实现与实际权限操控应用

1. Filter的作用

过滤器是JavaWeb三大组件之一,它与Servlet很相似,但是过滤器是用来拦截请求的,而不是处理请求的,常用来实现权限管理的功能

当用户请求某个Servlet时,会先执行部署在这个请求上的Filter,如果Filter“放行”,那么会继承执行用户请求的Servlet;如果Filter不“放行”,那么就不会执行用户请求的Servlet。

其实可以这样理解,当用户请求某个Servlet时,Tomcat会去执行Filter,而是否“放行”由Filter来决定。可以理解为,Filter来决定是否调用Servlet。当执行完成Servlet的代码后,还会继续执行Filter后面的代码

2.Filter生命周期

容器启动时就创建Filter实例,先执行构造方法,然后执行init()方法,这两步是在容器创建时就已经执行了的。在此之后,每次拦截到需要过滤的请求都会执行doFilter()方法。在容器关闭时,执行destroy()方法。

public class GlobalFilter implements Filter {

    public GlobalFilter() { //容器创建时执行
    }

    @Override
    public void init(FilterConfig filterConfig) throws ServletException { //容器创建时执行
    }

    @Override
    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException { //拦截到请求时执行
    }

    @Override
    public void destroy() { //容器销毁时执行
    }
}

3.Filter的实现

3.1 Java代码

我们知道用户的会话信息是存在Session中的,所以权限管理时我们可以基于Session中保存的信息对于不同权限的用户进行不同的管理。这里我们主要研究doFilter方法即可:

  1. servletRequest类并没有直接获取Session的方法,我们可以将servletRequest强制转换为其父类HttpServletRequest,利用父类的getSession()方法来获取,并且新建一个对象用于存储用户信息;
  2. 根据用户信息进行判断其权限,并根据其权限决定是否“放行”;
  3. 若“放行”,则使用filterChain访问用户所请求的资源;若“拦截”,则将用户请求转发至特定页面(例如未登录情况下强行跳转至登录界面)。要注意的是,在请求转发后一定要添加return;,否则在请求转发完成后会顺序执行后续代码。
  4. 若登录页、注册页与过滤目录在同一目录下,必须将其排除在过滤名单之外,具体可以使用很多方法实现,这里用了indexOf函数来判断url中是否有某些页面的字段以将其排除。

具体代码示例如下:

    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
        HttpServletRequest httpServletRequest = (HttpServletRequest) servletRequest;
        HttpServletResponse httpServletResponse = (HttpServletResponse) servletResponse;
        Object user = httpServletRequest.getSession().getAttribute("user");
        String path = httpServletRequest.getRequestURI();

        if (!(path.indexOf("/login.jsp") + path.indexOf("/register.jsp") + path.indexOf("/pleaselogin.jsp") > -1)) {
            filterChain.doFilter(servletRequest, servletResponse);
            return;
        }

        if (user == null) {
            servletRequest.setAttribute("msg", "请先登录!");
//            servletRequest.getRequestDispatcher("/pages/user/login.jsp").forward(servletRequest,servletResponse); //请求转发
            httpServletResponse.sendRedirect("/test/pages/pleaselogin.jsp");  //页面重定向
            return;
        } else {
            filterChain.doFilter(servletRequest, servletResponse);
        }
    }

3.2 web.xml 配置

<filter>
    <filter-name>GlobalFilter</filter-name> <!---过滤器名->
    <filter-class>com.renhouse.filter.GlobalFilter</filter-class> <!---过滤器类->
  </filter>
  <filter-mapping> <!---配置需要过滤的页面->
    <filter-name>GlobalFilter</filter-name>
    <url-pattern>/pages/*</url-pattern>
    <url-pattern>/houseServlet</url-pattern>
  </filter-mapping>

以上仅为个人学习过程中的学习记录,在开发过程中会持续完善。若有理解错误的地方欢迎指正。

猜你喜欢

转载自blog.csdn.net/qq_37396476/article/details/107317448