【发布时间】:2020-05-19 21:14:43
【问题描述】:
当请求正文无效并且使用了@Valid(或@Validated)时,Spring 是否会抛出HttpRequestMethodNotSupportedException?我真的期待MethodArgumentNotValidException。
详细信息:我有一个基于 Spring-Boot 版本 2.2.4 构建的小型 REST 服务器。其中一种方法如下所示:
@PostMapping("/yapp")
public Yapp kickYapp(@Validated @RequestBody YappDescriptor yappDescriptor) {
logger.debug("kickYapp descriptor {}", yappDescriptor);
doWork(yappDescriptor);
}
YappDescriptor 具有“必需”之类的注释,但对于有效值、范围等没有任何注释。当我发布一个格式良好的 JSON 对象,其中包含 YappDescriptor POJO 中定义的所有必需字段的值时,找到了 Spring 控制器方法并按预期调用。
我尝试了几个错误场景:
1) 如果我 POST 一个格式正确的 JSON 对象,该对象的预期字段只有空值,则会按预期找到并输入该方法。
2) 如果我发布一个格式正确的 JSON 对象,其键与 POJO 的任何字段都不匹配,则找不到并输入该方法。在观看org.springframework.web.servlet.mvc.method.annotation.ResponseEntityExceptionHandler 课程时,我看到异常是HttpRequestMethodNotSupportedException,服务器回答 405“不支持请求方法'POST'”。
在这个控制器类中,kickYapp 是指定路径上唯一的 POST 映射方法,所以我认为这个答案相当混乱。虽然我肯定发送了一个错误的请求(意外数据),但我很惊讶我的 POST 映射方法没有找到并被调用。
这篇帖子Validating if request body in HTTP POST request is null in Spring Boot controller 建议我应该看到HttpMessageNotReadableException 这会有所帮助,但我从来没有遇到过这种异常。
关于 SO 的许多其他问题似乎与启用请求正文的验证有关,例如 Spring 4.1.7 validate request body ,但我似乎已经过去了。
提前感谢您帮助我了解此行为,并可能改进服务器以帮助我的用户更轻松地发现他们的错误(这节省了我的时间 :)。以为我可以扩展该方法以接受 BindingResult 参数并以这种方式报告错误,但如果从未输入控制器方法,那将是不可行的。
更新以响应 cmets:是的,我本可以使用 @Valid。在我的测试中注解@javax.validation.Valid 和@org.springframework.validation.annotation.Validated 效果一样,都开启了RequestBody参数的验证。
【问题讨论】:
-
我以为你只需要将
@Valid添加到控制器而不是@Validated。
标签: java spring spring-boot jackson-databind