【发布时间】:2014-08-21 19:05:29
【问题描述】:
我几乎没有通过 Spring 实现的 Rest web 服务。问题是,如果抛出任何异常,webservice 会返回带有格式化错误消息的 json 对象,其中包含堆栈跟踪。我可以单点处理异常,并返回带有不包含堆栈跟踪的消息的自定义 json 对象吗?
我看到了 spring mvc 的描述,但我并没有真正使用它来构建我的视图等。
【问题讨论】:
标签: spring rest exception-handling
我几乎没有通过 Spring 实现的 Rest web 服务。问题是,如果抛出任何异常,webservice 会返回带有格式化错误消息的 json 对象,其中包含堆栈跟踪。我可以单点处理异常,并返回带有不包含堆栈跟踪的消息的自定义 json 对象吗?
我看到了 spring mvc 的描述,但我并没有真正使用它来构建我的视图等。
【问题讨论】:
标签: spring rest exception-handling
我知道为时已晚,但只是指出一些可能对其他人有所帮助的解决方案!
案例 1:如果您使用的是 application.properties 文件,请将以下行添加到您的属性文件中。
server.error.include-stacktrace=on_trace_param
案例 2:如果您使用的是 application.yml 文件,请将以下行添加到您的 yml 文件中。
server:
error:
include-stacktrace: on_trace_param
案例 3:如果它们都不起作用,请尝试以下更改:
尝试通过覆盖异常类中的fillInStackTrace 方法来抑制堆栈跟踪,如下所示。
public class DuplicateFoundException extends RuntimeException {
@Override
public synchronized Throwable fillInStackTrace() {
return this;
}
}
ps1:我提到了this article。
【讨论】:
on_trace_param 时遇到了一个异常,但在仅使用on_param 时似乎可以正常工作。看到这个页面:docs.spring.io/spring-boot/docs/current/api/org/springframework/…
Spring 提供了一个开箱即用的解决方案,可以从一个点处理所有自定义异常。您需要的是异常控制器中的 @ControllerAdvice 注释:
@ControllerAdvice
public class GlobalDefaultExceptionHandler {
@ExceptionHandler(Exception.class)
public String exception(Exception e) {
return "error";
}
}
如果您想深入了解 Springs @ExceptionHandler 在单个控制器级别或 @ControllerAdvice 在全局应用程序级别 here 是一个很好的博客。
【讨论】:
要在单个点处理从 Spring 应用程序抛出的异常,这是最好的方法。 @ControllerAdvice 将创建一个切面连接点,它将拦截所有绑定到相应公共方法的所需匹配类型的异常。这里,公共 ResponseEntity handleDataIntegrityViolationException(DataIntegrityViolationException dataIntegrityViolationException, WebRequest 请求)正在处理一处从系统抛出的 DataIntegrityViolationException。
@ControllerAdvice
public class GlobalControllerExceptionHandler {
private Logger logger = Logger.getLogger(this.getClass());
private HttpHeaders header = new HttpHeaders();
@Autowired
private MessageSource messageSource;
public GlobalControllerExceptionHandler() {
header.set(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_JSON_VALUE);
}
/**
* @param dataIntegrityViolationException
* @param request
* @return
*/
@ExceptionHandler({ DataIntegrityViolationException.class })
public ResponseEntity<?> handleDataIntegrityViolationException(DataIntegrityViolationException dataIntegrityViolationException,
WebRequest request) {
String message = ExceptionUtils.getMessage(dataIntegrityViolationException);
logger.error("*********BEGIN**************DataIntegrityViolationException******************BEGIN*******************\n");
logger.error(message, dataIntegrityViolationException.fillInStackTrace());
logger.error("*********ENDS**************DataIntegrityViolationException*******************ENDS*****************************\n");
return ResponseEntity.status(HttpStatus.CONFLICT).headers(header).body(dataIntegrityViolationException);
}
}
【讨论】: