likes
comments
collection
share

@RestControllerAdvice 业务案例场景

作者站长头像
站长
· 阅读数 19

@RestControllerAdvice注解,用于定义一个类,该类可以全局处理多个控制器的异常以及封装响应数据。它通常与 @ExceptionHandler@InitBinder@ModelAttribute 注解结合使用,以实现集中式异常处理和模型属性的初始化。

注解结构:

@RestControllerAdvice 业务案例场景

业务场景:

例如你正在开发一个大型的 Web 应用程序,该程序包含许多不同的控制器,这些控制器可能会抛出各种异常。为了统一处理这些异常并返回统一格式的响应数据,你可以使用 @RestControllerAdvice

1. 创建全局异常处理器:

import org.springframework.web.bind.annotation.RestControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.http.HttpStatus;
import org.springframework.web.servlet.mvc.method.annotation.ResponseEntityExceptionHandler;

@RestControllerAdvice
public class GlobalExceptionHandler extends ResponseEntityExceptionHandler {

    // 处理自定义异常
    @ExceptionHandler(CustomNotFoundException.class)
    public ResponseEntity<Object> handleCustomNotFoundException(CustomNotFoundException ex) {
        ErrorDetails errorDetails = new ErrorDetails(new Date(), ex.getMessage());
        return new ResponseEntity<>(errorDetails, HttpStatus.NOT_FOUND);
    }

    // 处理所有未捕获的异常
    @ExceptionHandler(Exception.class)
    public ResponseEntity<Object> handleAllExceptions(Exception ex) {
        ErrorDetails errorDetails = new ErrorDetails(new Date(), "Internal Server Error");
        return new ResponseEntity<>(errorDetails, HttpStatus.INTERNAL_SERVER_ERROR);
    }
    
    // 可以添加更多的异常处理方法...
}

class ErrorDetails {
    private Date timestamp;
    private String message;

    public ErrorDetails(Date timestamp, String message) {
        this.timestamp = timestamp;
        this.message = message;
    }

    // 标准的 getter 和 setter
}

在这个例子中,GlobalExceptionHandler 类使用 @RestControllerAdvice 注解,表示它是一个全局异常处理器。@ExceptionHandler 注解的方法可以捕获并处理特定类型的异常。

2. 定义自定义异常:

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

3. 控制器中抛出异常:

@RestController
@RequestMapping("/api")
public class ApiController {

    @GetMapping("/items/{id}")
    public Item getItem(@PathVariable Long id) {
        Item item = itemService.findById(id);
        if (item == null) {
            throw new CustomNotFoundException("Item with id " + id + " not found");
        }
        return item;
    }
}

在这个控制器中,如果请求的资源不存在,将抛出 CustomNotFoundException 异常。

4. 异常处理和响应:

当控制器抛出异常时,GlobalExceptionHandler 中相应的 @ExceptionHandler 方法将捕获并处理异常,返回一个包含错误详情和 HTTP 状态码的响应。

5. 注解属性说明:

@RestControllerAdvice 注解的主要属性及其说明:

  1. basePackages:

    • 类型:String[]
    • 作用:指定控制器所在的基础包。@RestControllerAdvice 注解的类将只对这些包或其子包中的控制器有效。
  2. basePackageClasses:

    • 类型:Class<?>[]
    • 作用:类型安全的替代 basePackages,用于指定控制器所在的包。可以通过引用包中的特定类来实现。
  3. assignableTypes:

    • 类型:Class<?>[]
    • 作用:指定控制器的类型。@RestControllerAdvice 注解的类将对所有可以被 assignableTypes 中的类所处理的控制器提供建议。
  4. annotations:

    • 类型:Class<? extends Annotation>[]
    • 作用:指定注解类型。@RestControllerAdvice 注解的类将对所有被 annotations 中指定的注解所注解的控制器提供建议。
  5. order:

    • 类型:int
    • 作用:指定 @RestControllerAdvice 类的顺序值。这个值决定了多个 @RestControllerAdvice 类的执行顺序,数值越小,优先级越高。
  6. value:

    • 类型:String[]
    • 作用:与 basePackages 相同,是 basePackages 的别名,用于指定控制器所在的基础包。

限制作用用法:

@RestControllerAdvice(basePackages = "com.example.myapp.controllers")
public class GlobalExceptionHandler {

    // 异常处理、模型属性初始化等方法
}

在这个示例中,@RestControllerAdvice 注解的 basePackages 属性用于指定该异常处理器应该应用于 com.example.myapp.controllers 包及其子包中的控制器。

总结:

  • @RestControllerAdvice 允许开发者集中处理应用程序中的异常,而不是在每个控制器中单独处理。
  • 它提供了一种机制来统一异常响应的格式,使得返回给客户端的错误信息更加一致和易于理解。
  • 使用 @RestControllerAdvice 可以提高代码的复用性和可维护性,尤其是当应用程序中的异常处理逻辑较为复杂时。
转载自:https://juejin.cn/post/7383029376381861925
评论
请登录