我正在尝试将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。相反,我可以让每个控制器端点直接调用验证器。
答案 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);
}
}