欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

【2019】Spring boot 定义配置拦截器Interceptor

程序员文章站 2022-05-23 11:22:06
...

Spring boot 配置拦截器Interceptor

最近项目中用 spring boot 结合拦截器实现部分功能需求。网上太难找相关资料,这里分享出来希望对你有用。

定义拦截器

因为是在 spring boot 中使用,这里所有的 xml 配置文件全都可以用注解来实现。

这里和 springMVC 写法是一样的,代码如下。

/**
 * Created by [email protected] on 2019/1/7
 * Description:
 */
public class MyInterceptor implements HandlerInterceptor  {
    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        System.out.println("拦截并放行");
        return true;
    }
}

WebMvcConfigurationSupport配置拦截器

配置拦截器有两种方法。继承WebMvcConfigurationSupport和实现WebMvcConfigurer

先看前者,直接上代码。

/**
 * Created by [email protected] on 2019/1/7
 * Description:
 */
@Configuration
public class MyInterceptorConfig extends WebMvcConfigurationSupport {

    @Override
    protected void addInterceptors(InterceptorRegistry registry) {
        super.addInterceptors(registry);
        registry.addInterceptor(new MyInterceptor()).addPathPatterns("/**");
    }
}

添加Configuration注解。然后添加拦截规则,如上我假设拦截所有路径。随便写个接口测试下,拦截是否生效。

@RequestMapping("/getPerson")
    public String getPerson(){
        return configData.getName()+" "+configData.getAge()+" "+configData.getAdress();
    }

算了,太简单,这里不贴图。是生效的 已经测试。

最后还剩下静态资源的处理,其实我都不想写。前后端分离是趋势,在将静态资源放到 Java 这边不是明智的选择。但是以防万一,还是将处理的方法贴出来,平时直接复制使用就是了。

spring boot 的静态资源都在resources/static/下面,不管是 .js .css .img都是在这。所以需要将这个位置下的文件排除在外。

在 config 类中重写如下方法,添加如下配置。

    @Override
    protected void addResourceHandlers(ResourceHandlerRegistry registry) {
        registry.addResourceHandler("/**").addResourceLocations("classpath:/static/");
        super.addResourceHandlers(registry);
    }

可以用图片测试下,放张图片在里面,然后在浏览器上输入地址访问,对比前后能不能请求到。

WebMvcConfigurer配置拦截器

实现它完成配置,是天生带了排除静态资源。所以要想一劳永逸,建议使用这种办法。

/**
 * Created by [email protected] on 2019/1/7
 * Description:
 */
@Configuration
public class MyInterceptorConfig2 implements WebMvcConfigurer {

    @Override
    public void addInterceptors(InterceptorRegistry registry) {
        registry.addInterceptor(new MyInterceptor()).addPathPatterns("/**");
    }
}

排除部分地址URL

大部分情况下我们都是采取拦截所有地址,规则如上/**,但是不可能真的所有拦截,至少有一两个地址是“不能”拦截的,需要放开的。

处理方案有很多,比较「低级」的就别讲究直接在拦截器方法中通过 request获取到请求地址,然后判断,如果符合直接返回true

request.getServletPath()

成熟点的处理方案就是通过注解。其实原理是一样的,我直接上代码。

/**
 * 该注解用来指定某个方法不用拦截
 */
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface UnInterception {
}

然后在 Controller 中的某个方法上添加该注解,在拦截器处理方法中添加该注解取消拦截的逻辑,如下:

@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {

    HandlerMethod handlerMethod = (HandlerMethod) handler;
    Method method = handlerMethod.getMethod();
    String methodName = method.getName();
    logger.info("====拦截到了方法:{},在该方法执行之前执行====", methodName);

    // 通过方法,可以获取该方法上的自定义注解,然后通过注解来判断该方法是否要被拦截
    // @UnInterception 是我们自定义的注解
    UnInterception unInterception = method.getAnnotation(UnInterception.class);
    if (null != unInterception) {
        return true;
    }
    // 返回true才会继续执行,返回false则取消当前请求
    return true;
}

拦截器中使用Autowired

这点很重要,以前总结过点这

Thx

https://gitbook.cn/gitchat/column/5b3c9f35a3442272491a176a/topic/5b47fa3efa56195ed488acfc

https://my.oschina.net/dengfuwei/blog/1795346

本来还有过滤器,合起来太长另开一篇吧

原创