Java体系知识之过滤器Filter

Java体系知识之过滤器Filter

1 技术简介

(1)过滤器:
	净水器
	空气净化器
	...
(2)JavaWeb组件:
	Servlet
	Filter
	Listener
(3)作用:
	适合做一些通用的操作
	
	A.普通意义的公共代码:
		跨域请求处理;
		字符编码;
	B.逻辑方面的公共代码:
    	登录访问控制:根据是否登录判断
    		若已登录过,可允许继续访问;
    		若未登录,不允许继续访问;
		权限访问控制:根据是否拥有权限判断
			若已拥有权限,可允许访问;
			若不拥有权限,不允许访问;

2 过滤器使用步骤(重点)

2.1 使用步骤

(1)创建一个类,实现Filter接口
(2)重写方法
(3)配置过滤器:
	web.xml;
	注解;

2.2 案例

package com.javasm.filter.basic;

import javax.servlet.*;
import javax.servlet.annotation.WebFilter;
import java.io.IOException;

/**
 * @author: ShangMa
 * @className: MyFilterDemo01
 * @description: 过滤器使用步骤
 * @date: 2022/8/31 11:22
 */
@WebFilter("/demo01")
public class MyFilterDemo01 implements Filter {
    /**
     * 过滤器使用步骤:
     * (1)创建一个类,实现Filter接口
     * (2)重写方法
     * (3)配置过滤器:
     * 	web.xml;
     * 	注解;
     *
     */
    @Override
    public void init(FilterConfig filterConfig) throws ServletException {
    }

    @Override
    public void destroy() {
    }

    @Override
    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
        System.out.println("执行MyFilterDemo01.doFilter()");

    }
}

3 过滤器执行过程(重点)

3.1 内容概述

(1)当请求过来时,先进入过滤器执行
(2)若过滤器有放行代码,再找对应的Servlet执行
(3)最后执行放行代码下面的语句

3.2 案例

package com.javasm.filter.basic;

import javax.servlet.*;
import javax.servlet.annotation.WebFilter;
import java.io.IOException;

/**
 * @author: ShangMa
 * @className: MyFilterDemo02
 * @description: 过滤器执行过程
 * @date: 2022/8/31 11:22
 */
@WebFilter("/demo02")
public class MyFilterDemo02 implements Filter {
    /**
     * 过滤器执行过程:
     *  当请求过来时,先进入过滤器执行;
     *  若过滤器有放行代码,再找对应的Servlet执行;
     *  最后执行放行代码下面的语句;
     */

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

    @Override
    public void destroy() {
    }

    @Override
    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
        System.out.println("执行MyFilterDemo02.doFilter()");
        // 放行代码
        filterChain.doFilter(servletRequest,servletResponse);
        System.out.println("执行MyFilterDemo02过滤器放行代码下面的语句");
    }
}

4 过滤器生命周期

4.1 内容概述

(1)服务器启动时,创建Filter实例,触发init方法执行
(2)当有请求访问时,执行doFilter方法
(3)服务器正常关闭时,销毁Filter实例,触发destroy方法执行

4.2 案例

package com.javasm.filter.basic;

import javax.servlet.*;
import javax.servlet.annotation.WebFilter;
import java.io.IOException;

/**
 * @author: ShangMa
 * @className: MyFilterDemo03
 * @description: 过滤器生命周期
 * @date: 2022/8/31 15:21
 */
@WebFilter("/demo03")
public class MyFilterDemo03 implements Filter {
    /**
     * 过滤器生命周期:
     *  服务器启动时,创建Filter实例,触发init方法执行;
     *  当有请求访问时,执行doFilter方法;
     *  服务器正常关闭时,销毁Filter实例,触发destroy方法执行;
     */
    @Override
    public void init(FilterConfig filterConfig) throws ServletException {
        System.out.println("服务器启动时,创建Filter实例,触发init方法执行");
    }

    @Override
    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
        System.out.println("执行MyFilterDemo03.doFilter()");
        // 放行代码
        // filterChain.doFilter(servletRequest, servletResponse);

    }

    @Override
    public void destroy() {
        System.out.println("服务器正常关闭时,销毁Filter实例,触发destroy方法执行");
    }
}

5 过滤器配置详解

5.1 内容概述

(1)拦截具体资源:比如 /demo04
(2)拦截指定目录:比如 /menu/*
(3)拦截指定后缀:比如 *.do
(4)拦截所有请求资源:比如 /*

6 过滤器链

(1)当经过分析,发现该案例中需要使用多个过滤器时,则配置多个多滤器即可
(2)当给多个过滤器配置相同的访问路径后,执行顺序:
	注解配置:按照类名的字符串比较规则比较,值小的先执行;
	web.xml:哪个过滤器的配置代码在前面,先执行哪个过滤器;

7 综合案例(重点)

7.1 处理请求数据乱码

7.1.1 MyFilter1

package com.javasm.filter.case1;

import javax.servlet.*;
import javax.servlet.annotation.WebFilter;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;

/**
 * @author: ShangMa
 * @className: MyFilter1
 * @description: 处理中文乱码
 * @date: 2022/8/31 16:19
 */
@WebFilter("/*")
public class MyFilter implements Filter {
    @Override
    public void init(FilterConfig filterConfig) throws ServletException {
    }

    @Override
    public void destroy() {
    }

    @Override
    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
        servletRequest.setCharacterEncoding("utf-8");
        filterChain.doFilter(servletRequest,servletResponse);
    }
}

7.2 登录访问控制&权限访问控制

(1)场景:
	用户执行登录->访问其他模块
	
	问题:
		未登录->不能访问其他模块   给用户设置提示信息
		无权限->不能访问对应模块   给用户设置提示信息
(2)过滤器:
	未登录->不能访问其他模块   给用户设置提示信息
	无权限->不能访问对应模块   给用户设置提示信息
(3)过程:
	模拟:
		filter
		servlet:假设用户登录成功,设置基础用户数据和用户权限数据绑定到session对象

7.2.1 案例实现

7.2.1 MyFilter1

package com.javasm.filter.case2.filter;

import javax.servlet.*;
import javax.servlet.annotation.WebFilter;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;

/**
 * @author: ShangMa
 * @className: MyFilter1
 * @description: 处理中文乱码
 * @date: 2022/8/31 16:19
 */
@WebFilter("/*")
public class MyFilter1 implements Filter {
    @Override
    public void init(FilterConfig filterConfig) throws ServletException {
    }

    @Override
    public void destroy() {
    }

    @Override
    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
        System.out.println("1111");
        HttpServletRequest req = (HttpServletRequest) servletRequest;
        HttpServletResponse resp = (HttpServletResponse) servletResponse;
        servletRequest.setCharacterEncoding("utf-8");
        String requestURI = req.getRequestURI();
        if("/login".equals(requestURI) || requestURI.endsWith(".html")){
            filterChain.doFilter(servletRequest,servletResponse);
        }
    }
}

7.2.2 MyFilter2

package com.javasm.filter.case2.filter;

import com.alibaba.fastjson.JSON;
import com.javasm.filter.entity.CodeAndMsg;
import com.javasm.filter.entity.ReturnEntity;

import javax.servlet.*;
import javax.servlet.annotation.WebFilter;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.io.IOException;
import java.io.PrintWriter;

/**
 * @author: ShangMa
 * @className: MyFilter2
 * @description: 处理用户是否登录
 * @date: 2022/8/31 16:20
 */
@WebFilter("/*")
public class MyFilter2 implements Filter {
    @Override
    public void init(FilterConfig filterConfig) throws ServletException {
    }

    @Override
    public void destroy() {
    }

    @Override
    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
        HttpServletRequest req = (HttpServletRequest) servletRequest;
        HttpServletResponse resp = (HttpServletResponse) servletResponse;
        // 获取值
        HttpSession session = req.getSession();
        String userName = (String) session.getAttribute("userName");
        // 根据路径判断
        String requestURI = req.getRequestURI();
        // 白名单
        if ("/login".equals(requestURI) || requestURI.endsWith(".html")) {
            // 执行登录  放行
            filterChain.doFilter(servletRequest, servletResponse);
        } else {
            // 不是执行登录 是否已登录
            if (userName != null) {
                filterChain.doFilter(servletRequest, servletResponse);
            } else {
                // 未登录 设置提示信息
                ReturnEntity re = new ReturnEntity();
                re.setReturnCode(CodeAndMsg.NO_LOGIN.getReturnCode());
                re.setReturnMsg(CodeAndMsg.NO_LOGIN.getReturnMsg());
                resp.setContentType("application/json;charset=utf-8");
                PrintWriter writer = resp.getWriter();
                writer.print(JSON.toJSONString(re));
                writer.flush();
                writer.close();
            }
        }
    }
}

7.2.3 MyFilter3

package com.javasm.filter.case2.filter;

import com.alibaba.fastjson.JSON;
import com.javasm.filter.entity.CodeAndMsg;
import com.javasm.filter.entity.ReturnEntity;

import javax.servlet.*;
import javax.servlet.annotation.WebFilter;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.List;

/**
 * @author: ShangMa
 * @className: MyFilter3
 * @description: 处理用户是否有权限
 * @date: 2022/8/31 16:20
 */
@WebFilter("/*")
public class MyFilter3 implements Filter {
    @Override
    public void init(FilterConfig filterConfig) throws ServletException {
    }

    @Override
    public void destroy() {
    }

    @Override
    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
        HttpServletRequest req = (HttpServletRequest) servletRequest;
        HttpServletResponse resp = (HttpServletResponse) servletResponse;
        HttpSession session = req.getSession();
        List<String> authList = (List<String>) session.getAttribute("authList");
        // 获取请求路径
        String requestURI = req.getRequestURI();
        // 判断
        if ("/login".equals(requestURI)) {
            filterChain.doFilter(servletRequest, servletResponse);
        } else {
            // 判断是否有权限
            if(authList.contains(requestURI)){
                // 有权限
                filterChain.doFilter(servletRequest, servletResponse);
            }else{
                // 无权限  设置提示信息
                ReturnEntity re = new ReturnEntity();
                re.setReturnCode(CodeAndMsg.NO_AUTH.getReturnCode());
                re.setReturnMsg(CodeAndMsg.NO_AUTH.getReturnMsg());
                resp.setContentType("application/json;charset=utf-8");
                PrintWriter writer = resp.getWriter();
                writer.print(JSON.toJSONString(re));
                writer.flush();
                writer.close();
            }
        }
    }
}

7.2.4 LoginServlet

package com.javasm.filter.case2.servlet;

import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;

/**
 * @author: ShangMa
 * @className: LoginServlet
 * @description: 控制层-用户注册
 * @date: 2022/8/31 16:13
 */
@WebServlet("/login")
public class LoginServlet extends HttpServlet {
    @Override
    protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        System.out.println(req.getParameter("userName"));
        // 假设通过判断,该用户可以登录
        boolean isLogin = true;
        if (isLogin) {
            HttpSession session = req.getSession();
            // 往session对象上绑定基础的用户数据->该用户是否已登录
            session.setAttribute("userName", "tom");
            // 往session对象上绑定用户权限数据->该用户是否有对应权限
            List<String> authList = new ArrayList<>();
            authList.add("/menu/query");
            authList.add("/menu/queryOneMenu");
            session.setAttribute("authList", authList);
        }
    }
}

你可能感兴趣的:(java,servlet,前端)