SpringBoot之HandlerInterceptorAdapter
在SpringBoot中我们可以使⽤HandlerInterceptorAdapter这个适配器来实现⾃⼰的。这样就可以拦截所有的请求并做相应的处理。
应⽤场景
⽇志记录,可以记录请求信息的⽇志,以便进⾏信息监控、信息统计等。
权限检查:如登陆检测,进⼊处理器检测是否登陆,如果没有直接返回到登陆页⾯。
性能监控:典型的是慢⽇志。
在HandlerInterceptorAdapter中主要提供了以下的⽅法:
preHandle:在⽅法被调⽤前执⾏。在该⽅法中可以做类似校验的功能。如果返回true,则继续调⽤下⼀个。如果返回false,则中断执⾏,也就是说我们想调⽤的⽅法不会被执⾏,但是你可以修改response为你想要的响应。
postHandle:在⽅法执⾏后调⽤。
afterCompletion:在整个请求处理完毕后进⾏回调,也就是说视图渲染完毕或者调⽤⽅已经拿到响应。
在HandlerInterceptorAdapter中主要提供了以下的⽅法:
preHandle:在⽅法被调⽤前执⾏。在该⽅法中可以做类似校验的功能。如果返回true,则继续调⽤下⼀个。如果返回false,则中断执⾏,也就是说我们想调⽤的⽅法不会被执⾏,但是你可以修改response为你想要的响应。
postHandle:在⽅法执⾏后调⽤。
afterCompletion:在整个请求处理完毕后进⾏回调,也就是说视图渲染完毕或者调⽤⽅已经拿到响应。
HandlerInterceptor
适配器HandlerInterceptorAdapter
public abstract class HandlerInterceptorAdapter implements AsyncHandlerInterceptor {
/**
* This implementation always returns {@code true}.
*/
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler)
throws Exception {
return true;
}
/**
* This implementation is empty.
*/
@Override
public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler,
@Nullable ModelAndView modelAndView) throws Exception {
}
/**
* This implementation is empty.
*/
@Override
public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler,
@Nullable Exception ex) throws Exception {
}
/**
* This implementation is empty.
*/
@Override
public void afterConcurrentHandlingStarted(HttpServletRequest request, HttpServletResponse response,
Object handler) throws Exception {
}
}
有时候我们可能只需要实现三个回调⽅法中的某⼀个,如果实现HandlerInterceptor接⼝的话,三个⽅法必须实现,不管你需不需要,此时spring提供了⼀个HandlerInterceptorAdapter适配器(种适配器设计模式的实现),允许我们只实现需要的回调⽅法。
这样在我们业务中⽐如要记录系统⽇志,⽇志肯定是在afterCompletion之后记录的,否则中途失败了,也记录了,那就扯淡了。⼀定是程序正常跑完后,我们记录下那些对数据库做个增删改的操作⽇志进数据库。所以我们只需要继承HandlerInterceptorAdapter,并重写afterCompletion⼀个⽅法即可,因为preHandle默认是true。
运⾏流程总结如下:
1. 执⾏顺序是按照Spring配置⽂件中定义的顺序⽽定的。
2. 会先按照顺序执⾏所有的preHandle⽅法,⼀直遇到return false为⽌,⽐如第⼆个preHandle⽅法是return false,则第三个以及
以后所有都不会执⾏。若都是return true,则按顺序加载完preHandle⽅法。
3. 然后执⾏主⽅法(⾃⼰的controller接⼝),若中间抛出异常,则跟return false效果⼀致,不会继续执⾏postHandle,只会倒序执⾏
afterCompletion⽅法。
4. 在主⽅法执⾏完业务逻辑(页⾯还未渲染数据)时,按倒序执⾏postHandle⽅法。若第三个的preHandle⽅法return false,则会
执⾏第⼆个和第⼀个的postHandle⽅法和afterCompletion(postHandle都执⾏完才会执⾏这个,也就是页⾯渲染完数据后,执⾏after 进⾏清理⼯作)⽅法。(postHandle和afterCompletion都是倒序执⾏)
下⾯⽤⼀个demo来演⽰执⾏流程
定义⼀个类继承HandlerInterceptorAdapter,并重写⽅法
快捷键ctrl+o打开可以重写的⽅法⾯板选择
fig;
import org.springframework.web.servlet.ModelAndView;
import org.springframework.web.servlet.handler.HandlerInterceptorAdapter;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
public class LogInterceptor extends HandlerInterceptorAdapter {
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
return true;
}
@Override
public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
}
@Override
public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
}
}
WebMvcConfigurerAdapter 抽象类是对WebMvcConfigurer接⼝的简单抽象(增加了⼀些默认实现),但在在SpringBoot2.0及Spring5.0中WebMvcConfigurerAdapter已被废弃。官⽅推荐直接实现WebMvcConfigurer或者直接继承WebMvcConfigurationSupport
实现WebMvcConfigurer配置
fig;
import t.annotation.Configuration;
import org.springframework.fig.annotation.InterceptorRegistry;
import org.springframework.fig.annotation.WebMvcConfigurer;
@Configuration
public class WebConfig implements WebMvcConfigurer {
@Override
public void addInterceptors(InterceptorRegistry registry) {
registry.addInterceptor(new LogInterceptor());
}
}
在控制器中写⼀个⽅法并访问
@ApiOperation(value = "test mybatis", notes = "")
@RequestMapping(value = "getuser", method = RequestMethod.GET)
public User getUser() {
User();
}
会在控制台输出
此时在加⼊⼀个,会按照配置的顺序执⾏,配置如下
springboot和过滤器fig;
import t.annotation.Configuration;
import org.springframework.fig.annotation.InterceptorRegistry;
import org.springframework.fig.annotation.WebMvcConfigurer;
@Configuration
public class WebConfig implements WebMvcConfigurer {
@Override
public void addInterceptors(InterceptorRegistry registry) {
registry.addInterceptor(new LogInterceptor());
registry.addInterceptor(new LogInterceptor2());
}
}
控制的输出反映了配置多个的执⾏流程:
如果controller出现异常,则不会继续执⾏postHandle,只会倒序执⾏afterCompletion⽅法
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。
发表评论