[英]Why am I getting code 400 response instead of error json object in tomcat 9 with spring 5?
controller:
@RestController
@RequestMapping(value = "/test", produces = MediaType.APPLICATION_JSON_VALUE)
@Validated
public class ApiController {
@PostMapping(value = "/in",
consumes = MediaType.APPLICATION_JSON_VALUE)
ResponseEntity<InitResponse> inPost(
@ApiParam(required = true) @Valid @RequestBody InRequest inRequest) {
LOG.info("inPost request was received = {}", inRequest);
return new ResponseEntity<>(HttpStatus.NOT_IMPLEMENTED);
}
异常处理程序:
@ControllerAdvice(assignableTypes = ApiController .class, annotations = RestController.class)
public class InExceptionHandler {
@ExceptionHandler(ConstraintViolationException.class)
public ResponseEntity<INErrors> handleConstraintViolation(ConstraintViolationException ex) {
LOG.info("handleConstraintViolation was trigerred");
INError INError = new INError(HttpStatus.BAD_REQUEST.toString(), ex.getLocalizedMessage());
return new ResponseEntity<>(new INErrors(), HttpStatus.BAD_REQUEST);
}
@ExceptionHandler(MethodArgumentNotValidException.class)
public ResponseEntity<INErrors> handleMethodArgumentConstraintViolation(MethodArgumentNotValidException ex) {
BindingResult result = ex.getBindingResult();
List<FieldError> fieldErrors = result.getFieldErrors();
return new ResponseEntity<>(processFieldErrors(fieldErrors), HttpStatus.BAD_REQUEST);
}
}
如果 InRequest 具有 javax 验证约束内的所有字段,那么我会得到正确的代码,但是当字段与验证不匹配时,我只会得到 400 响应代码。 定义了其他异常处理程序,但我已将断点放置在任何地方,并且没有触发任何内容。
我还添加了 log4j 属性:
log4j.logger.org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod=DEBUG,stdout
但这并没有在调试时产生任何额外的 output 。 我还希望将 INErrors object 发回,但它甚至没有进入两种处理方法中的任何一种。
这是因为 Spring 的默认异常处理程序自己处理所有 WebMvc 的标准异常,然后将未处理的异常委托给用户定义的@ExceptionHandler
方法。
在您的情况下, MethodArgumentNotValidException
@Valid
由ResponseEntityExceptionHandler#handleMethodArgumentNotValid
处理。 因此,要更改此异常的默认行为,您需要在@ControllerAdivce
中覆盖此方法。
@ControllerAdvice(assignableTypes = ApiController .class, annotations = RestController.class)
public class InExceptionHandler extends ResponseEntityExceptionHandler {
@Override
protected ResponseEntity<Object> handleMethodArgumentNotValid(MethodArgumentNotValidException ex, HttpHeaders headers, HttpStatus status, WebRequest request) {
BindingResult result = ex.getBindingResult();
List<FieldError> fieldErrors = result.getFieldErrors();
return ResponseEntity.badRequest().body(processFieldErrors(fieldErrors));
}
}
编辑:我看到您正在使用assignableTypes
和@ControllerAdvice
异常处理程序的annotations
。 这使得 Spring 为所有@RestController
注册一个异常处理程序。 尝试使用assignableTypes
或annotations
。
作为一个选项,您可以为不同的异常处理程序创建自定义注释。
以下代码在向/one
提供无效数据时打印“one”,在向“/two”发送数据时打印“two”。
@RestController
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@interface One {}
@RestController
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@interface Two {}
@One
class ControllerOne {
@PostMapping("one")
String a(@RequestBody @Valid Data data) {
return data.value;
}
}
@Two
class ControllerTwo {
@PostMapping("two")
String a(@RequestBody @Valid Data data) {
return data.value;
}
}
@ControllerAdvice(annotations = One.class)
class HandlerOne extends ResponseEntityExceptionHandler {
@Override
protected ResponseEntity<Object> handleMethodArgumentNotValid(MethodArgumentNotValidException ex, HttpHeaders headers, HttpStatus status, WebRequest request) {
return ResponseEntity.badRequest().body("one");
}
}
@ControllerAdvice(annotations = Two.class)
class HandlerTwo extends ResponseEntityExceptionHandler {
@Override
protected ResponseEntity<Object> handleMethodArgumentNotValid(MethodArgumentNotValidException ex, HttpHeaders headers, HttpStatus status, WebRequest request) {
return ResponseEntity.badRequest().body("two");
}
}
仅当我在 controller 中添加方法时,model 的 javax 注释样式验证才对我有用:
public class ApiController {
...
@ExceptionHandler(MethodArgumentNotValidException.class)
public ResponseEntity<INErrors> handleConstraintViolation(MethodArgumentNotValidException exception) {
BindingResult result = exception.getBindingResult();
List<FieldError> fieldErrors = result.getFieldErrors();
return new ResponseEntity<>(processFieldErrors(fieldErrors), HttpStatus.BAD_REQUEST);
}
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.