SpringBoot学习笔记8(过滤器、监听器、拦截器)

过滤器介绍

filter是servlet规范中定义的一种特殊类。用于对指定的请求进行过滤,然后将请求交给对应的servlet进行处理并生成响应,最后filter再对服务器响应进行后处理,可以实现访问权限控制、过滤敏感词汇、压缩响应信息等功能。

监听器介绍

listener也是servlet规范中定义的一种特殊类。用于监听servletContext、HttpSession和servletRequest等域对象的创建和销毁事件。在事件发生前后做一些必要的处理,可以实现在线人数统计等功能。

拦截器介绍

interceptor在面向切面编程(Aspect-Oriented Programming,AOP)中用于在某个方法或字段被访问之前进行拦截,然后在处理前后加入某些功能,例如:日志,安全等功能。一般拦截器方法都是通过动态代理的方式实现,可以通过它来进行权限验证、判断用户是否登陆、日志记录。

下面是一个简单的实例:

文件夹结构.png

FilterConfig.java

// 标识本类为配置类
@Configuration
public class FilterConfig {

    @Bean
    public FilterRegistrationBean registFilter() {
        // 创建注册器
        FilterRegistrationBean registration = new FilterRegistrationBean();
        // 设置过滤器
        registration.setFilter(new LoginFilter());

        // 设置属性exclusions,不需要过滤的URL
        registration.addInitParameter("exclusions", "/user/login");

        // 添加过滤规则
        registration.addUrlPatterns("/*");
        // 过滤器设置名称
        registration.setName("LoginFilter");
        // 设置过滤器顺序,值越小优先级越高
        registration.setOrder(1);

        return registration;
    }
}

InterceptorConfig.java

// 标识本类为配置类
@Configuration
public class InterceptorConfig extends WebMvcConfigurationSupport{

    @Autowired
    private WordInterceptor wordInterceptor;

    @Override
    public void addInterceptors(InterceptorRegistry registry) {
        // 注册敏感词汇拦截器,设置拦截路径
        registry.addInterceptor(wordInterceptor).addPathPatterns("/user/search");

        super.addInterceptors(registry);
    }
}

ListenerConfig.java

// 标识本类为配置类
@Configuration
public class ListenerConfig {

    @Bean
    public OnlineListener init() {
        return new OnlineListener();
    }
}

UserController.java

@RestController
@RequestMapping("user")
public class UserController {

    // 统计在线用户数,请求方法类型get,URL:/user/online
    @GetMapping("online")
    public ResultObject setSession(HttpServletRequest request,
                                   HttpServletResponse response) {
        // 获取session
        HttpSession session = request.getSession();
        // 获取sessionid,即JSESSIONID
        String sessionId = session.getId();
        System.out.println(sessionId);

        // 获取session属性
        Object onlineNumber = session.getServletContext().getAttribute("onlineNumber");
        System.out.println(onlineNumber);
        // 返回结果
        return new ResultObject(onlineNumber);
    }

    // 登录验证用户,请求方法类型post,URL:/user/login
    @PostMapping("login")
    public ResultObject login(@RequestBody User user, HttpServletRequest request, HttpServletResponse response) {

        // 正确账号密码,模拟数据库中的信息
        User realUser = new User("jacky", "112233");
        // 判断账号、密码是否正确
        if (realUser.equals(user)) {
            // 获取session,获取不到则新建
            HttpSession session = request.getSession();

            // 获取sessionid,即JSESSIONID
            String sessionId = session.getId();
            System.out.println(sessionId);

            // 设置session属性user
            session.setAttribute("user", user);

            return new ResultObject("login success");
        } else {
            return new ResultObject(-1, "fail", "login fail");
        }
    }

    // 搜索功能,过滤敏感词汇,请求方法类型get,URL:/user/search
    @GetMapping("search")
    public ResultObject search(@RequestParam String word) {
        // 若关键字是敏感词,在拦截器中已经被拦截不可能走到这里
        return new ResultObject("search word " + "'" + word + "'" + " is valid.");
    }
}

ResultObject.java

public class ResultObject {

    // 后台返回码
    private int code;
    // 后台返回消息
    private String msg;
    // 结果
    private Object result;

    // 构造函数
    public ResultObject() {
        super();
        // TODO Auto-generated constructor stub
    }

    // 构造函数
    public ResultObject(int code, String msg, Object result) {
        super();
        this.code = code;
        this.msg = msg;
        this.result = result;
    }

    // 后台处理成功时使用的构造函数
    public ResultObject(Object result) {
        super();
        this.code = 0;
        this.msg = "success";
        this.result = result;
    }

    // 属性的setter、getter方法
    public int getCode() {
        return code;
    }
    public void setCode(int code) {
        this.code = code;
    }
    public String getMsg() {
        return msg;
    }
    public void setMsg(String msg) {
        this.msg = msg;
    }
    public Object getResult() {
        return result;
    }
    public void setResult(Object result) {
        this.result = result;
    }
    @Override
    public String toString() {
        return "ResultObject [code=" + code + ", msg=" + msg + ", result=" + result + "]";
    }
}

User.java

public class User{

    // 用户名称
    private String username;
    // 用户密码
    private String password;

    // 构造函数
    public User() {
        super();
        // TODO Auto-generated constructor stub
    }

    // 构造函数
    public User(String username, String password) {
        super();
        this.username = username;
        this.password = password;
    }

    // 属性的setter、getter方法
    public String getUsername() {
        return username;
    }
    public void setUsername(String username) {
        this.username = username;
    }
    public String getPassword() {
        return password;
    }
    public void setPassword(String password) {
        this.password = password;
    }

    // 重写toString方法
    @Override
    public String toString() {
        return "Book [username=" + username + ", password=" + password + "]";
    }

    // 重写hashCode方法
    @Override
    public int hashCode() {
        final int prime = 31;
        int result = 1;
        result = prime * result + ((password == null) ? 0 : password.hashCode());
        result = prime * result + ((username == null) ? 0 : username.hashCode());
        return result;
    }

    // 重写equals方法,便于直接比较user对象
    @Override
    public boolean equals(Object obj) {
        if (this == obj)
            return true;
        if (obj == null)
            return false;
        if (getClass() != obj.getClass())
            return false;
        User other = (User) obj;
        if (password == null) {
            if (other.password != null)
                return false;
        } else if (!password.equals(other.password))
            return false;
        if (username == null) {
            if (other.username != null)
                return false;
        } else if (!username.equals(other.username))
            return false;
        return true;
    }
}

LoginFilter.java

public class LoginFilter implements Filter {

    // 存储不需要过滤的URLs,一个对象
    private static String exclusions;
    // 存储不需要过滤的URLs,exclusions分解而来的字符串数组
    private static String[] ALLOWEDURLS;

    @Override
    public void init(FilterConfig filterConfig) throws ServletException {
        // TODO Auto-generated method stub
        // 获取在filterconfig中配置好的,不需要过滤的URLs
        exclusions = filterConfig.getInitParameter("exclusions");
        if (!exclusions.isEmpty()) {
            // 获取不需要过滤的URLs,可以直接访问的URLs
            ALLOWEDURLS = exclusions.split(",");
        }
    }

    @Override
    public void doFilter(ServletRequest servletRequest,
                         ServletResponse servletResponse, FilterChain chain)
            throws IOException, ServletException {

        // 强转
        HttpServletRequest request = (HttpServletRequest)servletRequest;
        HttpServletResponse response = (HttpServletResponse)servletResponse;

        // 获取当前请求的URL
        String url = request.getRequestURI();

        // 获取session,false表示如果没有获取到也不会创建
        HttpSession session = request.getSession(false);
        // 如果当前请求的URL不需要过滤或者已经登录的用户的请求,则继续处理
        if (isAllowed(url) || session != null && session.getAttribute("user") != null) {
            chain.doFilter(request, response);
        } else {
            // 若用户没有登录,否则直接返回
            render(response, "not login");
        }
    }

    @Override
    public void destroy() {
        // TODO Auto-generated method stub

    }

    // 当前请求是否需要过滤
    public boolean isAllowed(String url) {
        for (String ALLOWEDURL: ALLOWEDURLS) {
            if (ALLOWEDURL.equals(url)) {
                return true;
            }
        }
        return false;
    }

    // 返回请求失败消息
    public void render(HttpServletResponse response, String msg) throws IOException {
        // 构造返回消息
        ResultObject resultObject = new ResultObject(-1, "fail", msg);

        // 生成json数据
        JSONObject object = new JSONObject(resultObject);

        // 返回json数据
        response.setContentType("application/json;charset=UTF-8");
        OutputStream out = response.getOutputStream();
        out.write(object.toString().getBytes("UTF-8"));
        out.flush();
        out.close();
    }

}

WordInterceptor.java

@Component
public class WordInterceptor implements HandlerInterceptor{

    // 设置敏感词汇
    private static final String[] forbitWords = {"apple", "pear", "peach", "Lemon "};

    // 处理前方法
    @Override
    public boolean preHandle(HttpServletRequest request,
                             HttpServletResponse response, Object handler) throws Exception {
        // 获取请求中的参数word
        String word = request.getParameter("word");
        // 与敏感词汇对比
        for (String forbitWord: forbitWords) {
            if (word.equals(forbitWord)) {
                render(response, "search word " + "'" + word + "'" + " is not allowed.");
                // 返回假,中断请求
                return false;
            }
        }

        // 返回真,继续处理请求
        return true;
    }

    // 处理后方法
    @Override
    public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler,
                           ModelAndView modelAndView) throws Exception {
    }

    // 完成后方法
    @Override
    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex)
            throws Exception {
    }

    // 返回失败消息
    public void render(HttpServletResponse response, String msg) throws IOException {
        ResultObject resultObject = new ResultObject(-1, msg, null);

        JSONObject object = new JSONObject(resultObject);

        response.setContentType("application/json;charset=UTF-8");
        OutputStream out = response.getOutputStream();
        out.write(object.toString().getBytes("UTF-8"));
        out.flush();
        out.close();
    }
}

OnlineListener.java

@WebListener
public class OnlineListener implements HttpSessionListener{

    // 记录当前登录用户数
    private int onlineNumber = 0;

    @Override
    public void sessionCreated(HttpSessionEvent se) {
        // 监听到创建了新的session,在线用户累加1
        onlineNumber++;
        // 设置session属性
        se.getSession().getServletContext().setAttribute("onlineNumber", onlineNumber);
    }

    @Override
    public void sessionDestroyed(HttpSessionEvent se) {
        // 监听到销毁了旧的session,在线用户减少1
        onlineNumber--;
        // 设置session属性
        se.getSession().getServletContext().setAttribute("onlineNumber", onlineNumber);
    }

}

文集推荐:

Java基础方法集1
Python基础知识完整版
Spring Boot学习笔记
Linux指令进阶
Java高并发编程
SpringMVC基础知识进阶
Mysql基础知识完整版
健康管理系统学习花絮(学习记录)
Node.js基础知识(随手笔记)
MongoDB基础知识
Dubbo学习笔记
Vue学习笔记(随手笔记)

声明:发表此文是出于传递更多信息之目的。若有来源标注错误或侵犯了您的合法权益,请作者持权属证明与本我们(QQ:981086665;邮箱:[email protected])联系联系,我们将及时更正、删除,谢谢。

你可能感兴趣的:(SpringBoot学习笔记8(过滤器、监听器、拦截器))