Quote:
To answer you use case, as long as your controller is a POJO, you can apply the Bean Validation logic to it (as opposed to your domain model). In your case the UserRegistration could get its user field validated by bean validation (probably through an interceptor). In addition to that, Bean Validation will try to provide an API to validate method parameters (we need to sit down and design that though)
The code example (with the property attribute) is closer to what I'm getting at. Contextual beans with domain model beans as properties could superimpose validations down onto those beans. The contextual bean might be a Struts FormBean, a Stripes ActionBean or a Swing PresentationModel class.
Quote:
The drawback of this method is that your @Email annotation has to manually go apply the constraint to the property: there is no built-in system for it.
It would be fair to assume that this responsibility would be part of the UI framework, whether it be Spring MVC, Struts or a rich client platform shell like those derived from Eclipse or NetBeans. The UI framework would leverage validation annotations by evaluating them automatically and take care of mapping the errors to form fields etc.
Quote:
But I really don't full understand why a controller or a view should apply more rules than the model knows. What are the fundamental reason for doing so?
Encapsulation. I'd be keeping the validation rules for a certain context close to the place where they're relevant. And I'm not arguing that these additional validation rules should specifically go in the controller or view, just that there would be value in being able to superimpose them from some external bean. I already mentioned other reasons this would be desirable:
1. You might not have any control over the domain object in question.
2. The domain object might be a central part of a complex system where it is used in so many contexts that maintaining many different annotations and groups within that one class becomes too difficult.
Quote:
It's not as elegant as you cannot reuse it in a different controller / view (duplication). And let's imagine that a valid reason exists, it sounds that it would awfully look like a traditional business rule. A classing service class would serve this purpose quite well.
Let's be clear, I'm talking about things like "Not Null", "Valid Email" etc. and I'm arguing that groups should not be the only way to achieve contextual validation. For reuse, you would create a contextual shell bean that might represent, say, a commonly used form, or abstract parent to a set of similar forms. To make this work, the JSR-303 spec would need to explicitly include the "property" attribute as an optional parameter. The implementation would take the property string and apply the validation to the (arbitrarily deep) property.
Quote:
PS in your stripes example, it seems you are hijacking the converter infrastructure to do validation. That does not sound right :)
That is how it works with Stripes. The Stripes TypeConverter interface defines a means to collect validation errors and that is how all of Stripes standard validations work, and user-defined ones plug in the same way. Because Stripes maps strings from the HTTP request to bean properties, there will be times when a given type cannot be fulfilled because the string that's being converted is invalid. I didn't design it, but I presume this is why type conversion and validation are intertwined in Stripes.
Code:
public interface TypeConverter<T> {
// ... snip ...
T convert(String input, Class<? extends T> targetType, Collection<ValidationError> errors);
}
One last question: If I have a string property where in one context it must be at least 5 characters long, and in another context it must be at least 10 characters long, is JSR-303 as it currently stands able to support that?