Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Spring @Validated in service layer

Hej,

I want to use the @Validated(group=Foo.class) annotation to validate an argument before executing a method like following:

public void doFoo(Foo @Validated(groups=Foo.class) foo){} 

When i put this method in the Controller of my Spring application, the @Validated is executed and throws an error when the Foo object is not valid. However if I put the same thing in a method in the Service layer of my application, the validation is not executed and the method just runs even when the Foo object isn't valid.

Can't you use the @Validated annotation in the service layer ? Or do I have to do configure something extra to make it work ?

Update:

I have added the following two beans to my service.xml:

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

and replaced the @Validate with @Null like so:

public void doFoo(Foo @Null(groups=Foo.class) foo){} 

I know it is a pretty silly annotation to do but I wanted to check that if I call the method now and passing null it would throw an violation exception which it does. So why does it execute the @Null annotation and not the @Validate annotation ? I know one is from javax.validation and the other is from Spring but I do not think that has anything to do with it ?

like image 420
Tom Avatar asked Oct 17 '13 11:10

Tom


People also ask

What is the use of @validated in Spring boot?

@Validated annotation is a class-level annotation that we can use to tell Spring to validate parameters that are passed into a method of the annotated class. @Valid annotation on method parameters and fields to tell Spring that we want a method parameter or field to be validated.

What is the use of @validated annotation?

The @Valid annotation ensures the validation of the whole object.

What is the use of service layer in Spring boot?

A service layer is a layer in an application that facilitates communication between the controller and the persistence layer. Additionally, business logic is stored in the service layer. It includes validation logic in particular. The model state is used to communicate between the controller and service layers.

Should I validate in controller or service?

As a general rule of thumb, I would say that business logic of this sort should be in the service. Controllers should be light-weight and pass on requests. Further, there may be other clients of your service, not just controllers, so this allows you to keep validation in one place.


1 Answers

In the eyes of a Spring MVC stack, there is no such thing as a service layer. The reason it works for @Controller class handler methods is that Spring uses a special HandlerMethodArgumentResolver called ModelAttributeMethodProcessor which performs validation before resolving the argument to use in your handler method.

The service layer, as we call it, is just a plain bean with no additional behavior added to it from the MVC (DispatcherServlet) stack. As such you cannot expect any validation from Spring. You need to roll your own, probably with AOP.


With MethodValidationPostProcessor, take a look at the javadoc

Applicable methods have JSR-303 constraint annotations on their parameters and/or on their return value (in the latter case specified at the method level, typically as inline annotation).

Validation groups can be specified through Spring's Validated annotation at the type level of the containing target class, applying to all public service methods of that class. By default, JSR-303 will validate against its default group only.

The @Validated annotation is only used to specify a validation group, it doesn't itself force any validation. You need to use one of the javax.validation annotations like @Null or @Valid. Remember that you can use as many annotations as you would like on a method parameter.

like image 163
Sotirios Delimanolis Avatar answered Oct 02 '22 23:10

Sotirios Delimanolis