Spring MVC interceptor and exception handling

Interceptor

Interceptor configuration

Interceptors in spring MVC are used to intercept the execution of controller methods.

Interceptors in spring MVC need to implement HandlerInterceptor.

package com.atguigu.springmvc.interceptor;

import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

/**
 * @version 1.0
 * @Description
 * @Author The first three poles of the month
 * @Date 2022-03-04 14:48
 **/
public class FirstInterceptor implements HandlerInterceptor {
    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        System.out.println("FirstInterceptor--->preHandle");
        return true;
    }

    @Override
    public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
        System.out.println("FirstInterceptor--->postHandle");
    }

    @Override
    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
        System.out.println("FirstInterceptor--->afterCompletion");
    }
}

The interceptor of spring MVC must be configured in the configuration file in spring MVC.

First configuration

<mvc:interceptors>
    <bean class="com.atguigu.springmvc.interceptor.FirstInterceptor"></bean>
</mvc:interceptors>

Second configuration

<mvc:interceptors>
<bean class="com.atguigu.springmvc.interceptor.FirstInterceptor"></bean>
    <ref bean="firstInterceptor"></ref>
</mvc:interceptors>

Third configuration

<mvc:interceptors>
    <mvc:interceptor>
    	<mvc:mapping path="/**"/>
    	<mvc:exclude-mapping path="/"/>
        <ref bean="firstInterceptor"></ref>
    </mvc:interceptor>
</mvc:interceptors>

In the above configuration methods, you can set interceptors through bean s or ref tags, set requests to be intercepted through mvc:mapping, and set requests to be excluded through MVC: exclude mapping, that is, requests that do not need to be intercepted.

Three abstract methods in interceptor

Interceptors in spring MVC have three abstract methods:

  1. preHandle: execute preHandle() before the controller method is executed. The return value of boolean type indicates whether to intercept or release. Return true is release, that is, call the controller method; Returning false indicates interception, that is, the controller method is not called.
  2. postHandle: execute postHandle() after the controller method is executed.
  3. Aftercompilation: after processing the view and model data, execute aftercompilation () after rendering the view.

DispatcherServlet source code

Execution sequence of multiple interceptors

If the preHandle() of each interceptor returns true, the execution order of multiple interceptors is related to the configuration order of interceptors in the configuration file of spring MVC

preHandle() will execute in the order of configuration, while postHandle() and aftercompilation () will execute in the reverse order of configuration.

springMVC. Interceptor configuration in XML file:

    <mvc:interceptors>
        <ref bean="firstInterceptor"></ref>
        <ref bean="secondInterceptor"></ref>
    </mvc:interceptors>

Execution sequence of Interceptor:

Source code analysis:


Since the preHandler() of both FirstInterceptor and SecondInterceptor returns true, there are only two things to do in the applyPreHandle method in the DispatcherServlet:

  1. Gets the interceptor for the current index.
  2. Assign the index value of the current interceptor to interceptorIndex.


If the preHandle() of an interceptor returns false

When preHandle() returns false, the preHandle() of the interceptor before it will be executed, and postHandle() will not be executed. After compilation() of the interceptor before fasle will be executed.

The preHandler() of FirstInterceptor returns true, while the preHandler() of SecondInterceptor returns false:

Source code analysis:

The applyPreHandle method in the DispatcherServlet traverses the interceptorList. Since the interceptor provided by spring MVC and the preHandle() method of the FirstInterceptor interceptor interceptor we set return true, the interceptorIndex value at this time is 1. When i is 2, traverse the SecondInterceptor and its preHandle() returns false. Therefore, execute the statement in if:

Execute the triggerAfterCompletion method, and you can see that the interceptorIndex is indeed 1. After the loop is executed, the applyPreHandle method returns false.


According to the source code, when the return value of preHandle() of the interceptor is false:

  1. This interceptor and its previous interceptor's preHandle() will execute.
  2. The postHandle() of this interceptor and its previous interceptors will not be executed.
  3. After completion() before the interceptor will be executed.

Exception handler

Configuration based exception handling

Spring MVC provides an interface to handle exceptions that occur during the execution of controller methods: HandlerExceptionResolver.

The implementation classes of HandlerExceptionResolver interface include:

  • DefaultHandlerExceptionResolver (spring MVC default exception handling)
  • SimpleMappingExceptionResolver (custom exception handling)
<bean class="org.springframework.web.servlet.handler.SimpleMappingExceptionResolver">
    <property name="exceptionMappings">
        <props>
            <!--
                properties The key of represents an exception that occurs during the execution of the processor method
                properties The value of indicates that if a specified exception occurs, set a new view name and jump to the execution page
            -->
            <prop key="java.lang.ArithmeticException">error</prop>
        </props>
	</property>
    <!-- exceptionAttribute Property to set a property name and share the exception information in the request domain -->
    <property name="exceptionAttribute" value="ex"></property>
</bean>
<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head>
    <meta charset="UTF-8">
    <title>Error page</title>
</head>
<body>
    <h1>Error!!!!!</h1>
    <p th:text="${ex}"></p>
</body>
</html>

Annotation based exception handling

package com.atguigu.springmvc.controller;

import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;

/**
 * @version 1.0
 * @Description
 * @Author The first three poles of the month
 * @Date 2022-03-05 8:56
 **/
// @ControllerAdvice identifies the current class as an exception handling component
@ControllerAdvice
public class ExceptionController {
    // @ExceptionHandler is used to set the exceptions handled by the identified method
    @ExceptionHandler(value = {ArithmeticException.class,NullPointerException.class})
    public String testException(Exception ex, Model model){
        // ex represents the exception object in the current request processing
        model.addAttribute("ex",ex);
        return "error";
    }
}

Keywords: Java Spring Spring MVC mvc

Added by mancroft on Sat, 05 Mar 2022 04:19:59 +0200