• SpringBoot中Filter和Interceptor快速入门


    一、Filter

    1.定义

    说明:filter文件里面DemoFilter类实现Filter接口。

    1. package com.itheima.filter;
    2. import javax.servlet.*;
    3. import javax.servlet.annotation.WebFilter;
    4. import java.io.IOException;
    5. //用于指定一个过滤器要拦截的URL模式。
    6. @WebFilter(urlPatterns = "/*")
    7. public class DemoFilter implements Filter {
    8. @Override //初始化方法, 只调用一次
    9. public void init(FilterConfig filterConfig) throws ServletException {
    10. System.out.println("init 初始化方法执行了");
    11. }
    12. @Override //拦截到请求之后调用, 调用多次
    13. public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
    14. System.out.println("Demo 拦截到了请求...放行前逻辑");
    15. //放行
    16. chain.doFilter(request, response);
    17. System.out.println("Demo 拦截到了请求...放行后逻辑");
    18. }
    19. @Override //销毁方法, 只调用一次
    20. public void destroy() {
    21. System.out.println("destroy 销毁方法执行了");
    22. }
    23. }

    2.测试类

    1. package com.itheima;
    2. import org.springframework.boot.SpringApplication;
    3. import org.springframework.boot.autoconfigure.SpringBootApplication;
    4. import org.springframework.boot.web.servlet.ServletComponentScan;
    5. //开启了servlet组件支持(拦截支持)
    6. @ServletComponentScan
    7. @SpringBootApplication
    8. public class TliasWebManagementApplication {
    9. public static void main(String[] args) {
    10. SpringApplication.run(TliasWebManagementApplication.class, args);
    11. }
    12. }

     3.过滤器

    说明:请求->放行前逻辑->放行->资源->放行;创建一个另一个XbcFilter类实现Filter接口。执行顺序根据类名字母顺序一次进行。

    1. package com.itheima.filter;
    2. import javax.servlet.*;
    3. import javax.servlet.annotation.WebFilter;
    4. import java.io.IOException;
    5. //执行顺序类名首字母靠前就在前
    6. @WebFilter(urlPatterns = "/*")
    7. public class XbcFilter implements Filter {
    8. @Override
    9. public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
    10. System.out.println("Abc 拦截到了请求...放行前逻辑");
    11. //放行
    12. chain.doFilter(request,response);
    13. System.out.println("Abc 拦截到了请求...放行后逻辑");
    14. }
    15. }

    4.完成的filter类

    1. package com.itheima.filter;
    2. import com.alibaba.fastjson.JSONObject;
    3. import com.itheima.controller.utils.JwtUtils;
    4. import com.itheima.pojo.Result;
    5. import lombok.extern.slf4j.Slf4j;
    6. import org.springframework.util.StringUtils;
    7. import javax.servlet.*;
    8. import javax.servlet.http.HttpServletRequest;
    9. import javax.servlet.http.HttpServletResponse;
    10. import java.io.IOException;
    11. @Slf4j
    12. @WebFilter(urlPatterns = "/*")
    13. public class LoginCheckFilter implements Filter {
    14. @Override
    15. public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
    16. // 强转我们可以使用HttpServletRequest和ServletResponse对象中的所有方法,而不受Spring框架的限制。
    17. HttpServletRequest req = (HttpServletRequest) request;
    18. HttpServletResponse resp = (HttpServletResponse) response;
    19. //1.获取请求url。
    20. String url = req.getRequestURL().toString();
    21. log.info("请求的url: {}", url);
    22. //2.判断请求url中是否包含login,如果包含,说明是登录操作,放行。
    23. if (url.contains("login")) {
    24. log.info("登录操作, 放行...");
    25. chain.doFilter(request, response);
    26. // 如果不写return语句,那么程序会继续执行下一个过滤器,直到过滤器链中的最后一个过滤器执行完毕。
    27. return;
    28. }
    29. //3.获取请求头中的令牌(token)。
    30. String jwt = req.getHeader("token");
    31. //4.判断令牌是否存在,如果不存在,返回错误结果(未登录)。
    32. if (!StringUtils.hasLength(jwt)) {
    33. log.info("请求头token为空,返回未登录的信息");
    34. Result error = Result.error("NOT_LOGIN");
    35. //手动转换 对象--json --------> 阿里巴巴fastJSON
    36. String notLogin = JSONObject.toJSONString(error);
    37. // HttpServletResponse接口提供了一个getWriter()方法,该方法返回一个PrintWriter对象,用于将数据写入HTTP响应中。
    38. resp.getWriter().write(notLogin);
    39. return;
    40. }
    41. //5.解析token,如果解析失败,返回错误结果(未登录)。
    42. try {
    43. // ctrl+alt+t try,catch使用
    44. JwtUtils.parseJWT(jwt);
    45. } catch (Exception e) {//jwt解析失败
    46. e.printStackTrace();
    47. log.info("解析令牌失败, 返回未登录错误信息");
    48. Result error = Result.error("NOT_LOGIN");
    49. //手动转换 对象--json --------> 阿里巴巴fastJSON
    50. // 将error对象转成字符串
    51. String notLogin = JSONObject.toJSONString(error);
    52. // 直接响应给浏览器
    53. resp.getWriter().write(notLogin);
    54. return;
    55. }
    56. //6.放行。
    57. log.info("令牌合法, 放行");
    58. chain.doFilter(request, response);
    59. }
    60. }

     

    二、Interceptor

    1.概念

    说明:是一种动态拦截方法调用的机制,类似于过滤器。Spig框架中提供的,用来动态拦截控制器方法的执行。

    2.定义拦截器类

    1. package com.itheima.interceptor;
    2. import com.alibaba.fastjson.JSONObject;
    3. import com.itheima.controller.utils.JwtUtils;
    4. import com.itheima.pojo.Result;
    5. import lombok.extern.slf4j.Slf4j;
    6. import org.springframework.stereotype.Component;
    7. import org.springframework.util.StringUtils;
    8. import org.springframework.web.servlet.HandlerInterceptor;
    9. import org.springframework.web.servlet.ModelAndView;
    10. import javax.servlet.http.HttpServletRequest;
    11. import javax.servlet.http.HttpServletResponse;
    12. @Slf4j
    13. //IOC容器管理
    14. @Component
    15. public class LoginCheckInterceptor implements HandlerInterceptor {
    16. @Override //目标资源方法运行前运行, 返回true: 放行, 放回false, 不放行
    17. public boolean preHandle(HttpServletRequest req, HttpServletResponse resp, Object handler) throws Exception {
    18. //1.获取请求url。
    19. String url = req.getRequestURL().toString();
    20. log.info("请求的url: {}",url);
    21. //2.判断请求url中是否包含login,如果包含,说明是登录操作,放行。
    22. if(url.contains("login")){
    23. log.info("登录操作, 放行...");
    24. return true;
    25. }
    26. //3.获取请求头中的令牌(token)。
    27. String jwt = req.getHeader("token");
    28. //4.判断令牌是否存在,如果不存在,返回错误结果(未登录)。
    29. if(!StringUtils.hasLength(jwt)){
    30. log.info("请求头token为空,返回未登录的信息");
    31. Result error = Result.error("NOT_LOGIN");
    32. //手动转换 对象--json --------> 阿里巴巴fastJSON
    33. String notLogin = JSONObject.toJSONString(error);
    34. resp.getWriter().write(notLogin);
    35. return false;
    36. }
    37. //5.解析token,如果解析失败,返回错误结果(未登录)。
    38. try {
    39. JwtUtils.parseJWT(jwt);
    40. } catch (Exception e) {//jwt解析失败
    41. e.printStackTrace();
    42. log.info("解析令牌失败, 返回未登录错误信息");
    43. Result error = Result.error("NOT_LOGIN");
    44. //手动转换 对象--json --------> 阿里巴巴fastJSON
    45. String notLogin = JSONObject.toJSONString(error);
    46. resp.getWriter().write(notLogin);
    47. return false;
    48. }
    49. //6.放行。
    50. log.info("令牌合法, 放行");
    51. return true;
    52. }
    53. @Override //目标资源方法运行后运行
    54. public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
    55. System.out.println("postHandle ...");
    56. }
    57. @Override //视图渲染完毕后运行, 最后运行
    58. public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
    59. System.out.println("afterCompletion...");
    60. }
    61. }

    3. 配置类

    1. package com.itheima.config;
    2. import com.itheima.interceptor.LoginCheckInterceptor;
    3. import org.springframework.beans.factory.annotation.Autowired;
    4. import org.springframework.context.annotation.Configuration;
    5. import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
    6. import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
    7. @Configuration //配置类
    8. public class WebConfig implements WebMvcConfigurer {
    9. @Autowired
    10. private LoginCheckInterceptor loginCheckInterceptor;
    11. @Override
    12. public void addInterceptors(InterceptorRegistry registry) {
    13. // registry添加一个拦截器,定义的一个loginCheckInterceptor类;拦截什么路径的资源 /**表示所有容器,/*表示一级路径,不拦截/login资源
    14. registry.addInterceptor(loginCheckInterceptor).addPathPatterns("/**").excludePathPatterns("/login");
    15. }
    16. }

    三、总结

    1. Filter是Servlet API中的一种组件,它可以在HTTP请求到达Servlet之前或之后对请求进行处理。Filter可以实现一些常见的功能,例如身份验证、授权、数据压缩、缓存等。Filter通常是单例的,并且可以在整个应用程序中共享。
    2. Interceptor是Spring MVC框架中的一种组件,它可以在Controller方法执行之前或之后对请求进行处理。Interceptor可以实现一些常见的功能,例如请求参数验证、日志记录、统计请求次数等。Interceptor通常是基于注解的,可以在Controller方法上使用注解来标识需要拦截的方法。

     

  • 相关阅读:
    vue中如何在自定义组件上使用v-model和.sync
    【操作系统】存储器管理:对换
    c# --- 修饰符
    2023.10.20期中考核复现(misc)
    文献|敬畏这种情绪,居然可以让世界变得更美好
    Tensorflow1架构内核和学习方法论
    Springboot 如何在连接池未加载前从AWS,Azure等云上获取数据库密码
    FFmpeg开发笔记(二十四)Linux环境给FFmpeg集成AV1的编解码器
    Python高级篇(08):生成器
    redis的原理和源码-客户端结构体的介绍和源码解析
  • 原文地址:https://blog.csdn.net/m0_62785037/article/details/133093495