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

Spring boot 配置拦截器Interceptor

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

定义拦截器

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

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

/**
 * Created by guozhaohui628@gmail.com 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 guozhaohui628@gmail.com 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 guozhaohui628@gmail.com 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

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

发表评论

电子邮件地址不会被公开。 必填项已用*标注