详解Spring全局异常处理的三种方式

yizhihongxing

我会详细讲解“详解Spring全局异常处理的三种方式”的完整攻略,并给出两个示例说明。

1. 为什么需要全局异常处理

Spring应用程序在运行过程中难免会遇到一些异常,如异常的输入、网络连接中断等。这些异常无法避免,但我们需要对这些异常进行合理的处理以便程序更健壮。而全局异常处理正是为此而设。

全局异常处理是指在应用程序中捕获所有未被捕获的异常,并尝试对它们进行恰当的处理。它在以下方面提供了价值:

  • 避免将异常抛给系统入口,提高应用程序健壮性。
  • 可以避免在日志或控制台中看到未处理的异常。
  • 可以尝试恢复异常,或向用户提供友好的错误提示。

2. 方式一:使用@ControllerAdvice进行全局异常处理

@ControllerAdvice是Spring提供的异常处理增强器。它允许我们使用一个单独的类来控制对所有异常的统一处理。

首先,我们定义一个ControllerAdvice类,用于处理全局异常:

@ControllerAdvice
public class GlobalExceptionHandler {
    @ExceptionHandler(Exception.class)
    public ResponseEntity<String> handleException(Exception ex) {
        // 返回自定义错误信息及状态码
        return new ResponseEntity<>("处理错误:" + ex.getMessage(), HttpStatus.INTERNAL_SERVER_ERROR);
    }
}

上面的代码中,我们指定了一个全局的Exception处理程序,它处理所有未处理的异常,并输出自定义的错误信息。

接下来,我们编写一个Controller类,它会抛出一个RuntimeException,而我们的全局异常处理程序会捕获它:

@RestController
public class HomeController {
    @GetMapping("/")
    public String index() {
        throw new RuntimeException("测试异常");
    }
}

如果你现在向http://localhost:8080/发送一个GET请求,你将会看到如下输出:

处理错误:测试异常

这就是一个最简单的全局异常处理的实现方式。

3. 方式二:使用XML进行全局异常处理

我们也可以使用XML来配置全局异常处理。以下是一个全局异常处理的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:p="http://www.springframework.org/schema/p"
    xmlns:c="http://www.springframework.org/schema/c" xmlns:mvc="http://www.springframework.org/schema/mvc"
    xmlns:context="http://www.springframework.org/schema/context"
    xsi:schemaLocation="http://www.springframework.org/schema/beans
    http://www.springframework.org/schema/beans/spring-beans-4.0.xsd
    http://www.springframework.org/schema/mvc
    http://www.springframework.org/schema/mvc/spring-mvc-4.0.xsd
    http://www.springframework.org/schema/context
    http://www.springframework.org/schema/context/spring-context-4.0.xsd">

    <bean class="org.springframework.web.servlet.handler.SimpleMappingExceptionResolver">
        <property name="exceptionMappings">
            <props>
                <prop key="java.lang.Exception">error</prop>
            </props>
        </property>
    </bean>

</beans>

在上面的配置中,我们指定了一个SimpleMappingExceptionResolver程序,用于处理所有Exception异常,并将它们映射到错误页面。

4. 方式三:使用@WebAdvice进行全局异常处理

@WebAdvice是Spring4.3中新引入的一种异常处理方式,它与@ControllerAdvice类似,但更加简单。我们定义一个类并添加@WebAdvice注解,如下所示:

@WebAdvice
public class GlobalExceptionHandler {
    @ExceptionHandler(Exception.class)
    public ResponseEntity<String> handleException(Exception ex) {
        // 返回自定义错误信息及状态码
        return new ResponseEntity<>("处理错误:" + ex.getMessage(), HttpStatus.INTERNAL_SERVER_ERROR);
    }
}

上述代码中,我们使用@WebAdvice注解注释了一个全局异常处理程序,并对异常进行了捕获和处理。

5. 示例

假设我们有一个Controller,其中包含一些方法,对这些方法抛出的异常进行处理:

@RestController
public class UserController {

   @PostMapping("/users")
   public ResponseEntity createUser(@RequestBody User user){
        // Simulate runtime exception
        if(user.getName().equalsIgnoreCase("test")){
            throw new RuntimeException("Test Exception");
        }
        return ResponseEntity.ok("User created successfully");
   }

   @GetMapping("/users/{id}")
   public User getUser(@PathVariable int id){
         User user = new User();
         // Simulate runtime exception
        if(id == 0){
            throw new RuntimeException("Invalid User ID");
        };
        return user;
   }
}

如果我们现在尝试使用POST方法创建用户并在创建用户名为test的用户时发生运行时异常,或者通过GET方法获取用户时提供无效的用户ID,会返回一个 server error。 我们需要改进这个行为并以友好的方式通知用户。

我们可以通过使用@ControllerAdvice并实现一个ExceptionHandler来处理这种行为。 下面是代码示例 (我们将重新使用方式1):

@ControllerAdvice
public class GlobalExceptionHandler {

    @ExceptionHandler(RuntimeException.class)
    public ResponseEntity<ErrorResponse> handleRuntimeException(RuntimeException e) {
        ErrorResponse errorResponse = new ErrorResponse();
        errorResponse.setMessage(e.getMessage());
        return new ResponseEntity<ErrorResponse>(errorResponse, HttpStatus.INTERNAL_SERVER_ERROR);
    }

    @ExceptionHandler(Exception.class)
    public ResponseEntity<ErrorResponse> handleGeeksException(Exception e) {
        ErrorResponse errorResponse = new ErrorResponse();
        errorResponse.setMessage(e.getMessage());
        return new ResponseEntity<ErrorResponse>(errorResponse, HttpStatus.BAD_REQUEST);
    }

}

在这里,GlobalExceptionHandler类中的方法会捕获与别名相同的所有异常,并以友好的方式通知用户。

我们创建一个实体类ErrorResponse==> 错误响应的格式如下所示:

@Data // 类中默认生成setter和getter方法,此处使用了lombok插件
public class ErrorResponse {
    private String message;
    private String explanation;
    private List<String> details;
}

6. 结论

全局异常处理提供了一种统一处理未处理异常的方法,增加了 Spring 应用程序的健壮性,使得用户获得了更好的体验。在以上示例中,我们使用了多种方式来创建全局异常处理程序。虽然有许多方式可供选择,但我们将选择一个适合我们的解决方案,并尽可能使其简洁明了。

希望以上内容对你有所帮助。

本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:详解Spring全局异常处理的三种方式 - Python技术站

(0)
上一篇 2023年5月27日
下一篇 2023年5月27日

相关文章

  • spring-boot项目启动迟缓异常排查解决记录

    首先,需要介绍一下 Spring Boot 项目启动的流程。当 Spring Boot 应用启动时,它会加载并解析所有的依赖包和配置文件,然后创建和初始化 Spring ApplicationContext,最后启动嵌入式的 Web 服务器,等待处理 HTTP 请求。 如果 Spring Boot 项目启动缓慢,可以考虑以下几个方面进行排查: 1. 依赖包冲…

    Java 2023年5月27日
    00
  • Java基础教程之包(package)

    Java基础教程之包(package) 在 Java 中,包(package)是一种用于组织及管理类、接口及其他资源的机制。包可以看成是文件夹,类则是文件,利用类放在包中,可以更好地组织和访问代码。 包的定义 在 Java 中,一个包是一组相互关联的 Java 类的集合。 当需要用到某个类时,可以指定其完全限定名(包括包名称和类名)来引用该类,例如: jav…

    Java 2023年5月20日
    00
  • Java对象深复制与浅复制实例详解

    Java对象深复制与浅复制实例详解 在 Java 中,对象的复制分为浅复制和深复制两种方式。本文将详细讲解 Java 中对象复制的概念、浅复制和深复制的实现方式、以及深浅复制的应用场景。 对象复制的概念 在 Java 中,我们可以通过 new 运算符来生成新的对象实例,但是有时候我们需要创建一个新对象,它的属性和原对象一模一样而且它们内存地址不同,这个时候就…

    Java 2023年5月26日
    00
  • Java如何计算两个时间段内的工作日天数

    针对Java如何计算两个时间段内的工作日天数,可以分成以下几个步骤: 1.确定工作日 首先,我们需要明确工作日的定义。工作日通常是指周一到周五,排除周末和法定节假日。 2.计算天数 其次,确认所需计算的两个时间段,并通过Java API获取这两个时间段之间的天数差。 3.排除非工作日 最后,遍历两个时间段中的每一天,将所有非工作日从计算结果中排除,得到最终的…

    Java 2023年5月20日
    00
  • MyBatis批量插入的五种方式小结(MyBatis以集合方式批量新增)

    MyBatis批量插入的五种方式小结 在使用MyBatis进行批量插入时,有多种方式可以选择。本文将介绍MyBatis批量插入的五种方式,并提供示例代码,以便读者更好地理解这些方法。 方式一:使用for循环单条插入 在使用for循环单条插入时,需要在for循环中执行insert语句。这种方式的优点是插入的数据可以轻松地进行转换,缺点是插入效率较低。 priv…

    Java 2023年6月1日
    00
  • 最适合人工智能开发的5种编程语言 附人工智能入门书籍

    最适合人工智能开发的5种编程语言,包括Python、Java、R语言、LISP和Prolog。这些编程语言不仅易学易用,而且拥有丰富的库和工具,能够方便地完成数据分析、机器学习、深度学习等多种人工智能任务。 Python Python是目前最常用的人工智能编程语言之一,甚至有人将其描述为“完美的人工智能编程语言”。Python易学易用,有丰富的库和工具,可实…

    Java 2023年5月19日
    00
  • 大厂面试常考:快速排序冒泡排序算法

    大厂面试常考:快速排序冒泡排序算法 在大厂面试中,经常会出现排序算法的相关问题。快速排序和冒泡排序是最常见的排序算法之一,本文将详细讲解这两种常见的排序算法。 快速排序 概念 快速排序采用“分治法”的思想。首先选取一个基准点,将数组分为左右两部分。左侧部分小于基准点,右侧部分大于基准点。接下来,递归地对左、右两个子数组执行快速排序。 代码实现 def qui…

    Java 2023年5月19日
    00
  • 如何优雅的处理异常

    作者:京东零售  秦浩然 一、什么是异常 Java 语言按照错误严重性,从 throwale 根类衍生出 Error 和 Exception 两大派系。 Error(错误): 程序在执行过程中所遇到的硬件或操作系统的错误。错误对程序而言是致命的,将导致程序无法运行。常见的错误有内存溢出,jvm 虚拟机自身的非正常运行,calss 文件没有主方法。程序本生是不…

    Java 2023年4月25日
    00
合作推广
合作推广
分享本页
返回顶部