繁体   English   中英

为什么我在 tomcat 9 中收到代码 400 响应而不是错误 json object 和 Z2A2D595E6ED9A0B24D0ZB51?

[英]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 @ValidResponseEntityExceptionHandler#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注册一个异常处理程序。 尝试使用assignableTypesannotations

作为一个选项,您可以为不同的异常处理程序创建自定义注释。

以下代码在向/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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM