【接口篇】SpringBoot 过滤器与拦截器的浅入浅出

导读:本篇文章讲解 【接口篇】SpringBoot 过滤器与拦截器的浅入浅出,希望对大家有帮助,欢迎收藏,转发!站点地址:www.bmabk.com

过滤器(Filter)

过滤器主要用于对用户请求进行预处理,也可以对响应进行后处理。例如:敏感词处理,在过滤器中定义了一些敏感词,请求内容包含这些敏感词的直接禁止访问。

过滤器应用场景

  • 过滤黑名单
  • 过滤敏感词汇
  • 设置字符编码,对非标准编码的请求解码
  • 压缩响应信息

拦截器(Interceptor)

拦截器是一种面向方面/切面编程(AOP Aspect-Oriented Programming),而面向切面就是将多个模块的通用服务进行分离,如权限管理、日志服务,这些通用服务的具体实现是通过拦截器来完成。就是在不侵入业务代码的情况下,你可以对业务代码做点你想做的事,干预业务代码的执行,甚至终止它进行!

拦截器应用场景

  • 登录验证
  • 权限验证
  • 日志记录

过滤器与拦截器的区别

  • 过滤器是基于函数回调的(职责链),而拦截器则是基于 Java 反射的;
  • 过滤器依赖于 Servlet 容器,而拦截器不依赖于 Servlet 容器;
  • 过滤器对几乎所有的请求起作用,而拦截器只能对 Action 请求起作用;
  • 拦截器可以访问 Action 的上下文,值栈里的对象,而过滤器不能;
  • 在 Action 的生命周期里,拦截器可以被多次调用,而过滤器只能在容器初始化时调用一次。

执行顺序

过滤前 -> 拦截前 -> 业务 -> 拦截后 -> 请求与响应完成 -> 过滤后

INFO 4744 --- [nio-8080-exec-1] c.c.m.f.filter.MingYueIpWordFilter       : 过滤前
INFO 4744 --- [nio-8080-exec-1] c.c.m.f.interceptor.LogInterceptor       : 拦截前
INFO 4744 --- [nio-8080-exec-1] c.c.m.f.interceptor.LogInterceptor       : 拦截后
INFO 4744 --- [nio-8080-exec-1] c.c.m.f.interceptor.LogInterceptor       : 请求与响应完成
INFO 4744 --- [nio-8080-exec-1] c.c.m.f.filter.MingYueIpWordFilter       : 过滤后

SpringBoot 过滤器使用

Demo 地址mingyue-springboot-filter-interceptor

需求:过滤 localhost/127.0.0.1 ip 的请求。

1.编写过滤器

import java.io.IOException;
import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;

/**
 * Ip过滤器
 *
 * @author Strive
 */
@Slf4j
@Component
public class MingYueIpWordFilter implements Filter {
  @Override
  public void doFilter(ServletRequest request, ServletResponse response, FilterChain filterChain)
      throws IOException, ServletException {
    /*
     * 0:0:0:0:0:0:0:1 是 ipv6 的表现形式,对应 ipv4 来说相当于 127.0.0.1,也就是本机
     * 禁止使用 127.0.0.1 / localhost 访问
     * 这里 ip 可以换成动态黑名单 ip
     */
    if ("0:0:0:0:0:0:0:1".equals(request.getRemoteHost())
        || "127.0.0.1".equals(request.getRemoteHost())) {
      response.getWriter().append("Not Allowed Ip!");
      log.info("Not Allowed Ip:{}!", request.getRemoteHost());
    } else {
      filterChain.doFilter(request, response);
    }
  }
}

2.编写接口

@ApiOperation("根据用户ID查询用户信息")
@GetMapping("/{userId}")
public ResponseEntity<MingYueUser> queryUserById(@PathVariable Long userId) {
    return ResponseEntity.ok(mingYueUserService.queryUserById(userId));
}

3.请求接口

访问:http://127.0.0.1:8080/user/1

# 日志打印如下
c.c.m.f.filter.MingYueIpWordFilter       : Not Allowed Ip:127.0.0.1!

SpringBoot 拦截器使用

Demo 地址mingyue-springboot-filter-interceptor

1.编写拦截器

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;

/**
 * 日志拦截器
 *
 * @author csp73
 */
@Slf4j
public class LogInterceptor implements HandlerInterceptor {
  @Override
  public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler)
      throws Exception {
    log.info("拦截前");
    log.info("request " + request.getServletPath() + " api into");
    return HandlerInterceptor.super.preHandle(request, response, handler);
  }

  @Override
  public void postHandle(
      HttpServletRequest request,
      HttpServletResponse response,
      Object handler,
      ModelAndView modelAndView)
      throws Exception {
    log.info("拦截后");
    log.info("request " + request.getServletPath() + " api start");
    HandlerInterceptor.super.postHandle(request, response, handler, modelAndView);
  }

  @Override
  public void afterCompletion(
      HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex)
      throws Exception {
    log.info("请求与响应完成");
    log.info("request " + request.getServletPath() + " api end");
    HandlerInterceptor.super.afterCompletion(request, response, handler, ex);
  }
}

2.注册拦截器

import com.csp.mingyue.filterAndInterceptor.interceptor.LogInterceptor;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;

/**
 * Web配置
 *
 * @author Strive
 */
@Configuration
public class WebMvcConfig implements WebMvcConfigurer {

  @Override
  public void addInterceptors(InterceptorRegistry registry) {
    // 将日志拦截器注册到拦截器注册表
    registry.addInterceptor(new LogInterceptor()).addPathPatterns("/**");
  }
}

3.请求接口

访问:http://127.0.0.1:8080/user/1

# 日志打印如下
INFO 19136 --- [nio-8080-exec-2] c.c.m.f.filter.MingYueIpWordFilter       : 过滤前
INFO 19136 --- [nio-8080-exec-2] c.c.m.f.interceptor.LogInterceptor       : 拦截前
INFO 19136 --- [nio-8080-exec-2] c.c.m.f.interceptor.LogInterceptor       : preHandle request /user/1 api into
INFO 19136 --- [nio-8080-exec-2] c.c.m.f.interceptor.LogInterceptor       : 拦截后
INFO 19136 --- [nio-8080-exec-2] c.c.m.f.interceptor.LogInterceptor       : postHandle request /user/1 api start
INFO 19136 --- [nio-8080-exec-2] c.c.m.f.interceptor.LogInterceptor       : 请求与响应完成
INFO 19136 --- [nio-8080-exec-2] c.c.m.f.interceptor.LogInterceptor       : afterCompletion request /user/1 api end
INFO 19136 --- [nio-8080-exec-2] c.c.m.f.filter.MingYueIpWordFilter       : 过滤后

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。

文章由极客之音整理,本文链接:https://www.bmabk.com/index.php/post/78345.html

(0)
小半的头像小半

相关推荐

极客之音——专业性很强的中文编程技术网站,欢迎收藏到浏览器,订阅我们!