目录
4. 使用`ResponseEntityExceptionHandler`
@ControllerAdvice/@RestControllerAdvice
继承ResponseEntityExceptionHandler
异常处理与简单示例
在Spring Boot中,异常处理通常可以通过以下几种方式来实现:
1. Controller内异常处理:在Controller中使用`try-catch`块直接处理异常。
2. 使用`@ExceptionHandler`注解:在Controller中定义方法来处理局部异常。
3. 使用`@ControllerAdvice`或`@RestControllerAdvice`注解:创建一个全局异常处理器,它可以捕获整个应用程序的异常。
4. 使用`ResponseEntityExceptionHandler`:扩展`ResponseEntityExceptionHandler`类来提供全局异常处理,并覆盖其中的方法。
下面是使用这些方法的Java代码示例:
1. Controller内异常处理
@RestController
@RequestMapping("/api")
public class MyController {
@GetMapping("/item/{id}")
public ResponseEntity<?> getItem(@PathVariable("id") String id) {
try {
// logic to get item
} catch (ItemNotFoundException e) {
return ResponseEntity.status(HttpStatus.NOT_FOUND).body(e.getMessage());
}
}
}
2. 使用`@ExceptionHandler`注解
@RestController
@RequestMapping("/api")
public class MyController {
@GetMapping("/item/{id}")
public String getItem(@PathVariable("id") String id) {
// logic to get item
return "item";
}
@ExceptionHandler(ItemNotFoundException.class)
public ResponseEntity<String> handleItemNotFoundException(ItemNotFoundException e) {
return ResponseEntity.status(HttpStatus.NOT_FOUND).body(e.getMessage());
}
}
3. 使用`@ControllerAdvice`注解
@ControllerAdvice
public class GlobalExceptionHandler {
@ExceptionHandler(ItemNotFoundException.class)
public ResponseEntity<String> handleItemNotFoundException(ItemNotFoundException e) {
return ResponseEntity.status(HttpStatus.NOT_FOUND).body(e.getMessage());
}
@ExceptionHandler(Exception.class)
public ResponseEntity<String> handleGeneralException(Exception e) {
return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).body(e.getMessage());
}
}
4. 使用`ResponseEntityExceptionHandler`
@ControllerAdvice
public class CustomGlobalExceptionHandler extends ResponseEntityExceptionHandler {
@Override
protected ResponseEntity<Object> handleMethodArgumentNotValid(MethodArgumentNotValidException ex,
HttpHeaders headers,
HttpStatus status,
WebRequest request) {
// custom logic
return new ResponseEntity<>("Custom message", HttpStatus.BAD_REQUEST);
}
@ExceptionHandler(ItemNotFoundException.class)
protected ResponseEntity<Object> handleItemNotFound(ItemNotFoundException ex) {
return new ResponseEntity<>(ex.getMessage(), HttpStatus.NOT_FOUND);
}
}
在上述示例中,`ItemNotFoundException`是一个自定义异常,你需要根据自己的业务逻辑来创建和抛出它。这些方法可以根据需要组合使用,例如在Controller中处理特定的异常,同时有一个全局异常处理器来处理整个应用程序的其他异常。
自定义异常
想实现的场景是,
指定的异常直接抛到前端,
捕获的异常后log.error(), 前端模糊返回"操作异常"
1、自定义一个异常
public class MyException extends RuntimeException {
private static final long serialVersionUID = -1004916162498956491L;
public MyException(String msg) {
super(msg);
}
}
2、实现类调用
@Override
public int add(Demo demo) {
if (null == demo.getName()) {
throw new MyException("名称为空!");
}
return demoMapper.add(demo);
}
3、Controller
@PostMapping(value = "/add")
public String add(@RequestBody Demo demo) {
try {
demoService.add(demo);
} catch (MyException e) {
return Resule.fail(e.getMsg());
} catch (Exception e)
log.error("异常:{}",e)
return Resule.fail();
}
return Resule.success();
}
4、统一异常捕获
package com.xx.xx.manage.exception;
/**
* @author libusi
*/
@Slf4j
@RestControllerAdvice
public class ApplicationExceptionHandler {
protected static final Logger logger = LoggerFactory.getLogger(ApplicationExceptionHandler.class);
@Autowired
public ApplicationExceptionHandler(LogSaveUtil logSaveUtil) {
this.logSaveUtil = logSaveUtil;
}
/**
* 异常详细信息
*
* @return BaseResponse
*/
@ExceptionHandler(MyException.class)
public String msgException(Throwable t) {
...
return Resule.fail();
}
}
5、注意事项
自定义异常捕获不到, 那是因为controller没有catch MyException, 或者全局捕获异常的问题
一般情况下, 不要把未知异常的错误信息抛到前端, 要模糊处理返回
总结
当涉及到Spring Boot中异常处理的不同方法时,我们可以比较它们的优缺点以及它们各自的最佳使用场景。下面是一个简化的对比表格,用于概述每种方法:
使用场景
方法 | 优点 | 缺点 | 使用场景 |
---|---|---|---|
Controller内try-catch | - 简单直接<br>- 控制器内部局部化处理 | - 代码重复<br>- 没有集中管理异常 | - 小型应用<br>- 快速原型开发<br>- 特定控制器需要特殊处理时 |
@ExceptionHandler 注解 | - 减少代码重复<br>- 控制器内部集中处理异常 | - 只限于单个控制器<br>- 可能导致每个控制器都有重复的异常处理 | - 控制器内部有多个处理方法需要处理相同的异常 |
@ControllerAdvice /@RestControllerAdvice | - 全局异常处理<br>- 集中管理异常<br>- 可以处理多个控制器的异常 | - 如果过于通用,可能会捕获并隐藏问题 | - 大型应用<br>- 需要统一异常响应格式时 |
继承ResponseEntityExceptionHandler | - 全局异常处理<br>- 可以重用Spring的内置异常处理机制 | - 比自定义@ControllerAdvice 更为复杂<br>- 可能需要更多的定制 | - 需要细粒度控制异常响应<br>- 扩展Spring的默认异常处理 |
使用场景详细说明
Controller内try-catch
适用于不需要复杂异常处理机制的小型项目或者是在特定的控制器方法中需要特殊处理异常的情况。
@ExceptionHandler注解
当你有一个控制器,并且它有多个处理方法需要处理相同的异常时,你可以在该控制器内部使用@ExceptionHandler注解来集中处理这些异常,从而减少代码重复。
@ControllerAdvice/@RestControllerAdvice
在大型应用程序中,通常需要一个集中的方式来处理所有控制器抛出的异常。@ControllerAdvice或@RestControllerAdvice提供了一种便捷的方式来定义全局异常处理逻辑,这样你就可以保持一个统一的异常响应格式,同时也便于维护。
继承ResponseEntityExceptionHandler
当你需要更细粒度的控制异常响应时,或者想要扩展和利用Spring MVC提供的默认异常处理机制时,可以选择扩展ResponseEntityExceptionHandler。这种方法适用于需要高度定制异常处理行为的复杂应用程序。
在实际应用中,开发者可以根据项目的具体需求和复杂度选择最适合的异常处理方法,也可以将不同的方法组合起来使用,以达到最佳的效果。
有用请点赞,养成良好习惯!
疑问、交流、鼓励请留言!