SpringMVC之异常处理器的使用

开发过程中是不可避免地会出现各种异常情况的,例如网络连接异常、数据格式异常、空指针异常等等。异常的出现可能导致程序的运行出现问题,甚至直接导致程序崩溃。因此,在开发过程中,合理处理异常、避免异常产生、以及对异常进行有效的调试是非常重要的。

对于异常的处理,一般分为两种方式:

  • 编程式异常处理:是指在代码中显式地编写处理异常的逻辑。它通常涉及到对异常类型的检测及其处理,例如使用 try-catch 块来捕获异常,然后在 catch 块中编写特定的处理代码,或者在 finally 块中执行一些清理操作。在编程式异常处理中,开发人员需要显式地进行异常处理,异常处理代码混杂在业务代码中,导致代码可读性较差。
  • 声明式异常处理:则是将异常处理的逻辑从具体的业务逻辑中分离出来,通过配置等方式进行统一的管理和处理。在声明式异常处理中,开发人员只需要为方法或类标注相应的注解(如 @Throws@ExceptionHandler),就可以处理特定类型的异常。相较于编程式异常处理,声明式异常处理可以使代码更加简洁、易于维护和扩展。

站在宏观角度来看待声明式事务处理:

整个项目从架构这个层面设计的异常处理的统一机制和规范。

一个项目中会包含很多个模块,各个模块需要分工完成。如果张三负责的模块按照 A 方案处理异常,李四负责的模块按照 B 方案处理异常……各个模块处理异常的思路、代码、命名细节都不一样,那么就会让整个项目非常混乱。

使用声明式异常处理,可以统一项目处理异常思路,项目更加清晰明了!

  • SpringMVC的异常处理器是处理控制器方法执行过程出现的异常。
  • SpringMVC提供了一个处理异常的接口HandlerExceptionResolver
  • HandlerExceptionResolver接口有两个实现类:
    DefaultHandlerExceptionResolver实现类和SimpleMappingExceptionResolver实现类。
    DefaultHandlerExceptionResolver实现类是SpringMVC默认异常处理器。
    SimpleMappingExceptionResolver实现类是简易异常处理器,我们一般自定义配置异常处理策略就是使用该异常处理器。

基于xml文件配置异常处理器

<!-- 配置异常处理器 -->
<bean class="org.springframework.web.servlet.handler.SimpleMappingExceptionResolver">
	<!-- 配置异常视图的优先级 -->
	<property name="order" value="1"/>
	<!-- 配置异常逻辑视图映射:出现指定异常跳转到指定错误页面 -->
	<property name="exceptionMappings">
		<props>
			<!--
			 key设置要处理的异常,全类名
			 value设置出现该异常时要跳转的页面所对应的逻辑视图
			 -->
			<prop key="java.lang.Exception">error</prop>
			<prop key="java.lang.NullPointerException">error</prop>
			<prop key="java.lang.ArithmeticException">error</prop>
		</props>
	</property>
	<!-- 设置默认错误视图 -->
	<property name="defaultErrorView" value="error"/>
	<!-- 设置异常属性:将异常信息共享到请求域中,浏览器可以获取请求域中的异常信息 -->
	<property name="exceptionAttribute" value="ex"/>
	<!-- 异常状态码 -->
	<!--<property name="statusCodes" value="404,500"/>-->
	<!-- 默认异常状态码 -->
	<!--<property name="defaultStatusCode" value="500"/>-->
	<!-- 排除指定异常 -->
	<!--<property name="excludedExceptions" value="java.lang.ArithmeticException"/>-->
</bean>

基于注解配置异常处理器

@ControllerAdvice //将当前类标识为异常处理的组件
public class GlobalHandlerException {

    //@ExceptionHandler用于设置所标识方法处理的异常
    //ex表示当前请求处理中出现的异常对象
    @ExceptionHandler(NullPointerException.class)
    public Object handleException(NullPointerException e, Model model) {
        String message = e.getMessage();
        System.out.println(message);
        model.addAttribute("message", message);
        return "error";
    }

    @ExceptionHandler(ArithmeticException.class)
    public Object handleException(ArithmeticException e,Model model) {
        String message = e.getMessage();
        System.out.println(message);
        model.addAttribute("message",message);
        return "error";
    }

/**
 * 所有异常都会触发此方法!但是如果有具体的异常处理Handler! 
 * 具体异常处理Handler优先级更高!
 * 例如: 发生NullPointerException异常!
 *       会触发handlerNullException方法,不会触发handlerException方法!
 * @param e,model
 * @return
 */
    @ExceptionHandler(Exception.class)
    public Object handleException(Exception e,Model model) {
        String message = e.getMessage();
        System.out.println(message);
        model.addAttribute("meaages",message);
        return "error";
    }
}

创建视图

<a th:href="@{/test/get1}">测试异常处理器</a><br/>
<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head>
    <meta charset="UTF-8">
    <title>错误</title>
</head>
<body>
    <h2>error.html</h2>
    <h4 style="color: green">系统内部出现故障,请联系管理员!</h4>
    <p th:text="${message}">注解方式获取域中异常信息</p>
    <!--<p th:text="${ex}">Xml配置方式获取域中的异常信息</p>-->
</body>
</html>

编写控制器方法

@RestController
@RequestMapping("/user")
public class UserController {

    @GetMapping("/get1")
    public String getUser() {
        String name = null;
        name.toString();
        System.out.println(name);
        return "ok";
    }


    @GetMapping("/get2")
    public String getAdmin() {
        Integer i = 10 / 0;
        System.out.println(i);
        return "ok";
    }
}

测试
发送访问/user/get1控制器方法的请求,控制器方法执行过程中出现异常处理器中配置的异常策略,跳转到指定异常视图。

相关文章

开发过程中是不可避免地会出现各种异常情况的,例如网络连接...
说明:使用注解方式实现AOP切面。 什么是AOP? 面向切面编程...
Spring MVC中的拦截器是一种可以在请求处理过程中对请求进行...
在 JavaWeb 中,共享域指的是在 Servlet 中存储数据,以便在...
文件上传 说明: 使用maven构建web工程。 使用Thymeleaf技术...
创建初始化类,替换web.xml 在Servlet3.0环境中,Web容器(To...