我有一个基本的SpringBoot 2.0.4.RELEASE应用程序。使用Spring Initializer,JPA,嵌入式Tomcat,Thymeleaf模板引擎和包作为可执行的JAR文件。
我创建了这个类来管理异常:
@ControllerAdvice
@RestControllerAdvice
public class RestResponseEntityExceptionHandler extends ResponseEntityExceptionHandler {
public RestResponseEntityExceptionHandler() {
super();
}
// 500
@ExceptionHandler({ NullPointerException.class, IllegalArgumentException.class, IllegalStateException.class, RuntimeException.class })
/*500*/
@ResponseStatus(HttpStatus.INTERNAL_SERVER_ERROR)
public BodyBuilder handleInternal(final RuntimeException ex, final WebRequest request) {
logger.error("500 Status Code", ex);
return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR);
}
}
该方法处理RuntimeException,ArithmeticException扩展RuntimeException。
为了测试它,我创建了这个方法;
GetMapping(path = "/getUsers", consumes = "application/json", produces = "application/json")
public ResponseEntity<List<User>> testErrors(HttpServletRequest request) {
double ss = 3 /0;
return ResponseEntity.ok(userService.findAll());
}
期待这只会返回一个HttpStatus.INTERNAL_SERVER_ERROR
,但它返回“
{"timestamp":"2018-08-31T09:21:21.717+0000","status":500,"error":"Internal Server Error","message":"/ by zero","trace":"java.lang.ArithmeticException: / by zero\n\tat ...
用这种方法
@ExceptionHandler({ NullPointerException.class, IllegalArgumentException.class, IllegalStateException.class, RuntimeException.class })
/*500*/
public BodyBuilder handleInternal(final RuntimeException ex, final WebRequest request) {
logger.error("500 Status Code", ex);
return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR);
}
我有完整的痕迹:{"timestamp":"2018-09-03T07:04:58.803+0000","status":500,"error":"Internal Server Error","message":"/ by zero","trace":"java.lang.ArithmeticException: / by zero\n\tat
有了这个,我在控制台中看不到有任何卷曲:
@ExceptionHandler({ NullPointerException.class, IllegalArgumentException.class, IllegalStateException.class, RuntimeException.class })
/*500*/
@ResponseStatus(HttpStatus.INTERNAL_SERVER_ERROR)
public void handleInternal(final RuntimeException ex, final WebRequest request) {
logger.error("500 Status Code", ex);
}
而另一个,在控制台中也没有任何东西:
@ExceptionHandler({ NullPointerException.class, IllegalArgumentException.class, IllegalStateException.class, RuntimeException.class })
/*500*/
public ResponseEntity<Object> handleInternal(final RuntimeException ex, final WebRequest request) {
logger.error("500 Status Code", ex);
return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).build();
}
也许piradian没有具体指出它,但问题似乎是你的handleInternal
方法的返回类型。在您提供的代码中,返回类型为BodyBuilder
,并返回ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR)
返回的值。实际上,正如BodyBuilder
的名字所暗示的那样,它代表了Builder pattern的实现。在这种情况下你应该做的是:
return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).build();
并将方法的返回类型更改为ResponseEntity
或ResponseEntity<Object>
(在您的情况下,正文是空的,因此确实没有太大区别)。
但是,考虑到你的例子中没有返回任何体,你已经用@ResponseStatus(HttpStatus.INTERNAL_SERVER_ERROR)
注释了你的方法,你所能做的就是将返回类型改为void
而不返回任何东西 - 这正是piradian建议的。这也应该有用。
试试这个:
@ExceptionHandler({NullPointerException.class, IllegalArgumentException.class, IllegalStateException.class, RuntimeException.class})
/* 500 */
@ResponseStatus(HttpStatus.INTERNAL_SERVER_ERROR)
public void handleInternal(final RuntimeException ex, final WebRequest request) {
logger.error("500 Status Code", ex);
}
用这个
@RestControllerAdvice//insted of @ControllerAdvice
public class RestResponseEntityExceptionHandler extends ResponseEntityExceptionHandler {
@ExceptionHandler(value = { Exception.class, RuntimeException.class })
@ResponseStatus(HttpStatus.INTERNAL_SERVER_ERROR)
public BodyBuilder handleInternal(final RuntimeException ex, final WebRequest request) {
logger.error("500 Status Code", ex);
return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR);
}
}