【问题标题】:Spring @ExceptionHandler does not return content unless body is emptySpring @ExceptionHandler 不返回内容,除非 body 为空
【发布时间】:2018-03-21 03:18:01
【问题描述】:

我正在使用 Spring @ControllerAdvice 来处理异常

@ControllerAdvice
public class RestResponseEntityExceptionHandler extends ResponseEntityExceptionHandler {


    @ExceptionHandler(value = { DataIntegrityViolationException.class})
    @ResponseBody
    public ResponseEntity<String> unknownException(Exception ex, WebRequest req) {
        return new ResponseEntity<>(ex.getCause().getMessage(), new HttpHeaders(), HttpStatus.INTERNAL_SERVER_ERROR);

    }

我遇到的问题是当异常发生时(当我通过 swagger 发送请求时),我没有收到预期的异常消息,但是:

{"error": "no response from server"}
Response Code : 0
Response Body : No Content

在调试模式下可以清楚的看到@ExceptionHandler注解的方法被调用了。

我已经尝试过方法返回类型、@ResponseBody@ResponseStatus 注释和其他一些想到的东西,但是当我返回 ResponseEntity 而没有一个身体,例如

 ResponseEntity.noContent().build()

ResponseEntity.ok().build()

在这种情况下,我会得到正确的 http 代码和一些标头

请告知我做错了什么

  • 春季版 4.3.9
  • Spring Boot 1.5.4 版

提前谢谢你

UPD

我进行了实验,这是对我有用的解决方案。 它非常接近其中一个答案 - 我会将其标记为已接受

简而言之,我刚刚创建了自己的 dto 类,用我感兴趣的异常详细信息填充实例并直接返回它 我的代码

@ExceptionHandler(value = { DataIntegrityViolationException.class})
@ResponseStatus(code = HttpStatus.INTERNAL_SERVER_ERROR)
@ResponseBody
public ExceptionDetailHolder unknownException(Exception ex, WebRequest req) {
    final Throwable cause = ex.getCause();
    return new ExceptionDetailHolder("Error interacting with the database server",
                                     cause.getClass() + ":" + cause.getMessage(),
                                     cause.getCause().getClass() + ":" + cause.getCause().getMessage()
                                    );
}

@AllArgsConstructor
@NoArgsConstructor
@Getter
@Setter
private class ExceptionDetailHolder {
    private String message;
    private String exceptionMessage;
    private String innerExceptionMessage;
}

结果(还显示评论者询问的 ex.getMessage 和 ex.getCause().getMessage() 的内容):

{
  "message": "Error interacting with the database server",
  "exceptionMessage": "class org.hibernate.exception.ConstraintViolationException:could not execute statement",
  "innerExceptionMessage": "class com.mysql.jdbc.exceptions.jdbc4.MySQLIntegrityConstraintViolationException:Column 'allow_copay_payments' cannot be null"
}

【问题讨论】:

  • 能否将Exception ex, WebRequest req这两个参数的值打印并分享到控制台中? .考虑打印ex.getMessage() ex.getCause().getMessage() 也可以看出区别。之后,考虑删除@ResponseBody(它如何进行第二次测试)
  • 你能分享一下你在ex.getCause().getMessage() in unknownException() 方法中的期望和得到什么吗?

标签: java spring spring-mvc exception


【解决方案1】:

我处理异常的方式如下,我找到具体的异常,然后在这种情况下创建自己的类对象ValidationErrorDTO,然后在该类中填充必填字段(ValidationErrorDTO):

@ExceptionHandler(HttpMessageNotReadableException.class)
    @ResponseStatus(HttpStatus.BAD_REQUEST)
    @ResponseBody
    public ResponseEntity<ValidationErrorDTO> processValidationIllegalError(HttpMessageNotReadableException ex,
            HandlerMethod handlerMethod, WebRequest webRequest) {

        Throwable throwable = ex.getMostSpecificCause();
        ValidationErrorDTO errorDTO = new ValidationErrorDTO();
        if (throwable instanceof EnumValidationException) {

            EnumValidationException exception = (EnumValidationException) ex.getMostSpecificCause();

            errorDTO.setEnumName(exception.getEnumName());
            errorDTO.setEnumValue(exception.getEnumValue());
            errorDTO.setErrorMessage(exception.getEnumValue() + " is an invalid " + exception.getEnumName());
        }

        return new ResponseEntity<ValidationErrorDTO>(errorDTO, HttpStatus.BAD_REQUEST);
    }

【讨论】:

    猜你喜欢
    • 2016-08-05
    • 2018-11-07
    • 1970-01-01
    • 2017-12-30
    • 1970-01-01
    • 1970-01-01
    • 2021-04-01
    • 1970-01-01
    • 2021-11-14
    相关资源
    最近更新 更多