Chao's Blog Chao's Blog
首页
  • vue

    • vue路由
  • 学习笔记

    • 《JavaScript教程》
    • 《JavaScript高级程序设计》
    • 《ES6 教程》
    • 《Vue》
    • 《React》
    • 《TypeScript 从零实现 axios》
    • 《Git》
    • TypeScript
    • JS设计模式总结
  • java
  • spring
  • springboot
  • springcloud
  • git
  • maven
  • nginx
  • tomcat
  • springmvc
  • jvm
  • 图数据库
  • mysql数据库
  • redis数据库
  • windows下docker安装nginx并挂载目录
  • linux命令
  • linux安装软件
  • linux脚本
  • idea
  • vscode
  • 归档
  • 综合项目

    • 若依项目
    • mall项目
  • java
  • mybatis
  • xxl-job
  • mybatis
GitHub (opens new window)

~chao

永远菜鸟,不断努力~
首页
  • vue

    • vue路由
  • 学习笔记

    • 《JavaScript教程》
    • 《JavaScript高级程序设计》
    • 《ES6 教程》
    • 《Vue》
    • 《React》
    • 《TypeScript 从零实现 axios》
    • 《Git》
    • TypeScript
    • JS设计模式总结
  • java
  • spring
  • springboot
  • springcloud
  • git
  • maven
  • nginx
  • tomcat
  • springmvc
  • jvm
  • 图数据库
  • mysql数据库
  • redis数据库
  • windows下docker安装nginx并挂载目录
  • linux命令
  • linux安装软件
  • linux脚本
  • idea
  • vscode
  • 归档
  • 综合项目

    • 若依项目
    • mall项目
  • java
  • mybatis
  • xxl-job
  • mybatis
GitHub (opens new window)
  • java

  • spring

  • springboot

  • springcloud

  • git

  • maven

  • nginx

  • tomcat

  • springmvc

    • 基础

      • SpringMVC简介
      • RequestMapping 注解
      • SpringMVC获取请求参数
      • 域对象共享数据
      • SpringMVC视图
      • RESTful
      • RESTful案例
      • HttpMessageConverter
      • 拦截器和异常处理
        • 1、拦截器
          • 1.1、拦截器的配置
          • 方式一
          • 方式二
          • 方式三
          • 小结
          • 1.2、拦截器的三个抽象方法
          • 1.3、多个拦截器的执行顺序
          • 若每个拦截器的preHandle()都返回true
          • 若某个拦截器的preHandle()返回了false
        • 2、异常处理
          • 2.1、基于配置的异常处理
          • 2.2、基于注解的异常处理
        • 总结
      • 完全注解开发
      • SpringMVC 执行流程
    • 总结

  • jvm

  • 正则表达式

  • 消息中间件

  • python

  • 后端
  • springmvc
  • 基础
~chao
2022-12-16
目录

拦截器和异常处理

笔记来源:【尚硅谷】SpringMVC教程丨一套快速上手spring mvc (opens new window)

[TOC]

# 拦截器和异常处理

# 1、拦截器

# 1.1、拦截器的配置

SpringMVC 中的拦截器用于拦截控制器方法的执行,需要实现HandlerInterceptor,并在 SpringMVC 的配置文件中进行配置

# 方式一

后台测试代码

public class MyInterceptor implements HandlerInterceptor {
    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        System.out.println("MyInterceptor==>preHandle");
        return HandlerInterceptor.super.preHandle(request, response, handler);
    }

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

    @Override
    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
        System.out.println("MyInterceptor==>afterCompletion");
        HandlerInterceptor.super.afterCompletion(request, response, handler, ex);
    }
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19

配置拦截器

<mvc:interceptors>
    <bean id="myInterceptor" class="com.vectorx.springmvc.s00_helloworld.interceptor.MyInterceptor"></bean>
</mvc:interceptors>
1
2
3

访问任意路径,后台日志信息

MyInterceptor==>preHandle
MyInterceptor==>postHandle
MyInterceptor==>afterCompletion
1
2
3

# 方式二

后台测试代码

@Component
public class MyInterceptor implements HandlerInterceptor {
    // 略同
}
1
2
3
4

配置拦截器

<mvc:interceptors>
    <ref bean="myInterceptor"></ref>
</mvc:interceptors>
1
2
3

访问任意路径,后台日志信息

MyInterceptor==>preHandle
MyInterceptor==>postHandle
MyInterceptor==>afterCompletion
1
2
3

# 方式三

后台测试代码

@Component
public class MyInterceptor implements HandlerInterceptor {
    // 略同
}
1
2
3
4

配置拦截器

<mvc:interceptors>
    <mvc:interceptor>
        <mvc:mapping path="/**"/>
        <mvc:exclude-mapping path="/"/>
        <ref bean="myInterceptor"></ref>
    </mvc:interceptor>
</mvc:interceptors>
1
2
3
4
5
6
7

此时除了访问/即首页时不会走拦截器,其他请求都会走拦截器,其后台日志信息

MyInterceptor==>preHandle
MyInterceptor==>postHandle
MyInterceptor==>afterCompletion
1
2
3

注意:这里的path路径配置的是/**,表示任意层路径的请求,符合Ant风格的路径。这与web.xml中url-pattern的/*匹配效果一致,但写法不同

# 小结

  • 方式一和方式二都是对DispatcherServlet所处理的所有请求进行拦截
  • 方式三可以有选择拦截请求,通过ref或bean设置拦截器,通过mvc:mapping设置需要拦截的请求,通过mvc:exclude-mapping设置需要排除(即不需要拦截)的请求

# 1.2、拦截器的三个抽象方法

  • preHandle:控制器方法执行之前执行preHandle(),其 boolean 类型的返回值表示是否拦截或放行
    • 返回 true 表示放行,即调用控制器方法
    • 返回 false 表示拦截,即不调用控制器方法
  • postHandle:控制器方法执行之后执行postHandle()
  • afterCompletion:处理完视图和模型数据,渲染视图完毕之后执行afterCompletion()

# 1.3、多个拦截器的执行顺序

# 若每个拦截器的preHandle()都返回true

此时多个拦截器的执行顺序和拦截器在 SpringMVC 的配置文件的配置顺序有关:

preHandle()会按照配置的顺序执行,而postHandle()和afterComplation()会按照配置的反序执行

配置顺序

<mvc:interceptors>
    <ref bean="myInterceptor"></ref>
    <ref bean="myInterceptor2"></ref>
</mvc:interceptors>
1
2
3
4

后台日志信息

MyInterceptor==>preHandle
MyInterceptor2==>preHandle
MyInterceptor2==>postHandle
MyInterceptor==>postHandle
MyInterceptor2==>afterCompletion
MyInterceptor==>afterCompletion
1
2
3
4
5
6

可以看出,preHandle顺序执行,postHandle和afterCompletion反序执行

# 若某个拦截器的preHandle()返回了false

preHandle()返回 false 和它之前的拦截器的preHandle()都会执行,postHandle()都不执行,返回 false 的拦截器之前的拦截器的afterComplation()会执行

后台测试代码

@Component
public class MyInterceptor2 implements HandlerInterceptor {
    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        System.out.println("MyInterceptor2==>preHandle");
        return false;
    }
    // 略同
}
1
2
3
4
5
6
7
8
9

后台日志信息

MyInterceptor==>preHandle
MyInterceptor2==>preHandle
MyInterceptor==>afterCompletion
1
2
3

# 2、异常处理

# 2.1、基于配置的异常处理

SpringMVC 提供了一个处理控制器方法执行过程中所出现异常的接口:HandlerExceptionResolver

HandlerExceptionResolver接口的实现类有:DefaultHandlerExceptionResolver和SimpleMappingExceptionResolver

image-20220404180625663

SpringMVC 提供了自定义的异常处理器SimpleMappingExceptionResolver

配置文件

<bean id="simpleMappingExceptionResolver"
      class="org.springframework.web.servlet.handler.SimpleMappingExceptionResolver">
    <property name="exceptionMappings">
        <props>
            <!--
                properties的键表示处理器方法执行过程中出现的异常
                properties的值表示若出现指定异常,设置一个新的视图名称,跳转到指定页面
            -->
            <prop key="java.lang.ArithmeticException">error</prop>
        </props>
    </property>
    <!--设置一个属性名,将出现的异常信息共享在请求域中-->
    <property name="exceptionAttribute" value="ex"></property>
</bean>
1
2
3
4
5
6
7
8
9
10
11
12
13
14

后台测试代码

@RequestMapping("testException")
public String testException() {
    int i = 1 / 0;
    return "success";
}
1
2
3
4
5

测试结果

image-20220404183816999

# 2.2、基于注解的异常处理

  • @ControllerAdvice标识当前类为异常处理的组件
  • @ExceptionHandler设置所标识方法处理的异常

配置注解

// ControllerAdvice 标识当前类为异常处理的组件
@ControllerAdvice
public class ExceptionController {
    // ExceptionHandler 设置所标识方法处理的异常
    @ExceptionHandler(value = {ArithmeticException.class, NullPointerException.class})
    // ex 表示当前请求处理过程中出现的异常对象
    public String testException(Exception ex, Model model) {
        model.addAttribute("ex", ex);
        return "error";
    }
}
1
2
3
4
5
6
7
8
9
10
11

测试结果

image-20220404183816999

# 总结

本节重点掌握

  • 拦截器的自定义方法、三种配置方式、三个抽象方法及执行顺序
  • 异常处理解析器的两种方式:基于配置和基于注解

附上导图,仅供参考

07-拦截器和异常处理

编辑 (opens new window)
上次更新: 2024/01/26, 05:03:22
HttpMessageConverter
完全注解开发

← HttpMessageConverter 完全注解开发→

最近更新
01
python使用生成器读取大文件-500g
09-24
02
Windows环境下 Docker Desktop 安装 Nginx
04-10
03
使用nginx部署多个前端项目(三种方式)
04-10
更多文章>
Theme by Vdoing | Copyright © 2022-2024 chaos | MIT License
  • 跟随系统
  • 浅色模式
  • 深色模式
  • 阅读模式