1. Overview
Interceptors are used more and more, especially after the popularity of slice programming. So what can an interceptor usually do?
In our introduction to Agent, we mentioned that the call of statistical functions takes time. This idea is actually exactly the same as the surround enhancement of AOP.
Generally speaking, the scenario is as follows:
And others and so on.
2. Spring's interceptor
Whether it is SpringMVC or SpringBoot, we have to mention the interceptor:
org.springframework.web.servlet.handler.HandlerInterceptorAdapter
public abstract class HandlerInterceptorAdapter implements AsyncHandlerInterceptor { // Execute @Override public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception { return true; } // Execute after the target method is executed, but before the request returns, we can still modify the ModelAndView @Override public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {} // Execute @Override public void afterCompletion( HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {} // Used to handle asynchronous requests. This method will be triggered when there is an asynchronous request method in the Controller @Override public void afterConcurrentHandlingStarted( HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {}}Implement an interceptor for verifying simple permissions
1. Customize a permission annotation @Auth
@Inherited@Target({ElementType.TYPE, ElementType.METHOD})@Retention(RetentionPolicy.RUNTIME)@Documentedpublic @interface Auth { String user() default "";}2. Add annotations to the Controller method
After adding the annotations in the previous step, you should add relevant annotations to the method you are using, as follows.
@RestController@EnableAutoConfigurationpublic class DemoController { @Auth(user = "admin") @RequestMapping(value = "/hello", method = RequestMethod.GET) public String saysHello() { return "hello world."; }}3. Implement the interceptor function
Requirements: When the user accesses the URI through the /hello, it is verified. If it is admin, it will be released, otherwise it will be rejected. Assume that the user's identity is in the URL parameter.
Idea: Therefore, we need to verify the user before executing saysHello(). If its identity is the same as the identity in the annotation, it will be released. Therefore, we need to make a fuss in preHandle().
Difficulty: How do we get the @Auth annotation on the Controller method? Looking at the three parameters of PreHandle(), it seems that no one can provide annotations in the Controller class.
In fact, the third parameter handler, in general, its type is: org.springframework.web.method.HandlerMethod, and it contains relevant information about the annotation.
Why do you say so?
In SpringBoot, the default type of annotation is the function level, while in SpringMVC its default type is the Controller object level.
Therefore, if you need to configure it in dispatcher-servlet.xml in SpringMVC:
<bean/>, so that its type is HandlerMethod.
Let's look at the specific implementation logic:
@Override public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception { System.out.println("preHandle"); if (!handler.getClass().isAssignableFrom(HandlerMethod.class)) { System.out.println("cat cast handler to HandlerMethod.class"); return true; } // Get annotation Auth auth = ((HandlerMethod) handler).getMethod().getAnnotation(Auth.class); if (auth == null) { System.out.println("cant find @Auth in this uri:" + request.getRequestURI()); return true; } // Take out the user's identity from the parameters and verify String admin = auth.user(); if (!admin.equals(request.getParameter("user"))) { System.out.println("permission denied"); response.setStatus(403); return false; } return true; }In fact, there are two points in the implementation logic: take out the identity from the parameters and compare it with the annotation.
4. Configure the interceptor
So how can the interceptor just now be effective?
At this time, we need to configure: WebMvcConfigurerAdapter
The specific implementation is as follows:
@Configurationpublic class ConfigAdapter extends WebMvcConfigurerAdapter { @Override public void addInterceptors(InterceptorRegistry registry) { registry.addInterceptor(new LoginInterceptor()).addPathPatterns("/hello"); }}Note: There are two points to note here. One is the @Configuration annotation, so that the SpringBoot service can discover this configuration; the other is the configuration match, which is to intercept the "/hello". ("/**" is to block all accesses)
4. Operation
Visit http://127.0.0.1:8080/hello?user=admin to see the results.
For details of the code in this article, please refer to: https://github.com/hawkingfoo/springboot-interceptor
The above is all the content of this article. I hope it will be helpful to everyone's learning and I hope everyone will support Wulin.com more.