I am struggling to define where the validation process would be better placed in the different layers of the application? (I am not talking about user input validation here, I'm really talking about the object consistency).
A simple case:
Blog
entity which has a field List<Comment>
, and a method boolean addComment(Comment comment)
comment
parameter of the boolean addComment(Comment comment)
is null
, which would return false
To me, such a check could be done in both the Service
and Entity
layers to ensure that everything is consistent at any layer.
But it seems redundant and something tells me that only one layer should have that responsability.
I would say the highest one in the stack, thus the Service
layer should do this validation? But when I'm writing my unit tests, it feels wrong to not make that check again in the Entity
layer.
My recommendation is to put these at the "public" interfaces to the services. With any public method you can't give any kind of guarantees as to the quality of input.
Here is the reasoning:
The easiest way to enforce this logic is to create an aspect and put the validation code in there.
<aop:aspect ref="validator" order="3">
<aop:before method="doValidation" pointcut="execution(public * com.mycompany.myapp.services.*.*(..))"/>"/>
</aop:aspect>
So, this aspect bean example covers all public methods in the service layer.
@Aspect
public class ServiceValidator{
private Validator validator;
public ServiceValidator() {
}
public ServiceValidator(Validator validator) {
this.validator = validator;
}
public void doValidation(JoinPoint jp){
for( Object arg : jp.getArgs() ){
if (arg != null) {
// uses hibernate validator
Set<ConstraintViolation<Object>> violations = validator.validate(arg);
if( violations.size() > 0 ){
// do something
}
}
}
}
}
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.