[springMVC] Interceptor and exception handling of SpringMVC [source code attached]

1. Interceptor

1. SpringMVC's interceptor (Interceptor)
is similar to the filter (Filter) in Servlet, which is mainly used to intercept user requests (controller methods) and make corresponding processing. For example: permission verification, judging whether the user is logged in, etc.
2. Definition of interceptor
(1) Implement the HandlerInterceptor interface;
(2) Inherit the HandlerInterceptorAdapter class.
3. Three abstract methods of the interceptor
(1) preHandle: Execute preHandle() before the controller method is executed, and its return value of boolean type indicates whether to intercept or release, return true to release, that is, call the controller method; return false to indicate Intercept, that is, do not call the controller method
(2) postHandle: execute postHandle() after the controller method is executed
(3) afterComplation: execute afterComplation() after processing the view and model data, and rendering the view
4. Execution sequence of interceptors
( 1) The execution sequence of a single interceptor
The program will first execute the preHandler() method in the interceptor class. If the return value of the method is true, it will continue to execute the method in the processor, otherwise it will not go down Execution; after the business processor (Controller class) processes the request, the postHandler() method will be executed, and then the response will be returned to the client through the DispatcherServlet; after the DispatcherServlet has processed the request, the afterCompletion() method will be executed.
insert image description here
(2) The execution order of multiple interceptors:
① If the preHandle() of each interceptor returns true
When multiple interceptors work at the same time, their preHandle() methods will be executed in the configuration order of the interceptors in the configuration file, and their postHandle and afterCompletion() methods will be executed in the reverse order of the configuration order.
② If the preHandle() of an interceptor returns false,
preHandle() returns false and the preHandle() of the interceptor before it will be executed, and postHandle() will not be executed. AfterComplation( ) will execute
5. Custom interceptor
pom.xml dependencies

<dependencies>
    <!--SpringMVC-->
    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-webmvc</artifactId>
        <version>5.3.1</version>
    </dependency>
    <!--日志-->
    <dependency>
        <groupId>ch.qos.logback</groupId>
        <artifactId>logback-classic</artifactId>
        <version>1.2.3</version>
    </dependency>
    <!--servletAPI-->
    <dependency>
        <groupId>javax.servlet</groupId>
        <artifactId>javax.servlet-api</artifactId>
        <version>3.1.0</version>
        <scope>provided</scope>
    </dependency>
    <!--Spring与Thymeleaf整合-->
    <dependency>
        <groupId>org.thymeleaf</groupId>
        <artifactId>thymeleaf-spring5</artifactId>
        <version>3.0.12.RELEASE</version>
    </dependency>
</dependencies>

(1)InterceptorController.java

@Controller
public class InterceptorController {
    
    
    @RequestMapping("/testInterceptor")
    public String testInterceptor(){
    
    
        return "success";
    }
}

(2)CustomerInterceptor.java

//若想配置多个拦截器,只需要复制该拦截器,改个类名就可
@Component
public class CustomerInterceptor implements HandlerInterceptor {
    
    
    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
    
    
        System.out.println("InterceptorTest--->preHandle");
        //return false表示不拦截
        return true;
    }
    @Override
    public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
    
    
        System.out.println("InterceptorTest--->postHandle");
    }
    @Override
    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
    
    
        System.out.println("InterceptorTest--->afterCompletion");
    }
}

(3)springMVC.xml

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:context="http://www.springframework.org/schema/context"
       xmlns:mvc="http://www.springframework.org/schema/mvc"
       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
            http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd
            http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc.xsd">

    <context:component-scan base-package="com.jd.mvc"/>
    <!--配置视图解析器-->
    <bean id="viewResolver" class="org.thymeleaf.spring5.view.ThymeleafViewResolver">
        <property name="order" value="1"/>
        <property name="characterEncoding" value="UTF-8"/>
        <property name="templateEngine">
            <bean class="org.thymeleaf.spring5.SpringTemplateEngine">
                <property name="templateResolver">
                    <bean class="org.thymeleaf.spring5.templateresolver.SpringResourceTemplateResolver">
                        <!--视图前缀-->
                        <property name="prefix" value="/WEB-INF/templates/"/>
                        <!--视图后缀-->
                        <property name="suffix" value=".html"/>
                        <property name="templateMode" value="HTML5"/>
                        <property name="characterEncoding" value="UTF-8"/>
                    </bean>
                </property>
            </bean>
        </property>
    </bean>
    <!--配置SpringMVC的视图控制器-->
    <mvc:view-controller path="/" view-name="index"></mvc:view-controller>
    <mvc:default-servlet-handler/>
    <!--开启SpringMVC的注解驱动-->
    <mvc:annotation-driven/>
    <!--配置拦截器-->
    <mvc:interceptors>
<!--        <bean class="com.jd.mvc.interceptor.CustomerInterceptor"/>-->
			<!--配置第2个拦截器-->
<!--        <bean class="com.jd.mvc.interceptor.CustomerInterceptor2"/>-->
<!--        <ref bean="firstInterceptor"/>-->
<!--        以上两种配置会对所有的请求尽心拦截-->
        <mvc:interceptor>
            <mvc:mapping path="/**"/>
            <mvc:exclude-mapping path="/"/>
            <ref bean="customerInterceptor"/>
        </mvc:interceptor>
    </mvc:interceptors>
</beans>

(4)index.html

<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
<h1>首页</h1><br>
<a th:href="@{/testInterceptor}">测试Interceptor</a>
</body>
</html>

(5)web.xml

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd"
         version="4.0"
         metadata-complete="true">
    <!--1.配置编码过滤器,在此之前不能获取任何的请求参数,只要获取请求参数,设置编码方式就无用-->
    <filter>
        <filter-name>CharacterEncodingFilter</filter-name>
        <filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class>
        <!--设置请求的编码-->
        <init-param>
            <param-name>encoding</param-name>
            <param-value>UTF-8</param-value>
        </init-param>
        <!--设置响应的编码-->
        <init-param>
            <param-name>forceResponseEncoding</param-name>
            <param-value>true</param-value>
        </init-param>
    </filter>
    <!--表示对所有的都进行编码,过滤器的执行顺序是根据<filter-mapping>的顺序执行的-->
    <filter-mapping>
        <filter-name>CharacterEncodingFilter</filter-name>
        <url-pattern>/*</url-pattern>
    </filter-mapping>

    <!--2.配置HiddenHttpMethodFilter-->
    <filter>
        <filter-name>HiddenHttpMethodFilter</filter-name>
        <filter-class>org.springframework.web.filter.HiddenHttpMethodFilter</filter-class>
    </filter>
    <filter-mapping>
        <filter-name>HiddenHttpMethodFilter</filter-name>
        <url-pattern>/*</url-pattern>
    </filter-mapping>
    <!--3.配置SpringMVC的前端控制器-->
    <servlet>
        <servlet-name>DispatcherServlet</servlet-name>
        <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
        <init-param>
            <param-name>contextConfigLocation</param-name>
            <param-value>classpath:springMVC.xml</param-value>
        </init-param>
        <load-on-startup>1</load-on-startup>
    </servlet>
    <servlet-mapping>
        <servlet-name>DispatcherServlet</servlet-name>
        <url-pattern>/</url-pattern>
    </servlet-mapping>
</web-app>

Deploy the project to the tomcat server and run it. Click the hyperlink
insert image description here
to return to the idea console, and you can see the execution order of the two interceptors.
insert image description here

2. Exception handler

SpringMVC provides an exception interface that occurs during the execution of the controller method: HandlerExceptionResolver The
implementation classes of the HandlerExceptionResolver interface are: DefaultHandlerExceptionResolver and
SimpleMappingExceptionResolver
SpringMVC provides a custom exception handler SimpleMappingExceptionResolver, using:

Configuration-based exception handling

(1) Configure in the configuration file of SpringMVC

<!--配置SpringMVC的异常映射-->
<bean class="org.springframework.web.servlet.handler.SimpleMappingExceptionResolver">
    <property name="exceptionMappings">
        <props>
            <!--properties的键表示处理器方法执行过程中出现的异常;
                properties的值表示若出现指定异常时,设置一个新的视图名称,跳转到指定页面-->
            <prop key="java.lang.ArithmeticException">error</prop>
        </props>
    </property>
    <!--exceptionAttribute属性设置一个属性名,将异常信息共享在请求域中-->
    <property name="exceptionAttribute" value="ex"/>
</bean>

(2)index.html

<!--设置将异常信息共享在请求域中的键-->
<a th:href="@{/testException}">测试Exception</a><br>

(3)error.html

<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
出现了错误!!!
<!--获取异常并输出-->
<p th:text="${ex}"></p>
</body>
</html>

(4) Controller method

@RequestMapping("/testException")
public String testException(){
    
    
    int i = 10/0;
    return "error";
}

insert image description here

Annotation-based exception handling

You only need to create a java class, and then mark the corresponding annotations, which can save the configuration of the SpringMVC configuration file.

@ControllerAdvice
public class ExceptionController {
    
    
    @ExceptionHandler(value = {
    
    ArithmeticException.class,NullPointerException.class})
    public String testException(Exception ex, Model model){
    
    
        model.addAttribute("ex",ex);
        return "error";
    }
}

Guess you like

Origin blog.csdn.net/weixin_46081857/article/details/122267512