Spring Boot Validation Strategy Before Deserialization

5k views Asked by At

I am using spring boot to run an API. I want to validate the user request parameters before deserialization to prevent jackson from throwing deserialization exceptions. My thinking is it's better to validate without exception handling but if you think I'm wrong please let me know.

Right now I made an exception handler controller with an @ControllerAdvice annotation to catch exceptions before they bubble up to the user but is there a way to validate user input before jackson deserialization to check for errors?

I started playing around with spring validation but if I write a custom validator and annotate the request parameters with @Validate does the validation take place before deserialization? Is spring validation the way to go?

I looked into validation with annotations (JSR 380) but I think I need more control over validation so that's why I'm writing my own custom validator.

I was thinking I could write a custom deserializer that calls my custom validator but is that the best way to do this. I'm looking for best practices and a good strategy for validation.

Thanks in advance for your help.

2

There are 2 answers

0
Sabir Khan On

I started playing around with spring validation but if I write a custom validator and annotate the request parameters with @Validate does the validation take place before deserialization? Is spring validation the way to go?

No, Validation happens after deserialization only as already answered by Mark Bramnik. You do it via Standard JSR validators or via Spring Specific , it will always happen after deserialization.

I was thinking I could write a custom deserializer that calls my custom validator but is that the best way to do this. I'm looking for best practices and a good strategy for validation.

There is no standard strategy for these things , all goes case by case basis. Sometimes, you need a custom validator and sometimes you don't. Sometimes, you need custom deserializer and sometimes you don't. Just try to satisfy your business requirements and everything else should start falling in line.

Now the interesting part ,

Right now I made an exception handler controller with an @ControllerAdvice annotation to catch exceptions before they bubble up to the user but is there a way to validate user input before jackson deserialization to check for errors?

Yes. there is a way and its called json schema validation ( i.e. you have a json schema file and you validate your raw json against it ) & as far as I know, that is mostly a slow moving field & most likely dead too. I wouldn't advise mixing Bean Validations ( validations that you do after deserialization using Jackson, GSON etc ) and schema validation - choose only one ( because your code shouldn't spend too much time doing only validations & there is too much overlap in objective of both approaches ) and I guess at most places bean validation is a preferred choice.

Schema validation has its own advantages that I can think of ,

1.Validation logic moves out of your REST business logic ( out from controllers, beans etc ) and your deserializer always gets validated JSON. Code looks more clean that way.

2.JSON validation logic change is handled without code recompilation as you simply need to update schema file. With Bean validations, you always need to recompile artifact.

3.Validating raw data as is would always be more accurate than validating after deserialization. An date string with invalid month from JSON might get translated into a valid Date object in Java.

4.Performance : As per most blogs I read, schema validation is faster than bean validation.

I am not sure though as why its not popular , probably Spring folks made writing validations too easy and maintaining a schema is difficult :)

Refer these SO QA & Links to understand more ,

How do I validate incoming JSON data inside a REST service?

Validate JSON against Schema in Java

Tool for JSON schema validation

Json schema validation in Spring REST APIs

As you might have felt by reading above that JSON schema validation is done in pure Java way instead of supported by Jackson or Spring Boot.

0
Mark Bramnik On

Spring Validation is an examination of Bean state. Bean class has annotations and they put some constraints on bean field values.

So in order to invoke the "validation process" the bean should already exist. Creation of bean out of string json/xml representation that comes along with request is exactly a deserialization process.

Hence the answer is that spring first deserializes the object by using some library (like jackson for example) and only then tries to validate an input by applying validation techniques.