在SpringBoot 2.0.4.RELEASE中的RestController中捕获ArithmeticException

时间:2018-08-31 09:22:15

标签: java rest spring-mvc spring-boot

我有一个基本的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();

    }

3 个答案:

答案 0 :(得分:2)

也许piradian并没有特别指出,但是问题似乎出在handleInternal方法的返回类型上。在您提供的代码中,返回类型为BodyBuilder,并且您返回由ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR)返回的值。实际上,正如BodyBuilder名称所暗示的那样,它表示Builder pattern的实现。在这种情况下,您实际应该做的是:

return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).build();

然后将方法的返回类型更改为ResponseEntityResponseEntity<Object>(在您的情况下,主体为空,因此实际上没有太大区别)。

但是,考虑到您的示例中没有返回正文,并且您已经用@ResponseStatus(HttpStatus.INTERNAL_SERVER_ERROR)注释了您的方法,您所能做的就是将返回类型更改为void而不返回任何内容-这正是piradian的建议。这也应该工作。

答案 1 :(得分:1)

尝试一下:

@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);

}

答案 2 :(得分:-1)

  

使用这个

@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);
    }
}