在不放入参数列表的情况下访问Spring WebDataBinder的BindingResult

时间:2019-05-01 20:04:54

标签: java spring

我正在尝试将Spring验证与swagger-codegen生成的控制器接口一起使用。摇摇欲坠的代码生成为控制器提供了一个抽象类。我们的控制器实现了codegen类并提供了实际的逻辑。我想在控制器方法中访问BindingResult,但是swagger-codegen不会在其接口中生成该参数。除了将BindingResults对象指定为参数外,是否有其他方法?

为了更具体一点,代码生成器使端点如下所示(删除了嘈杂的代码):

    @RequestMapping(value = "/api/repository/v1/datasets",
        produces = { "application/json" }, 
        consumes = { "application/json" },
        method = RequestMethod.POST)
    default ResponseEntity<JobModel> createDataset(@Valid @RequestBody DatasetRequestModel dataset) {
...
}

我们使用通常的活页夹设置来实现一个控制器,例如:

@InitBinder
protected void initBinder(final WebDataBinder binder) {
    binder.addValidators(requestValidator)
}

但是在端点内,我们无法获得BindingResult,因为它必须与代码生成条目的签名匹配:

public ResponseEntity<StudySummaryModel> createStudy(@Valid @RequestBody StudyRequestModel studyRequest) {
...
}

我认为最直接的解决方案可能是跳过使用WebDataBinder。相反,我可以让每个控制器端点直接调用验证器。

1 个答案:

答案 0 :(得分:0)

除了手动编码验证,我发现了另一种方法;使用扩展了ResponseEntityExceptionHandler的@ControllerAdvice类。

这里有一个很好的例子:Spring Validation Example

这是我基于该示例的代码,用于格式化错误:

@ControllerAdvice
public class ApiValidationExceptionHandler extends ResponseEntityExceptionHandler {

    @Override
    protected ResponseEntity<Object> handleMethodArgumentNotValid(
        MethodArgumentNotValidException ex,
        HttpHeaders headers,
        HttpStatus status,
        WebRequest request
    ) {
        BindingResult bindingResult = ex.getBindingResult();

        List<String> errorDetails = bindingResult
            .getFieldErrors()
            .stream()
            .map(err -> err.getCode() + " error on '" + err.getObjectName() + "': " + err.getDefaultMessage())
            .collect(toList());

        ErrorModel errorModel = new ErrorModel()
            .message("Validation errors - see error details")
            .errorDetail(errorDetails);

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