【发布时间】:2017-08-26 11:22:34
【问题描述】:
在 Spring 4.x 中,如果您使用扩展 ResponseEntityExceptionHandler 的 @RestControllerAdvise(或 @ControllerAdvice),则默认情况下不再为标记为的参数返回带有漂亮且信息丰富的 JSON 响应主体的默认异常处理@Valid.
在使用基于ResponseEntityExceptionHandler 的@RestControllerAdvice 时,如何获取要返回的默认 JSON 正文?
以下是描述此问题的简单但完整的示例。使用这些类:
@RestController
class CarsController {
@PostMapping("/cars")
public void createCar(@RequestBody @Valid Car car) {
System.out.println("Creating " + car);
throw new WhateverException();
}
@ExceptionHandler(WhateverException.class)
@ResponseStatus(HttpStatus.EXPECTATION_FAILED)
public void handleWhateverException(){
System.out.println("Handling a WhateverException.");
}
}
class Car {
@NotNull
private String make;
@NotNull
private String model;
...getter/setters omitted for brevity...
}
class WhateverException extends RuntimeException {}
如果您使用
向/cars 提交POST
{
"make": "BMW"
}
它以 400 和以下正文进行响应:
{
"timestamp": 1491020374642,
"status": 400,
"error": "Bad Request",
"exception": "org.springframework.web.bind.MethodArgumentNotValidException",
"errors": [
{
"codes": [
"NotNull.car.model",
"NotNull.model",
"NotNull.java.lang.String",
"NotNull"
],
"arguments": [
{
"codes": [
"car.model",
"model"
],
"arguments": null,
"defaultMessage": "model",
"code": "model"
}
],
"defaultMessage": "may not be null",
"objectName": "car",
"field": "model",
"rejectedValue": null,
"bindingFailure": false,
"code": "NotNull"
}
],
"message": "Validation failed for object='car'. Error count: 1",
"path": "/cars"
}
但是,如果您将异常处理方法移到它自己的标记为 @RestControllerAdvice 的类中,该类从 ResponseEntityExceptionHandler 扩展而来,如下所示:
@RestControllerAdvice
class RestExceptionHandler extends ResponseEntityExceptionHandler {
@ExceptionHandler(WhateverException.class)
@ResponseStatus(HttpStatus.EXPECTATION_FAILED)
public void handleWhateverException(WhateverException e, HttpServletRequest httpServletRequest) {
System.out.println("Handling a WhateverException.");
}
}
你会得到一个带有空主体的400,这是由于ResponseEntityExceptionHandler提供了一个方法(handleMethodArgumentNotValid(..)),该方法在主体为null的地方构建了一个响应.
您将如何更改此 @RestControllerAdvice 类以触发发生的原始处理,该处理提供一个 JSON 正文来描述为什么提交的请求无效?
【问题讨论】:
-
这就是你的
RestExceptionHandler在现实中的样子吗?您是否出于演示目的截断了真实版本? -
我当然不能发布我的公司代码,所以这只是一个人为的例子来说明问题。
-
遇到了同样的问题。如果您已经解决了它或找到了不同的解决方案,它会对我有所帮助:)
-
不,我还没有解决这个问题。由于这种情况,我不得不放弃 Spring 的内置处理。如果有人确实解决了这个问题,那就太好了,因为我很想回去使用它。
标签: java spring spring-mvc spring-boot