我有一个简单的 Spring Rest Controller 并进行了一些验证。我的理解是验证失败会引发 MethodArgumentNotValidException。但是,我的代码会引发 BindException。在调试消息中,我还看到应用程序返回了一个空 ModelAndView。
为什么 Rest Controller 会抛出 BindException 或返回 null ModelAndView?
注意:我正在使用 curl 测试我的 Web 应用程序并进行 HTTP POST
curl -X POST http://localhost:8080/tasks
我故意省略了“名称”参数,这是一个用@NotNull 和@NotBlank 注释标记的必填字段。
我的控制器:
@RestController
public class TasksController {
private static Logger logger = Logger.getLogger(TasksController.class);
@Autowired
private MessageSource messageSource;
@Autowired
private Validator validator;
@InitBinder
protected void initBinder(WebDataBinder binder){
binder.setValidator(this.validator);
}
@RequestMapping(value = "/tasks", method = RequestMethod.POST)
public Task createTask(@Valid TasksCommand tasksCommand){
Task task = new Task();
task.setName(tasksCommand.getName());
task.setDue(tasksCommand.getDue());
task.setCategory(tasksCommand.getCategory());
return task;
}
}
我的“命令”类(包含验证注释)
public class TasksCommand {
@NotBlank
@NotNull
private String name;
private Calendar due;
private String category;
... getters & setters ommitted ...
}
我的 RestErrorHandler 类:
@ControllerAdvice
public class RestErrorHandler {
private static Logger logger = Logger.getLogger(RestErrorHandler.class);
@Autowired
private MessageSource messageSource;
@ExceptionHandler(MethodArgumentNotValidException.class)
@ResponseStatus(HttpStatus.BAD_REQUEST)
@ResponseBody
public ErrorsList processErrors(MethodArgumentNotValidException ex){
logger.info("error handler invoked ...");
BindingResult result = ex.getBindingResult();
List<FieldError> fieldErrorList = result.getFieldErrors();
ErrorsList errorsList = new ErrorsList();
for(FieldError fieldError: fieldErrorList){
Locale currentLocale = LocaleContextHolder.getLocale();
String errorMessage = messageSource.getMessage(fieldError, currentLocale);
logger.info("adding error message - " + errorMessage + " - to errorsList");
errorsList.addFieldError(fieldError.getField(), errorMessage);
}
return errorsList;
}
}
标有 @ExceptionHandler(...) 注释的 processErrors 方法永远不会被调用。如果我尝试使用 @ExceptionHandler(...) 注释来捕获 BindException,则该处理程序方法会被调用。
我有几个支持类——Task、TaskCommand、Error 和 ErrorsList——如果需要,我可以发布代码。