Java 空请求正文没有被 Spring @RequestBody @Valid 注释捕获
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/23301070/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Null request body not getting caught by Spring @RequestBody @Valid annotations
提问by Zasrin
I am currently running into an issue with the @RequestBody
annotation in Spring. I currently have all my validation annotations set up on my models properly, and they work great when an object is POSTed. Everything works as expected even when the request body posted is completely empty or an empty object "{}". The problem arises when someone tries to post a request body of "null". This somehow gets through the @Valid
annotation and is not caught, causing a NullPointerException
when I try to access the object. I have pasted a snippet of my controller below.
我目前遇到了@RequestBody
Spring 中的注释问题。我目前在我的模型上正确设置了所有验证注释,并且在发布对象时它们工作得很好。即使发布的请求正文完全为空或空对象“{}”,一切都按预期工作。当有人尝试发布“null”的请求正文时,就会出现问题。这以某种方式通过@Valid
注释并没有被捕获,导致NullPointerException
当我尝试访问该对象时。我在下面粘贴了我的控制器的片段。
@Secured({ ROLE_ADMIN })
@RequestMapping(method = RequestMethod.POST, consumes = { MediaType.APPLICATION_JSON_VALUE } )
public HttpEntity<Resource<Item>> addItem(@RequestBody @Valid Item item) throws Exception {
Resource<Item> itemResource = this.itemResourceAssembler.toResource(this.itemService.save(item));
return new ResponseEntity<Resource<Item>>(itemResource, HttpStatus.CREATED);
}
I do some checks in itemService.save()
to see if an item exists in the database already, since this is being used as an upsert. When I access the item passed to save I get the NullPointerException
because item is null. I've tried using the "required" parameter of @RequestBody
but that only checks to see if there was something POSTed. As stated above, the null item is only passed through when a user posts "null" without the quotes as the request body. Is there a automated Spring annotation or configuration to stop this null from being passed through, or should I just put if(item == null) throw new Exception();
in all of my controllers where this could crop up?
我做了一些检查itemService.save()
以查看数据库中是否已经存在一个项目,因为它被用作 upsert。当我访问传递给保存的项目时,我得到了NullPointerException
因为项目为空。我试过使用“必需”参数,@RequestBody
但只检查是否有发布的东西。如上所述,只有当用户发布不带引号的“null”作为请求正文时,才会传递空项目。是否有自动的 Spring 注释或配置来阻止传递这个空值,或者我应该把if(item == null) throw new Exception();
我的所有控制器放在可能会突然出现的地方?
采纳答案by rkaltreider
By the looks of the code snippet you posted, you have a clearly defined service layer. I would suggest using method level validation in you service as follows
从您发布的代码片段的外观来看,您有一个明确定义的服务层。我建议在您的服务中使用方法级别验证,如下所示
@Validated
public interface ItemService {
public Item save(@NotNull Item item);
If your using spring's XML config add this to your app's context xml.
如果您使用 spring 的 XML 配置,请将其添加到您的应用程序的上下文 xml 中。
<bean id="validator" class="org.springframework.validation.beanvalidation.LocalValidatorFactoryBean"/>
<bean class="org.springframework.validation.beanvalidation.MethodValidationPostProcessor"/>
a MethodConstraintViolationException will be thrown that could be caught in a @ControllerAdvice if you have that defined.
将抛出 MethodConstraintViolationException ,如果您定义了该异常,则该异常可能会在 @ControllerAdvice 中捕获。
@ExceptionHandler(MethodConstraintViolationException.class)
Happy Coding!
快乐编码!
回答by Sotirios Delimanolis
According to the JSON specification, null
is a valid value. Hymanson, which Spring uses behind the scenes, deserializes a null
JSON value to a Java null
reference.
根据JSON 规范,null
是一个有效值。Spring 在幕后使用的 Hymanson 将null
JSON 值反序列化为Javanull
引用。
You'll have to do what you described and check for it in your controller. Alternatively, you can create your own HandlerMethodArgumentResolver
to do that for you.
您必须按照您的描述进行操作并在控制器中检查它。或者,您可以创建自己的HandlerMethodArgumentResolver
来为您执行此操作。
回答by a better oliver
Let's put it this way: If an object doesn't exist, then it can't be invalid.
这么说吧:如果一个对象不存在,那么它就不能是无效的。
@Valid
only causes Spring to check if the item
object complies with some rules. It doesn't check if it's there. If the request body is empty or an empty object then the process stops beforevalidation. For in the default setup of Spring and Hymanson those two cases are not allowed.
@Valid
只会让 Spring 检查item
对象是否符合某些规则。它不会检查它是否在那里。如果请求正文为空或空对象,则该过程在验证之前停止。因为在 Spring 和 Hymanson 的默认设置中,这两种情况是不允许的。
So you can either check for null or write an extension, as @Sotirios Delimanolis has pointed out.
因此,正如@Sotirios Delimanolis 指出的那样,您可以检查 null 或编写扩展名。