• Java中过滤器与拦截器的使用


    目录

    Filter过滤器

    Filter作用时机

    Filter的使用

    过滤器链

    过滤器执行顺序

    测试

    Filter实现简单登陆验证

    Interceptor拦截器

    Interceptor的使用

    Interceptor的拦截路径

    Interceptor执行时机

    Interceptor实现登录验证

    Filter与Interceptor区别


    Filter过滤器

    Filter是JavaWeb三大组件(Servlet、Filter、Listener)之一。可以把对资源的请求拦截下来,从而实现一些特殊的功能。

    过滤器一般完成一些通用的操作,比如:登录校验、统一编码处理、敏感字符处理等。

    Filter作用时机

    Filter的使用

    首先在自己的Filter类上添加@WebFilter注解

    也需要在引导类上添加@ServletComponentScan注解(因为Filter不是SpringBoot的组件)

    1. @WebFilter("/*")
    2. public class DemoFilter implements Filter {
    3. @Override
    4. public void init(FilterConfig filterConfig) throws ServletException {
    5. System.out.println("初始化方法,只会执行一次");
    6. }
    7. @Override
    8. public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
    9. System.out.println("所有的请求都需要执行一次该方法");
    10. //放行
    11. chain.doFilter(request,response);
    12. System.out.println("Controller执行完毕返回Filter");
    13. }
    14. @Override
    15. public void destroy() {
    16. System.out.println("销毁方法,也只执行一次");
    17. }
    18. }
    1. @RestController
    2. @RequestMapping("/user")
    3. public class UserController {
    4. @RequestMapping("login")
    5. public void login(){
    6. System.out.println("进行了登录验证");
    7. }
    8. }

    启动服务器,浏览器访问localhost:8080/user/login地址观察控制台输出

    过滤器链

    当一个Web服务存在多个过滤器时,会形成一个过滤器链

    过滤器执行顺序

    过滤器执行顺序根据字符串的自然排序来执行,即由A到Z的顺序。

    测试

    现在创建A、B两个过滤器

    1. @WebFilter("/*")
    2. public class AFilter implements Filter {
    3. @Override
    4. public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
    5. System.out.println("执行A过滤器放行前方法");
    6. chain.doFilter(request, response);
    7. System.out.println("执行A过滤器放行后方法");
    8. }
    9. }
    1. @WebFilter("/*")
    2. public class BFilter implements Filter {
    3. @Override
    4. public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
    5. System.out.println("执行B过滤器放行前方法");
    6. chain.doFilter(request, response);
    7. System.out.println("执行B过滤器放行后方法");
    8. }
    9. }

    运行访问请求地址观察控制台输出 

    Filter实现简单登陆验证

    1. @RestController
    2. @RequestMapping("/user")
    3. public class UserController {
    4. @RequestMapping("login")
    5. public void login(HttpServletRequest request){
    6. request.getSession().setAttribute("token","ok");
    7. System.out.println("进行了登录验证");
    8. }
    9. @RequestMapping("/query")
    10. public void query(){
    11. System.out.println("查询成功");
    12. }
    13. }
    1. @WebFilter("/*")
    2. public class DemoFilter implements Filter {
    3. @Override
    4. public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
    5. HttpServletRequest req = (HttpServletRequest) request;
    6. HttpServletResponse res = (HttpServletResponse) response;
    7. String uri = req.getRequestURI();
    8. System.out.println(uri);
    9. //如果是登录请求则放行
    10. if (uri.contains("login")) {
    11. chain.doFilter(request, response);
    12. return;
    13. }
    14. Object token = req.getSession().getAttribute("token");
    15. if (token == null) {
    16. System.out.println("还没有进行登录");
    17. return;
    18. }
    19. if (token.equals("ok")) {
    20. //已经登陆成功 放行
    21. chain.doFilter(request, response);
    22. }
    23. }
    24. }

    先访问/user/query路径观察控制台输出

    登陆后再次访问观察输出。

    Interceptor拦截器

    Interceptor是Spring提供的,用来动态拦截Controller的方法执行。

    作用是拦截请求,在指定的方法调用前后,根据业务需要执行预先设定的代码。

    Interceptor的使用

    在拦截器类上添加注解@Component并实现HandlerInterceptor接口。

    1. @Component
    2. public class LoginInterceptor implements HandlerInterceptor {
    3. @Override
    4. public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
    5. System.out.println("目标资源方法执行前执行。放行返回true,不放行返回false");
    6. return true;
    7. }
    8. @Override
    9. public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
    10. System.out.println("目标资源方法执行后执行");
    11. }
    12. @Override
    13. public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
    14. System.out.println("视图渲染完毕后执行");
    15. }
    16. }

    我们除了定义拦截器类之外,还需要将拦截器注册到Spring中。添加一个配置类

    1. @Configuration
    2. public class WebConfig implements WebMvcConfigurer {
    3. @Autowired
    4. private LoginInterceptor loginInterceptor;
    5. @Override
    6. public void addInterceptors(InterceptorRegistry registry) {
    7. //注册拦截器
    8. registry.addInterceptor(loginInterceptor).addPathPatterns("/**");
    9. }
    10. }

    访问/user/query路径观察控制台输出

    Interceptor的拦截路径

    与过滤器有一个不同就是

    • /*:只能拦截一级路径意思是只能拦截/user而不能拦截/user/query
    • /**:拦截任意路径

    在注册时除了可以配置拦截路径外还可以配置排除拦截路径

    Interceptor执行时机

    Interceptor实现登录验证

    我们在配置里设置了排除对登录请求路径的拦截,那么在拦截器中只需要在执行Controller其他方法之前查询是否登录过即可

    1. @Component
    2. public class LoginInterceptor implements HandlerInterceptor {
    3. @Override
    4. public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
    5. String uri = request.getRequestURI();
    6. System.out.println(uri);
    7. Object token = request.getSession().getAttribute("token");
    8. if (token == null) {
    9. System.out.println("还没有进行登录");
    10. return false;
    11. }
    12. return true;
    13. }
    14. @Override
    15. public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
    16. System.out.println("目标资源方法执行后执行");
    17. }
    18. @Override
    19. public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
    20. System.out.println("视图渲染完毕后执行");
    21. }
    22. }

    Filter与Interceptor区别

    • 过滤器需要实现的是FIlter接口,而拦截器需要实现HandlerInterceptor接口
    • 过滤器会拦截所有的请求路径。而拦截器只会拦截Spring中存在的请求路径
  • 相关阅读:
    SpringBoot(一、快速入门)
    【工具使用】在vscode中用python绘图
    剑指 Offer 45. 把数组排成最小的数
    tensorflow2.x:构建tf.keras.Model实例的几种方式
    qt作业day4
    gorm操作数组
    数据要素价值:在数字时代的血脉中流淌
    TorchScript 解读(三):jit 中的 subgraph rewriter
    Vulnhub系列靶机-Hackadmeic.RTB1
    2022亚太杯C题思路代码分析
  • 原文地址:https://blog.csdn.net/zmbwcx/article/details/133932965