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 ?
@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.
The @Valid annotation ensures the validation of the whole object.
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.
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.
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With