Spring MVC interceptor

Important: The Spring MVC interceptor will only intercept requests from the controller, if they are JSP, JS, image, or HTML.

What is an interceptor

A program running on the server implements the interception of the requested resource by running before the Servlet or JSP, intercepting one or more servlets or JSPS, checking the request information before the Servlet or JSP, and processing the response information.

What is a SpringMVC interceptor

Spring MVC’s unique interceptor intercepts Controller requests according to the interception rules defined in the Spring MVC configuration file. JSP, JS, image, HTML will not be intercepted if requested (this does not conflict with the scope intercepted by the Web-configured DispatcherServlet)

Use the SpringMVC interceptor

Create a SpringMVC interceptor

Using Spring MVC results in only one Servlet (DispatcherServlet), so the interceptor sits between DispatchServlet and Controller in the physical model. There are two main ways to implement the Spring MVC interceptor, and I’ll show you just one of them for understanding the Spring MVC interceptor.

Implement the HandlerInterceptor interface

The HandlerInterceptor interface is one of the interceptor interfaces provided by Spring MVC, so let’s implement a Spring MVC interceptor:

MyInterceptor:
// Define interceptors to intercept requests
public class MyIntercept implements HandlerInterceptor {
    // dependency injection
    @Autowired
    private MyController controller;

    /** * preHandle: executed before the DispatcherServlet request unit method executes and determines whether to permit the DispatcherServlet request unit method based on its return value. * * Calling the current unit method with the HandlerMethod object executes only the method body, but does not return the object of the unit method's ModelAndView. You can get the HttpServletRequest, HttpServletResponse object * to redirect or forward the page * * *@paramHttpServletRequest httpServletRequest * delivered by the DispatcherServlet@paramHttpServletResponse The httpServletResponse * delivered by the DispatcherServlet@paramO This is called HandlerMethod, which is another way of reflecting, and stores the method object of the unit method *@returnAllow */
    @Override
    public boolean preHandle(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o) throws Exception {
        System.out.println(o instanceof HandlerMethod);
        HandlerMethod hm = (HandlerMethod) o;
        Method method = hm.getMethod();
        method.invoke(controller,httpServletResponse);
        return false;
    }

    @Override
    public void postHandle(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o, ModelAndView modelAndView) throws Exception {
        System.out.println("MyIntercept.postHandle");

    }

    @Override
    public void afterCompletion(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o, Exception e) throws Exception {
        System.out.println("MyIntercept.afterCompletion"); }}Copy the code

Based on the code above, we can see that the interface provides three methods:

  • PreHandles: Executes before a cell method executes.
  • PostHandle: Executed after calling the method before parsing the view.
  • AfterCompletion: After the view is rendered, the entire request is complete.

In fact, the action segments of these three methods are easy to understand.

PreHandle: The DispatcherServlet calls the unit method in the Controller based on the request. If the interceptor intercepts the request, it calls the preHandle method in MyInterceptor first. In this method, it determines whether to release the request. If not, return false. This Object is HandlerMethod. My understanding is that regardless of whether the request is blocked or not, our users will always get a result. Therefore, if the request is not allowed for other reasons, but the result is obtained in the unit Method, in this case, we can use the HandlerMethod object to get the Method object and then reflect and call the unit Method to get the result and respond to the user.

PostHandle: If the request is released, the unit method is called, and when the method body completes execution and returns the ModelAndView to the view parser, it goes into postHandle for request and model data modification (if needed). After execution, the modified ModelAndView is handed to the view parser for parsing and rendering the view. Why do I need to pass in ModelAndView? There may be times when we need to further fine-tune data or views, such as sensitive terms in a fixed period of time that may not be processed in the unit method, so we will do the data processing in this method.

AfterCompletion: This method is called after the view has been rendered and is used to close resources, such as I/O streams or exception handling.

We need to configure our interceptors in the Spring MVC configuration file, which is the next configuration file:

 <context:component-scan base-package="com.lyl.controller"/>

    <mvc:annotation-driven/>

    <mvc:resources mapping="/js/**" location="/js/"/>
    <mvc:resources mapping="/img/**" location="/img/"/>
    <mvc:resources mapping="/css/**" location="/css/"/>
    <! -- Configure interceptor -->
    <mvc:interceptors>
        <! Configure global interceptor to block all requests
        <bean id="all" class="com.lyl.intercept.AllIntercept"/>
        <! You can configure multiple interceptors, declare their interceptor scope, and define interceptors.
        <mvc:interceptor>
            <! -- Set interceptor range -->
            <mvc:mapping path="/demo"/>
            <! Configure the interceptor bean object -->
            <bean id="my1" class="com.lyl.intercept.MyIntercept"/>
        </mvc:interceptor>
        
        <mvc:interceptor>
            <! -- Set interceptor range -->
            <mvc:mapping path="/demo1"/>
            <mvc:mapping path="/demo2"/>
            <mvc:mapping path="/my/*"/> <! -- * Identified as a wildcard -->
            <! Configure the interceptor bean object -->
            <bean id="my1" class="com.lyl.intercept.MyIntercept"/>
        </mvc:interceptor>
        <! Interceptors can be nested, and the order of interceptors can be different. Consider interceptors to be executed around the notification, and the method body is generated from below.
    </mvc:interceptors>
Copy the code