SpringBoot 如何使用 @ExceptionHandler 注解进行局部异常处理

简介: SpringBoot 如何使用 @ExceptionHandler 注解进行局部异常处理

SpringBoot 如何使用 @ExceptionHandler 注解进行局部异常处理


介绍


在开发 Web 应用程序时,异常处理是非常重要的一部分。SpringBoot 提供了多种方式来处理异常,其中之一是使用 @ExceptionHandler 注解进行局部异常处理。使用 @ExceptionHandler 注解,我们可以在 Controller 层或方法级别上处理异常,而不用在整个应用程序中处理。


在本文中,我们将介绍 SpringBoot 中的 @ExceptionHandler 注解,演示如何使用它进行局部异常处理。


image.png


@ExceptionHandler 注解


@ExceptionHandler 注解是 SpringFramework 提供的一个注解,用于处理控制器中出现的异常。当在控制器方法中抛出异常时,SpringBoot 会查找带有 @ExceptionHandler 注解的方法,并调用它来处理异常。


下面是一个简单的例子:


@RestController
public class UserController {
    @GetMapping("/users/{id}")
    public User getUser(@PathVariable int id) {
        User user = userRepository.findById(id);
        if (user == null) {
            throw new UserNotFoundException("User not found");
        }
        return user;
    }
    @ExceptionHandler(UserNotFoundException.class)
    public ResponseEntity<ErrorResponse> handleUserNotFoundException(UserNotFoundException ex) {
        ErrorResponse error = new ErrorResponse(HttpStatus.NOT_FOUND.value(), ex.getMessage());
        return new ResponseEntity<>(error, HttpStatus.NOT_FOUND);
    }
}

在上面的代码中,我们定义了一个 UserController 类,并实现了一个 getUser 方法。如果用户不存在,则抛出 UserNotFoundException 异常。然后,我们使用 @ExceptionHandler 注解定义了一个 handleUserNotFoundException 方法,用于处理 UserNotFoundException 异常。在该方法中,我们创建了一个 ErrorResponse 对象,包含了错误响应的状态码和消息,然后将其封装在 ResponseEntity 对象中返回。


如何使用 @ExceptionHandler 注解进行局部异常处理


要使用 @ExceptionHandler 注解进行局部异常处理,请按照以下步骤操作:


第 1 步:定义自定义异常

在代码中定义自定义异常,继承自 Exception 或 RuntimeException 类。例如:


public class UserNotFoundException extends RuntimeException {
    public UserNotFoundException(String message) {
        super(message);
    }
}

在上面的代码中,我们定义了一个名为 UserNotFoundException 的自定义异常,它继承自 RuntimeException 类。


第 2 步:抛出异常

在控制器方法中抛出自定义异常。例如:

@GetMapping("/users/{id}")
public User getUser(@PathVariable int id) {
    User user = userRepository.findById(id);
    if (user == null) {
        throw new UserNotFoundException("User not found");
    }
    return user;
}

在上面的代码中,如果用户不存在,则抛出 UserNotFoundException 异常。


第 3 步:处理异常

使用 @ExceptionHandler 注解定义一个方法,用于处理自定义异常。例如:


@ExceptionHandler(UserNotFoundException.class)
public ResponseEntity<ErrorResponse> handleUserNotFoundException(UserNotFoundException ex) {
    ErrorResponse error = new ErrorResponse(HttpStatus.NOT_FOUND.value(), ex.getMessage());
    return new ResponseEntity<>(error, HttpStatus.NOT_FOUND);
}

在上面的代码中,我们使用 @ExceptionHandler(UserNotFoundException.class) 注解定义了一个方法 handleUserNotFoundException,用于处理 UserNotFoundException 异常。在该方法中,我们创建了一个 ErrorResponse 对象,包含了错误响应的状态码和消息,然后将其封装在 ResponseEntity 对象中返回。


示例


以下是一个完整的示例:


UserController.java


@RestController
public class UserController {
    @Autowired
    private UserRepository userRepository;
    @GetMapping("/users/{id}")
    public User getUser(@PathVariable int id) {
        User user = userRepository.findById(id);
        if (user == null) {
            throw new UserNotFoundException("User not found");
        }
        return user;
    }
    @PostMapping("/users")
    public User createUser(@RequestBody User user) {
        userRepository.save(user);
        return user;
    }
    @PutMapping("/users/{id}")
    public User updateUser(@PathVariable int id, @RequestBody User user) {
        User existingUser = userRepository.findById(id);
        if (existingUser == null) {
            throw new UserNotFoundException("User not found");
        }
        existingUser.setName(user.getName());
        existingUser.setAge(user.getAge());
        userRepository.save(existingUser);
        return existingUser;
    }
    @DeleteMapping("/users/{id}")
    public void deleteUser(@PathVariable int id) {
        UseruserRepository.deleteById(id);
    }
    @ExceptionHandler(UserNotFoundException.class)
    public ResponseEntity<ErrorResponse> handleUserNotFoundException(UserNotFoundException ex) {
        ErrorResponse error = new ErrorResponse(HttpStatus.NOT_FOUND.value(), ex.getMessage());
        return new ResponseEntity<>(error, HttpStatus.NOT_FOUND);
    }
}

UserNotFoundException.java


public class UserNotFoundException extends RuntimeException {
    public UserNotFoundException(String message) {
        super(message);
    }
}

ErrorResponse.java


public class ErrorResponse {
    private int status;
    private String message;
    public ErrorResponse(int status, String message) {
        this.status = status;
        this.message = message;
    }
    public int getStatus() {
        return status;
    }
    public String getMessage() {
        return message;
    }
}

在上面的代码中,我们定义了一个 UserController 类,实现了 getUser、createUser、updateUser 和 deleteUser 方法。如果用户不存在,则抛出 UserNotFoundException 异常。然后,我们使用 @ExceptionHandler 注解定义了一个 handleUserNotFoundException 方法,用于处理 UserNotFoundException 异常。在该方法中,我们创建了一个 ErrorResponse 对象,包含了错误响应的状态码和消息,然后将其封装在 ResponseEntity 对象中返回。


原理


当控制器方法抛出异常时,SpringBoot 会在控制器类中查找带有 @ExceptionHandler 注解的方法,并调用它来处理异常。@ExceptionHandler 注解的方法必须具有以下特征:


  • 方法必须是 public、没有返回值,并且具有一个参数,该参数类型为抛出的异常类型。
  • 方法必须使用 @ExceptionHandler 注解进行注解,该注解的参数为抛出的异常类型。


当控制器方法抛出异常时,SpringBoot 将异常传递给带有 @ExceptionHandler 注解的方法。该方法将处理异常,并返回一个 ResponseEntity 对象,该对象包含错误响应的状态码和消息。


总结


在本文中,我们介绍了 SpringBoot 中的 @ExceptionHandler 注解,演示了如何使用它进行局部异常处理。使用 @ExceptionHandler 注解,我们可以在 Controller 层或方法级别上处理异常。当控制器方法抛出异常时,SpringBoot 会查找带有 @ExceptionHandler 注解的方法,并调用它来处理异常。要使用 @ExceptionHandler 注解进行局部异常处理,需要定义自定义异常、抛出异常和处理异常。


相关文章
|
5月前
|
缓存 监控 Java
SpringBoot @Scheduled 注解详解
使用`@Scheduled`注解实现方法周期性执行,支持固定间隔、延迟或Cron表达式触发,基于Spring Task,适用于日志清理、数据同步等定时任务场景。需启用`@EnableScheduling`,注意线程阻塞与分布式重复问题,推荐结合`@Async`异步处理,提升任务调度效率。
873 128
|
5月前
|
XML 安全 Java
使用 Spring 的 @Aspect 和 @Pointcut 注解简化面向方面的编程 (AOP)
面向方面编程(AOP)通过分离横切关注点,如日志、安全和事务,提升代码模块化与可维护性。Spring 提供了对 AOP 的强大支持,核心注解 `@Aspect` 和 `@Pointcut` 使得定义切面与切入点变得简洁直观。`@Aspect` 标记切面类,集中处理通用逻辑;`@Pointcut` 则通过表达式定义通知的应用位置,提高代码可读性与复用性。二者结合,使开发者能清晰划分业务逻辑与辅助功能,简化维护并提升系统灵活性。Spring AOP 借助代理机制实现运行时织入,与 Spring 容器无缝集成,支持依赖注入与声明式配置,是构建清晰、高内聚应用的理想选择。
610 0
|
4月前
|
XML Java 应用服务中间件
【SpringBoot(一)】Spring的认知、容器功能讲解与自动装配原理的入门,带你熟悉Springboot中基本的注解使用
SpringBoot专栏开篇第一章,讲述认识SpringBoot、Bean容器功能的讲解、自动装配原理的入门,还有其他常用的Springboot注解!如果想要了解SpringBoot,那么就进来看看吧!
552 2
|
5月前
|
Java 测试技术 数据库
使用Spring的@Retryable注解进行自动重试
在现代软件开发中,容错性和弹性至关重要。Spring框架提供的`@Retryable`注解为处理瞬时故障提供了一种声明式、可配置的重试机制,使开发者能够以简洁的方式增强应用的自我恢复能力。本文深入解析了`@Retryable`的使用方法及其参数配置,并结合`@Recover`实现失败回退策略,帮助构建更健壮、可靠的应用程序。
685 1
使用Spring的@Retryable注解进行自动重试
|
5月前
|
XML Java 数据格式
常用SpringBoot注解汇总与用法说明
这些注解的使用和组合是Spring Boot快速开发和微服务实现的基础,通过它们,可以有效地指导Spring容器进行类发现、自动装配、配置、代理和管理等核心功能。开发者应当根据项目实际需求,运用这些注解来优化代码结构和服务逻辑。
423 12
|
5月前
|
传感器 Java 数据库
探索Spring Boot的@Conditional注解的上下文配置
Spring Boot 的 `@Conditional` 注解可根据不同条件动态控制 Bean 的加载,提升应用的灵活性与可配置性。本文深入解析其用法与优势,并结合实例展示如何通过自定义条件类实现环境适配的智能配置。
298 0
探索Spring Boot的@Conditional注解的上下文配置
|
5月前
|
智能设计 Java 测试技术
Spring中最大化@Lazy注解,实现资源高效利用
本文深入探讨了 Spring 框架中的 `@Lazy` 注解,介绍了其在资源管理和性能优化中的作用。通过延迟初始化 Bean,`@Lazy` 可显著提升应用启动速度,合理利用系统资源,并增强对 Bean 生命周期的控制。文章还分析了 `@Lazy` 的工作机制、使用场景、最佳实践以及常见陷阱与解决方案,帮助开发者更高效地构建可扩展、高性能的 Spring 应用程序。
230 0
Spring中最大化@Lazy注解,实现资源高效利用
|
5月前
|
安全 IDE Java
Spring 的@FieldDefaults和@Data:Lombok 注解以实现更简洁的代码
本文介绍了如何在 Spring 应用程序中使用 Project Lombok 的 `@Data` 和 `@FieldDefaults` 注解来减少样板代码,提升代码可读性和可维护性,并探讨了其适用场景与限制。
209 0
Spring 的@FieldDefaults和@Data:Lombok 注解以实现更简洁的代码
|
5月前
|
Java 测试技术 编译器
@GrpcService使用注解在 Spring Boot 中开始使用 gRPC
本文介绍了如何在Spring Boot应用中集成gRPC框架,使用`@GrpcService`注解实现高效、可扩展的服务间通信。内容涵盖gRPC与Protocol Buffers的原理、环境配置、服务定义与实现、测试方法等,帮助开发者快速构建高性能的微服务系统。
1086 0
|
5月前
|
XML Java 测试技术
使用 Spring 的 @Import 和 @ImportResource 注解构建模块化应用程序
本文介绍了Spring框架中的两个重要注解`@Import`和`@ImportResource`,它们在模块化开发中起着关键作用。文章详细分析了这两个注解的功能、使用场景及最佳实践,帮助开发者构建更清晰、可维护和可扩展的Java应用程序。
302 0