当前位置: 移动技术网 > IT编程>开发语言>Java > 玩转 SpringBoot 2 快速整合拦截器

玩转 SpringBoot 2 快速整合拦截器

2019年10月04日  | 移动技术网IT编程  | 我要评论
概述 首先声明一下,这里所说的拦截器是 SpringMVC 的拦截器 HandlerInterceptor。使用SpringMVC 拦截器需要做如下操作: 1. 创建拦截器类需要实现 HandlerInterceptor 2. 在 xml 配置文件中配置该拦截器,具体配置代码如下: 因为在Sprin ...

概述

首先声明一下,这里所说的拦截器是 springmvc 的拦截器 handlerinterceptor。使用springmvc 拦截器需要做如下操作:

  1. 创建拦截器类需要实现 handlerinterceptor
  2. 在 xml 配置文件中配置该拦截器,具体配置代码如下:
<mvc:interceptors>
    <mvc:interceptor>
    <!-- /test/** 这个是拦截路径以/test开头的所有的url-->
    <mvc:mapping path="/**"/><!—这个是拦截说有的路径-->
    <!-- 配置拦截器类路径-->
    <bean class="cn.ljk.springmvc.controller.myinterceptor"></bean>
    <!-- 配置不拦截器url路径-->
    <mvc:exclude-mapping path="/fore/**"/>
    </mvc:interceptor>
</mvc:interceptors>

因为在springboot 中没有 xml 文件,所以springboot 为我们提供 java config 的方式来配置拦截器。配置方式有2种:

  1. 继承 webmvcconfigureradapter (官方已经不建议使用)
  2. 实现 webmvcconfigurer

接下来开始 springboot 整合拦截器操作详细介绍!

整合拦截器实战操作

第一步:声明拦截器类

通过实现 handlerinterceptor 来完成。具体代码如下:

public class logininterceptor implements handlerinterceptor{}

第二步:实现 handlerinterceptor 3 个拦截方法

  • prehandle:controller逻辑执行之前进行拦截
  • posthandle:controller逻辑执行完毕但是视图解析器还为进行解析之前进行拦截
  • aftercompletion:controller逻辑和视图解析器执行完毕进行拦截

实际开发中 prehandle使用频率比较高,posthandle 和 aftercompletion操作相对比较少。

在下面的代码中 prehandle 方法中定义拦截所有访问项目 url并进行日志信息记录。posthandle 中在视图解析前进行拦截,通过 model 在次添加数据request域中。

aftercompletion 暂时没有想到使用场景,如果有使用过的场景可以在下面评论区中进行评论。

拦截器详细代码如下:

public class logininterceptor implements handlerinterceptor{
    
    private logger log = loggerfactory.getlogger(logininterceptor.class);
    
    //controllercontroller逻辑执行之前
    public boolean prehandle(httpservletrequest request, httpservletresponse response, object handler) throws exception {
        log.info("prehandle....");
        string uri = request.getrequesturi();
        log.info("uri:"+ uri);
        if (handler instanceof handlermethod) {
            handlermethod handlermethod = (handlermethod) handler;
            log.info("拦截 controller:"+ handlermethod.getbean().getclass().getname());
            log.info("拦截方法:"+handlermethod.getmethod().getname());
        }
        
        return true;
    }
    
    //controller逻辑执行完毕但是视图解析器还为进行解析之前
    @override
    public void posthandle(httpservletrequest httpservletrequest, httpservletresponse httpservletresponse, object o, modelandview modelandview) throws exception {
        log.info("posthandle....");
        map<string,object>map=modelandview.getmodel();
        map.put("msg","posthandle add msg");
    }
    
    //controller逻辑和视图解析器执行完毕
    @override
    public void aftercompletion(httpservletrequest httpservletrequest, httpservletresponse httpservletresponse, object o, exception e) throws exception {
        log.info("aftercompletion....");
    }
}

第三步:java config 的方式来配置拦截器

继承 webmvcconfigureradapter 方式

通过继承 webmvcconfigureradapter并重写 addinterceptors方法,通过其参数 interceptorregistry将拦截器注入到 spring的上下文中。

另外拦截路径和不拦截的路径通过interceptorregistry 的 addpathpatterns和 excludepathpatterns方法进行设置。

这种方式官方已经不建议使用,因为官方已将 webmvcconfigureradapter 标记为@deprecated 了。

@deprecated
public abstract class webmvcconfigureradapter implements webmvcconfigurer {

继承 webmvcconfigureradapter 方式具体代码如下:

@configuration
    public class interceptorconfigbyextendswebmvcconfigureradapter extends  webmvcconfigureradapter{

    @bean
        public logininterceptor logininterceptor(){
                return new logininterceptor();
        }

        public void addinterceptors(interceptorregistry registry) {
                registry.addinterceptor(logininterceptor()).addpathpatterns("/**").excludepathpatterns("/*.html");
        }
}

实现 webmvcconfigurer 方式

通过实现 webmvcconfigurer 接口并实现 addinterceptors方法,其他操作和继承 webmvcconfigureradapter方式一样。具体代码如下:

```java
@configuration
public class interceptorconfigbyimplwebmvcconfigurer implements webmvcconfigurer{
    
    @bean
    public logininterceptor logininterceptor(){
        return new logininterceptor();
    }
     @override
    public void addinterceptors(interceptorregistry registry) {
        registry.addinterceptor(logininterceptor()).addpathpatterns("/**").excludepathpatterns("/*.html");
    }
}
```

测试

编写普通controller,具体代码如下:

@controller
public class indexcontroller {
    
    @getmapping("/index")
    public string index(modelandview modelandview){
        
        return "index";
    }
}

在 src/main/resource 下的 templates目录下创建 indexcontroller访问页面 index.ftl, 代码如下:

<h1>${msg}</h1>

由于我这里使用的是 freemarker当页面使用,说以需要引入 freemarker starter依赖,具体点如下:

        <dependency>
            <groupid>org.springframework.boot</groupid>
            <artifactid>spring-boot-starter-freemarker</artifactid>
        </dependency>

通过游览器访问 localhost:8080/sbe/index,具体访问效果如下:

在这里插入图片描述

如上图所示在视图解析前通过 model在次添加数据到 request域中的msg 成功显示出来了!

日志输出信息如下:拦截地址和拦截controller 和具体方法进行日志输出

2019-09-24 15:53:04.144  info 7732 --- [nio-8080-exec-1] o.a.c.c.c.[tomcat].[localhost].[/sbe]    : initializing spring dispatcherservlet 'dispatcherservlet'
2019-09-24 15:53:04.145  info 7732 --- [nio-8080-exec-1] o.s.web.servlet.dispatcherservlet        : initializing servlet 'dispatcherservlet'
2019-09-24 15:53:04.153  info 7732 --- [nio-8080-exec-1] o.s.web.servlet.dispatcherservlet        : completed initialization in 8 ms
2019-09-24 15:53:04.155  info 7732 --- [nio-8080-exec-1] c.lijunkui.interceptor.logininterceptor  : prehandle....
2019-09-24 15:53:04.155  info 7732 --- [nio-8080-exec-1] c.lijunkui.interceptor.logininterceptor  : uri:/sbe/index
2019-09-24 15:53:04.155  info 7732 --- [nio-8080-exec-1] c.lijunkui.interceptor.logininterceptor  : 拦截 controller:cn.lijunkui.controller.indexcontroller
2019-09-24 15:53:04.155  info 7732 --- [nio-8080-exec-1] c.lijunkui.interceptor.logininterceptor  : 拦截方法:index
2019-09-24 15:53:04.156  info 7732 --- [nio-8080-exec-1] c.lijunkui.interceptor.logininterceptor  : posthandle....
2019-09-24 15:53:04.161  info 7732 --- [nio-8080-exec-1] c.lijunkui.interceptor.logininterceptor  : aftercompletion....

小结

springboot 2 整合拦截器和整合 filter的操作很像,都是通过一个注册类将其注入到spring的上下文中,只不过filter使用的是 filterregistrationbean 而 拦截器使用的是 interceptorregistry。

个人觉得比使用 xml 配置的方式更为简单了,如果你还没有在 springboot 项目中使用过拦截器,赶快来操作一下吧!

代码示例

具体代码示例请在我的github 仓库 springbootexamples 中模块名为 spring-boot-2.x-interceptor 项目中进行查看

github:https://github.com/zhuoqianmingyue/springbootexamples

如您对本文有疑问或者有任何想说的,请 点击进行留言回复,万千网友为您解惑!

相关文章:

验证码:
移动技术网