Java Spring-启动微服务异常处理
Java Spring-boot micro-services Exception handling
Java 异常处理分为错误、已检查异常和未检查异常。这个问题是关于异常的。
正常的Java异常处理是将Exceptionclass扩展为已检查的异常,并通过考虑异常层次结构按需处理。
例如:
public class ExceptionA extends Exception {}
public class RunClass {
public static void main() {
try {
RunClass runClass = new RunClass();
runClass.doSomething();
} catch(ExceptionA eA) {
// Do ExceptionA related resolutions.
} catch(Exception e) {
// Do Exception related resolutions.
}
}
public doSomething() throws ExceptionA {
throw new ExceptionA();
}
}
但我看到了主要的 Spring 书籍,甚至在互联网教程中提到了 Spring-boot 并且在微服务的上下文中总是从 RuntimeException class 扩展,即使@ControllerAdvice.
这明显违反了 Java 异常处理基础知识。但是仍然有一个论点说,它是用RuntimeException扩展的,因为这个异常是由@ExceptionHandler方法处理的,它是在运行时生成和处理的。
仍然,由于 RuntimeException 的这个扩展使得编译时异常处理轨迹不可见,并且很难追溯异常是如何抛出的。由于这些原因,我仍然相信,遵循基本的 Java 已检查和未检查异常处理概念仍然使用 @ExceptionHandler 方法。
例如:
public class ExceptionRA extends RuntimeException {}
@ContollerAdvice
public class ExceptionHandler {
@ExceptionHandler(ExceptionRA.class)
public String handleException (Exception exception, Model model) {
return "exception";
}
}
@Controller
public class RunClass {
@RequestMapping("/url1")
public doSomething() {
throw new ExceptionRA();
}
}
我应该使用@ExcpetionHadler 遵循所有异常场景的扩展RuntimeException 还是使用@ExceptionHaldler 遵循基本的Java 检查和未检查机制?欢迎提出想法、建议和更正。
对 checked/unchecked 例外的偏好就像一种宗教。
您通常不会在自己的代码中调用控制器方法。通常你不会有这样的代码:
try {
runClass.doSomething();
} catch(ExceptionRA exra) {
// Handle handle handle
}
因此您不会直接从控制器方法抛出的检查异常中获利。他们不会强制任何检查处理,因为没有地方可以处理它们。因此,您也可以抛出未经检查的异常并缩短方法签名。从控制器方法中抛出检查异常没有附加值。
控制器调用的某些业务服务方法也可能抛出异常。这就引出了两个问题:
- 您应该在业务逻辑中使用检查异常还是未检查异常?
- 如果业务逻辑抛出已检查异常,是否应该将其包装为未检查异常?还是只是路过?
第一个问题的答案是 - 你不应该让这个决定受到你在控制器中所做的事情的影响。按照你的"exception religion"去做。如果您更喜欢检查异常,请使用检查异常,无论您是否在控制器中使用未检查异常。
第二个问题不行。假设您的业务逻辑抛出一个已检查的异常。如果此异常足以向调用者表示情况,则没有理由将其包装到任何其他异常中,无论是已检查还是未检查。如果您的业务异常没有向调用者正确解释情况,最好将其包装起来。然后,未经检查的异常将使您的签名更短。
现发表个人看法。除了编程错误之外,我通常更喜欢检查异常。我也在控制器中使用它们(不要介意有点长的方法签名)。
@ControllerAdvice
public class ExceptionController {
@ExceptionHandler(NotFoundException.class)
public ResponseEntity<List<ErrorDto>> handleNotFoundException(NotFoundException e){
final String message = "The provided id is not in DB" + e.getMessage() + " " + "not found";
final List<ErrorDto> errorDto = new ArrayList<>();
errorDto.add(new ErrorDto("400", message, e.getField()));
return new ResponseEntity<>(errorDto, HttpStatus.BAD_REQUEST);
}
============================================= =======================================
@Data
public class ErrorDto {
private String code;
private String message;
private String field;
}
============================================= =======================================
参考使用如下link:(一步步解释)
Java 异常处理分为错误、已检查异常和未检查异常。这个问题是关于异常的。
正常的Java异常处理是将Exceptionclass扩展为已检查的异常,并通过考虑异常层次结构按需处理。
例如:
public class ExceptionA extends Exception {}
public class RunClass {
public static void main() {
try {
RunClass runClass = new RunClass();
runClass.doSomething();
} catch(ExceptionA eA) {
// Do ExceptionA related resolutions.
} catch(Exception e) {
// Do Exception related resolutions.
}
}
public doSomething() throws ExceptionA {
throw new ExceptionA();
}
}
但我看到了主要的 Spring 书籍,甚至在互联网教程中提到了 Spring-boot 并且在微服务的上下文中总是从 RuntimeException class 扩展,即使@ControllerAdvice.
这明显违反了 Java 异常处理基础知识。但是仍然有一个论点说,它是用RuntimeException扩展的,因为这个异常是由@ExceptionHandler方法处理的,它是在运行时生成和处理的。
仍然,由于 RuntimeException 的这个扩展使得编译时异常处理轨迹不可见,并且很难追溯异常是如何抛出的。由于这些原因,我仍然相信,遵循基本的 Java 已检查和未检查异常处理概念仍然使用 @ExceptionHandler 方法。
例如:
public class ExceptionRA extends RuntimeException {}
@ContollerAdvice
public class ExceptionHandler {
@ExceptionHandler(ExceptionRA.class)
public String handleException (Exception exception, Model model) {
return "exception";
}
}
@Controller
public class RunClass {
@RequestMapping("/url1")
public doSomething() {
throw new ExceptionRA();
}
}
我应该使用@ExcpetionHadler 遵循所有异常场景的扩展RuntimeException 还是使用@ExceptionHaldler 遵循基本的Java 检查和未检查机制?欢迎提出想法、建议和更正。
对 checked/unchecked 例外的偏好就像一种宗教。
您通常不会在自己的代码中调用控制器方法。通常你不会有这样的代码:
try {
runClass.doSomething();
} catch(ExceptionRA exra) {
// Handle handle handle
}
因此您不会直接从控制器方法抛出的检查异常中获利。他们不会强制任何检查处理,因为没有地方可以处理它们。因此,您也可以抛出未经检查的异常并缩短方法签名。从控制器方法中抛出检查异常没有附加值。
控制器调用的某些业务服务方法也可能抛出异常。这就引出了两个问题:
- 您应该在业务逻辑中使用检查异常还是未检查异常?
- 如果业务逻辑抛出已检查异常,是否应该将其包装为未检查异常?还是只是路过?
第一个问题的答案是 - 你不应该让这个决定受到你在控制器中所做的事情的影响。按照你的"exception religion"去做。如果您更喜欢检查异常,请使用检查异常,无论您是否在控制器中使用未检查异常。
第二个问题不行。假设您的业务逻辑抛出一个已检查的异常。如果此异常足以向调用者表示情况,则没有理由将其包装到任何其他异常中,无论是已检查还是未检查。如果您的业务异常没有向调用者正确解释情况,最好将其包装起来。然后,未经检查的异常将使您的签名更短。
现发表个人看法。除了编程错误之外,我通常更喜欢检查异常。我也在控制器中使用它们(不要介意有点长的方法签名)。
@ControllerAdvice
public class ExceptionController {
@ExceptionHandler(NotFoundException.class)
public ResponseEntity<List<ErrorDto>> handleNotFoundException(NotFoundException e){
final String message = "The provided id is not in DB" + e.getMessage() + " " + "not found";
final List<ErrorDto> errorDto = new ArrayList<>();
errorDto.add(new ErrorDto("400", message, e.getField()));
return new ResponseEntity<>(errorDto, HttpStatus.BAD_REQUEST);
}
============================================= =======================================
@Data
public class ErrorDto {
private String code;
private String message;
private String field;
}
============================================= =======================================
参考使用如下link:(一步步解释)