Interceptor is a component in Spring MVC. It can do some operations before entering the request method, or after requesting the method and rendering the view.
Definition of interceptor
The interceptor of spring MVC only needs to implement the HandlerInterceptor interface and configure it. The HandlerInterceptor interface is defined as follows:
public interface HandlerInterceptor { default boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception { return true; } default void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, @Nullable ModelAndView modelAndView) throws Exception { } default void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, @Nullable Exception ex) throws Exception { } }
There are three methods in HandlerInterceptor. The meaning of each method is as follows:
preHandler: execute before entering the request method;
postHandler: execute after the request method is executed;
After completion: executed after the view is rendered.
Execution process of interceptor
In the preHandle method, its return value is of boolean type. Its return value affects the request method, as well as the execution of postHandle and afterCompletion. The details are as follows.
In other words, if false is returned in the preHandle, the subsequent processes will not be executed, which may also be the origin of the interceptor's name.
Test interceptor
Write a simple interceptor with the following code:
@Slf4j public class TestInterceptor implements HandlerInterceptor { @Override public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception { log.info("preHandler"); return true; } @Override public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception { log.info("postHandler"); } @Override public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception { log.info("afterCompletion"); } }
A listener class of TestInterceptor is created, which implements all interfaces of HandlerInterceptor. After writing TestInterceptor, you also need to register. The code is as follows:
@Configuration public class InterceptorConfig implements WebMvcConfigurer { @Override public void addInterceptors(InterceptorRegistry registry) { registry.addInterceptor(testInterceptor()); }
Then write a simple request method. The code is as follows:
@GetMapping("test") public String test() { return "test"; }
To start our project and access it. The console output is as follows:
2021-05-05 16:02:08.110 INFO 88509 --- [nio-8081-exec-6] com.example.demo.TestInterceptor : preHandler 2021-05-05 16:02:08.111 INFO 88509 --- [nio-8081-exec-6] com.example.demo.TestInterceptor : postHandler 2021-05-05 16:02:08.111 INFO 88509 --- [nio-8081-exec-6] com.example.demo.TestInterceptor : afterCompletion
Execution sequence of multiple interceptors
Let's write several of the same listeners, namely TestInterceptor, TestInterceptor2 and TestInterceptor3. Then we register, and the registration code is as follows:
@Override public void addInterceptors(InterceptorRegistry registry) { registry.addInterceptor(testInterceptor()); registry.addInterceptor(testInterceptor2()); registry.addInterceptor(testInterceptor3()); }
Request our method, and the output is as follows:
2021-05-05 16:09:57.735 INFO 88572 --- [nio-8081-exec-1] com.example.demo.TestInterceptor : preHandler 2021-05-05 16:09:57.736 INFO 88572 --- [nio-8081-exec-1] com.example.demo.TestInterceptor2 : preHandler2 2021-05-05 16:09:57.736 INFO 88572 --- [nio-8081-exec-1] com.example.demo.TestInterceptor3 : preHandler3 2021-05-05 16:09:57.755 INFO 88572 --- [nio-8081-exec-1] com.example.demo.TestInterceptor3 : postHandler3 2021-05-05 16:09:57.755 INFO 88572 --- [nio-8081-exec-1] com.example.demo.TestInterceptor2 : postHandler2 2021-05-05 16:09:57.755 INFO 88572 --- [nio-8081-exec-1] com.example.demo.TestInterceptor : postHandler 2021-05-05 16:09:57.755 INFO 88572 --- [nio-8081-exec-1] com.example.demo.TestInterceptor3 : afterCompletion3 2021-05-05 16:09:57.755 INFO 88572 --- [nio-8081-exec-1] com.example.demo.TestInterceptor2 : afterCompletion2 2021-05-05 16:09:57.755 INFO 88572 --- [nio-8081-exec-1] com.example.demo.TestInterceptor : afterCompletion
Note the order of output. The preHandle method is executed in the registration order, while the postHandle and afterCompletion are in the opposite order.
Let preHandle intercept
Let's make the return value of the preHandle of TestInterceptor2 false, and then look at the output.
2021-05-05 16:14:00.997 INFO 88582 --- [nio-8081-exec-1] com.example.demo.TestInterceptor : preHandler 2021-05-05 16:14:00.998 INFO 88582 --- [nio-8081-exec-1] com.example.demo.TestInterceptor2 : preHandler2 2021-05-05 16:14:00.998 INFO 88582 --- [nio-8081-exec-1] com.example.demo.TestInterceptor : afterCompletion
You can see that after the return value of the preHandle of TestInterceptor2 is false, it is equivalent to that the subsequent process of the preHandle of TestInterceptor2 will not continue.
Let's adjust the registration order. The code is as follows:
@Override public void addInterceptors(InterceptorRegistry registry) { registry.addInterceptor(testInterceptor2()); registry.addInterceptor(testInterceptor()); registry.addInterceptor(testInterceptor3()); }
The output after modifying the sequence is as follows:
2021-05-05 16:17:23.956 INFO 88589 --- [nio-8081-exec-1] com.example.demo.TestInterceptor2 : preHandler2
You can see that the processes behind it have been intercepted and have no chance to execute.
summary
Interceptors are saved using a List. We can add multiple interceptors to the project to complete different functions, such as Token verification, permission acquisition, etc. We can put it into different interceptors for related operations.