Spring Boot 中的生产级异常处理
Posted
技术标签:
【中文标题】Spring Boot 中的生产级异常处理【英文标题】:Production level Exception handling in spring boot 【发布时间】:2018-08-17 01:01:14 【问题描述】:我有一个场景:
UI<--->Spring boot micro-service REST API<--->server
现在,有一种情况我想处理自定义异常(我知道该怎么做),以便在服务器以某种方式响应时将特定的 Http 状态和消息返回给 UI,例如500 应该返回“请稍后返回”而不是“内部服务器错误”。我们微服务的 maven 项目分为 3 层(子 maven 项目),即 Business、Web 和 Domain。其中 web 包含控制器类,Business 包含 Service 类,Domain 包含 @Entity、@Components 等。
我想知道为了处理上面提到的异常,比如说 HTTP 状态 500,应该在业务层完成吗?或在 web 层,即控制器级别。什么是最好的解决方案? (我知道 ResponseEntity 以及它如何为 UI 提供自定义响应)。
我个人认为,如果我在业务级别包含自定义异常类,并在检查响应状态后使用响应实体在控制器类中返回它,就可以解决问题。但官员们觉得应该在服务层面上做吗?我不明白为什么(它使过程更复杂)?谁能建议哪种解决方案最好?
【问题讨论】:
【参考方案1】:如果你想在全局级别处理错误,你可以使用@ControllerAdvice,这在处理自定义异常和运行时异常时非常容易。
您可以从业务层向 Web 控制器抛出异常,并定义一个 @ControllerAdvice 类来捕获这些错误并提供具有正确响应状态的响应。
例如:-
@ControllerAdvice
public class RestResponseEntityExceptionHandler extends ResponseEntityExceptionHandler
@ExceptionHandler(value = IllegalArgumentException.class, IllegalStateException.class )
protected ResponseEntity<Object> handleConflict(RuntimeException ex, WebRequest request)
String bodyOfResponse = "This should be application specific";
return handleExceptionInternal(ex, bodyOfResponse,
new HttpHeaders(), HttpStatus.CONFLICT, request);
并从控制器类中抛出这些异常类,您不需要从控制器中捕获异常。
希望对你有帮助...
我从here获取的代码片段
【讨论】:
【参考方案2】:官方说的没错,应该是在服务层。我想说最好的做法是使用@ExceptionHandler。由于在控制器方法中处理异常的缺点是它会降低代码的可读性,并且可能会在许多控制器方法中重复。
我建议为您的控制器创建一个基类,并定义 @ExceptionHandler。通过这种方式,它可以用于许多不同的控制器,而无需任何代码重复。这将比异常解析器方法更具可读性,但可以结合使用 这个解释清楚了here
【讨论】:
谢谢!!这篇博客帮助我理解了不在控制器级别处理异常背后的逻辑。【参考方案3】:错误响应通常由匹配您的异常类型的@ExceptionHandler
生成,并且可能按照here 的描述向@ConrtrollerAdvice
注册。
API 应标准化(例如http://jsonapi.org/)并主要为开发人员设计。返回“请稍后返回”而不是“内部服务器错误”对我来说毫无意义。这是一个不确定原因的 500 HTTP 状态响应,例如NullPointerException
在代码深处。
【讨论】:
以上是关于Spring Boot 中的生产级异常处理的主要内容,如果未能解决你的问题,请参考以下文章