The body of a null request does not fall under Spring @RequestBody @Valid annotations

I am currently facing a problem with @RequestBody annotation in Spring. Currently, I have all of my validation annotations installed on my models, and they work fine when the object is POSTED. Everything works as expected, even when the request body is sent as a completely empty or empty object "{}". The problem occurs when someone tries to send the request body "null". This somehow goes through the @Valid annotation and doesn't get caught, @Valid NullPointerException when trying to access the object. I pasted a snapshot of my controller below.

 @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 find out if an item already exists in the database since it is used as upsert. When I access the element passed for storage, I get a NullPointerException because the element is null. I tried using the "required" @RequestBody parameter, but it only checks if there is something POSTed. As indicated above, a null element is only transmitted when the user sends a β€œzero” without quotes as the body of the request. Is there an automatic annotation or Spring configuration to stop this null value, or should I just put if(item == null) throw new Exception(); to all my controllers, where can this happen?

+7
java null spring-mvc annotations request
source share
3 answers

By viewing the code fragment that you posted, you have a clearly defined level of service. I would suggest using method level checking in your service as follows

 @Validated public interface ItemService { public Item save(@NotNull Item item); 

If you are using spring XML configuration, add this to your xml application context.

 <bean id="validator" class="org.springframework.validation.beanvalidation.LocalValidatorFactoryBean"/> <bean class="org.springframework.validation.beanvalidation.MethodValidationPostProcessor"/> 

A MethodConstraintViolationException will be thrown, which can be detected in @ControllerAdvice if you have one defined.

 @ExceptionHandler(MethodConstraintViolationException.class) 

Happy coding!

+2
source share

According to the JSON specification , null is a valid value. Jackson, which Spring uses behind the scenes, deserializes the null JSON value for a Java null reference.

You will need to do what you described and check it in your controller. Alternatively, you can create your own HandlerMethodArgumentResolver to do this for you.

+2
source share

Let's just say: if the object does not exist, then it cannot be invalid.

@Valid calls Spring to check if the item object matches some rules. He does not check if there is. If the request body is empty or an empty object, the process stops until . If in the default settings Spring and Jackson these two cases are not resolved.

This way you can either check for null or write an extension as @Sotirios Delimanolis pointed out.

+1
source share

All Articles