Java Web学习 Filter

1 Filter概述

// JavaWeb 三大组件(Servlet、Filter、Listener)之一。
(1) 过滤器可以把对资源的请求拦截下来,从而实现一些特殊的功能。
(2) 浏览器可以访问服务器上的所有的资源(servlet、jsp、html等),而在访问到这些资源之前可以使过滤器拦截来下,也就是说在访问资源之前会先经过 Filter。
(3) 过滤器一般完成一些通用的操作。比如每个资源都要写一些代码完成某个功能,我们总不能在每个资源中写这样的代码吧,而此时我们可以将这些代码写在过滤器中,因为请求每一个资源都要经过过滤器。

       

2 Filter快速入门

(1) 定义类,实现 Filter接口,并重写其所有方法//定义在filter包下

public class FilterDemo implements Filter {
	@Override
	public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
	}

	@Override
	public void init(FilterConfig filterConfig) throws ServletException {
	}

	@Override
	public void destroy() {
	}
}

(2) 配置Filter拦截资源的路径:在类上定义 @WebFilter 注解。而注解的 value 属性值 * 表示拦截所有的资源
@WebFilter("/*")
(3) 在doFilter方法先对request数据进行处理,并放行,访问完成资源后,对Response数据进行处理

public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
	//1 放行前,对request数据进行处理
	//2 放行
	chain.doFilter(request,response);
	//chain.doFilter(request,response); 就是放行,也就是让其访问本该访问的资源。
	//3 放行后,对Response数据进行处理
}

 

3 Filter执行流程

执行放行前的逻辑->放行->访问资源->执行放行后的逻辑
//有点类似于递归,调用函数的代码执行完成后,继续返回执行剩余的代码。
//放行后访问对应资源,资源访问完成后,还会回到Filter中
//如果回到Filter中,会回到放行后逻辑 ,执行该部分代码。
//以后我们可以将对请求进行处理的代码放在放行之前进行处理,而如果请求完资源后还要对响应的数据进行处理时可以在放行后进行逻辑处理。

 

4 Filter拦截路径配置

(1) 拦截路径表示 Filter 会对请求的哪些资源进行拦截,使用 @WebFilter 注解进行配置。
(2) 拦截路径有如下四种配置方式:
<2.1> 拦截具体的资源:/index.jsp:只有访问index.jsp时才会被拦截
<2.2> 目录拦截:/user/*:访问/user下的所有资源,都会被拦截
<2.3> 后缀名拦截:*.jsp:访问后缀名为jsp的资源,都会被拦截
<2.4> 拦截所有:/*:访问所有资源,都会被拦截
//通过上面拦截路径的学习,大家会发现拦截路径的配置方式和 Servlet 的请求资源路径配置方式一样,但是表示的含义不同。

 

5 过滤器链

(1) 概述
过滤器链是指在一个Web应用,可以配置多个过滤器,这多个过滤器称为过滤器链。
(2) 运行流程
//若某个web应用有两个过滤器:Filter1、Filter2
<2.1> 执行 Filter1 的放行前逻辑代码
<2.2> 执行 Filter1 的放行代码
<2.3> 执行 Filter2 的放行前逻辑代码
<2.4> 执行 Filter2 的放行代码
<2.5> 访问到资源
<2.6> 执行 Filter2 的放行后逻辑代码
<2.7> 执行 Filter1 的放行后逻辑代码
(3) 我们现在使用的是注解配置Filter,而这种配置方式的优先级是按照过滤器类名(字符串)的自然排序。
比如有如下两个名称的过滤器 : BFilterDemo 和 AFilterDemo 。那一定是 AFilterDemo 过滤器先执行。

 

 6 登录fliter

@WebFilter("/*")
public class LoginFilter implements Filter {
    public void init(FilterConfig config) throws ServletException {
    }

    public void destroy() {
    }

    @Override
    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws ServletException, IOException {
        //将ServletRequest强转为HttpServletRequest,因为只有HttpServletRequest才能获取session。
        HttpServletRequest req = (HttpServletRequest) request;

        //确保所有非敏感信息(不登陆也需要被访问的数据)可以直接被访问。
        //将所有非敏感信息地址的关键部分,写入字符串数组。
        String[] urls = {"/login.jsp","register.jsp","/imgs/","/css/","/CheckCodeServlet","/LoginServlet","/RegisterServlet"};
        //获取当前访问的地址。
        String url = req.getRequestURL().toString();
        //将当前访问地址与字符串数组中数据轮番比对。
        for (String u:urls){
            if (url.contains(u)){//如果访问地址包含数组中某一个字符串。
                //放行。
                chain.doFilter(request, response);
                //终止程序。
                return;
            }
        }

        //确保所有敏感信息(登陆才能被访问的数据)不可以直接被访问。
        //LoginServlet中只有登录后的客户端session中才有user。
        HttpSession session = req.getSession();
        Object user = session.getAttribute("user");
        if (user != null) {//该用户已登录。
            //放行。
            chain.doFilter(request, response);
        }else{//该用户未登录。
            //跳转到登录页面返回错误信息。
            req.setAttribute("login_msg","您尚未登录!");
            req.getRequestDispatcher("/login.jsp").forward(req,response);
        }
    }
}

 

posted @ 2023-03-28 11:22  10kcheung  阅读(28)  评论(0)    收藏  举报