gpt4 book ai didi

java - 在 REST 应用程序中抛出 BindException 而不是 MethodArgumentNotValidException

转载 作者:塔克拉玛干 更新时间:2023-11-03 03:24:29 24 4
gpt4 key购买 nike

我有一个带有一些验证的简单 Spring Rest Controller 。我的理解是验证失败会抛出 MethodArgumentNotValidException。但是,我的代码反而抛出 BindException。在调试消息中,我还看到应用返回了一个空的 ModelAndView。

为什么 Rest Controller 会抛出 BindException 或返回 null ModelAndView?

注意:我正在使用 curl 测试我的 Web 应用程序并进行 HTTP POST

curl -X POST http://localhost:8080/tasks

我有意省略了“名称”参数,这是标有@NotNull 和@NotBlank 注释的必填字段。

我的 Controller :

@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 - 如果需要我可以发布代码。

最佳答案

问题出在我的 curl 命令上。

curl -d 发送内容类型“application/x-www-form-urlencoded”。因此,Spring 将数据解释为 Web 表单数据(而不是 JSON)。 Spring 使用 FormHttpMessageConverter 将 POST 的主体转换为域对象并导致 BindException。

我们想要的是让 Spring 将 POST 数据视为 JSON,并使用 MappingJackson2HttpMessageConverter 将 POST 的主体解析为对象。这可以通过使用 curl 命令指定“Content-Type” header 来完成:

curl -X POST -H "Content-Type: application/json" -d '{"name":"name1", "due":"2014-DEC-31 01:00:00 PDT", "category":"demo"}' http://localhost:8080/tasks

请参阅这篇文章了解如何使用 curl 发布 JSON 数据: How to POST JSON data with Curl from Terminal/Commandline to Test Spring REST?

此外,这里是有关 MessageConverters 的相关 Spring 文档: http://docs.spring.io/spring/docs/current/spring-framework-reference/html/mvc.html#mvc-ann-requestbody http://docs.spring.io/spring/docs/current/spring-framework-reference/html/remoting.html#rest-message-conversion

关于java - 在 REST 应用程序中抛出 BindException 而不是 MethodArgumentNotValidException,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23211076/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com