Vraptor Simple Validator
##Downloading directly or using it through Maven
For a quick start, you can use this snippet in your maven POM:
<dependency>
<groupId>br.com.caelum.vraptor</groupId>
<artifactId>vraptor-simple-validator</artifactId>
<version>4.1.0-RC2</version> <!--or the latest version-->
</dependency>
##How to use
1 - Inject the SimpleValidator at your controller:
@Controller
public class DogController {
private SimpleValidator validator;
public DogController(SimpleValidator validator){
this.validator = validator
}
}
2 - Call validator.validate on the desired action.
The first argument is the object that you want to validate and the second is the ValidationStrategy.
By the way, the vraptor-simple-validator provides a diversity of defaults validations that you may want to use.
You can access them through static methods of the class ValidationStrategies Curretly, the following validations are implemented:
matches("someString")- Check if theStrings are equals to each othernotEmpty()- Check if the givenListis not emptynotEmptyNorNull()- Check if the givenStringis not empty/nullnotNull()- Check if the givenObjectis not nulllessThan(12l)- Check if the givenlongis less than 12biggerThan(12l)- Check if the givenlongis bigger than 12lengthLessThan(12l)- Check if the givenStringhas length less than 12.lengthBiggerThan(12l)- Check if the givenStringhas length bigger than 12.
When using them you will need to tell which message.properties key you want to use on error. The validation call will as simple as that:
validator.validate(dog.getName(), ValidationStrategies.matches("Bob").key("wrong.name"));
It is also very simple to use more than one ValidationStrategy at an object:
validator.validate(dog.getName(),
matches("Bob").key("wrong.name"),
notNull().key("null.name")
);
And to validate more than one object:
validator.validate(dog.getName(), matches("Bob").key("wrong.name"))
.validate(dog.getNumberOfPaws(), lessThan(4l).key("mutant.dog"));
You can create a custom ValidationStrategy in a very simple way, this will be covered later.
3 - Specify where to go when the validation fail.
This is just like you would do with the default vraptor Validator:
validator.validate(dog.getName(), matches("Bob").key("wrong.name"))
.onErrorRedirectTo(this).createDog();
4 - Optional: Tell the validator to add a confirmation message if everything goes fine.
validator.validate(dog.getName(), matches("Bob").key("name.should.be.bob"))
.onSuccessAddConfirmationMessage("confirmation.key")
.onErrorRedirectTo(this).createDog();
5 - Display errors or confirmation in view.
The list of errors will be automatically inserted on the request with the name errors, you will only need to iterate that list:
<c:if test="${not empty errors}">
<ul class="error-messages">
<c:forEach var="error" items="${errors}">
<li class="${error.category}">${error.message}</li>
</c:forEach>
</ul>
</c:if>
The confirmation will be inserted with the name confirmations:
<c:if test="${not empty confirmations}">
<ul class="confirmation-messages">
<c:forEach var="confirmation" items="${confirmations}">
<li class="${confirmation.category}">${confirmation.message}</li>
</c:forEach>
</ul>
</c:if>
Tip: of course, the structure is exactly the same, so you can create a taglib to avoid copy/paste.
##Creating a custom ValidationStrategy
To create a ValidationStrategy, only need to create a class annotated with @Component that implements CustomValidationStrategy<Something> and implement the method addErrors as you desire:
@Component
public class DogValidator implements CustomValidationStrategy<Dog> {
@Override
public void addErrors(Dog dog) {
if(dog == null)
//add some error message
else if(dog.getNumberOfPaws() < 4)
//add some alert message
}
}
Tip: Yep, it is a vraptor component, so you can inject whatever you want at its constructor.
Then inject an instance of ValidationStrategyHelper at your ValidationStrategy so you can add messages calling addError, addAlert or addConfirmation on it:
@Component
public class DogValidator implements CustomValidationStrategy<Dog> {
private final ValidationStrategyHelper helper;
public DogValidator(ValidationStrategyHelper helper) {
this.helper = helper;
}
@Override
public void addErrors(Dog dog) {
if(dog == null)
helper.addError("invalid.dog");
else if(dog.getNumberOfPaws() < 4)
helper.addAlert("dog.has.less.than.4.paws", dog.getNumberOfPaws());
}
}
The difference between addError, addAlert is just the category(error or alert) and the list that it'll be included at the view (errors or alerts).
The confirmation will be included at the confirmations list.
To use the custom strategy, just pass its class to the validator:
validator.validate(dog, DogValidator.class)
.onSuccessAddConfirmationMessage("confirmation.key")
.onErrorRedirectTo(this).createDog();
##What happens when a validation fails?
1 - The program flow will be interrupted.
What does it mean? Well, you don't need to place an if verifying if the validation was ok or something like that. You can just call the validator:
public void newDog(Dog dog) {
validator.validate(dog, DogValidator.class)
.onSuccessAddConfirmationMessage("confirmation.key")
.onErrorRedirectTo(this).createDog();
dogs.save(dog); // This line won't be executed if the validation fails
}
2 - The db transaction will rollback
If you use vraptor-hibernate or vraptor-jpa to controll the transaction for you, it will rollback if there are validation errors
public void newDog(Dog dog) {
dogs.save(dog) // The dog won't be saved if validation fails
validator.validate(dog, DogValidator.class)
.onSuccessAddConfirmationMessage("confirmation.key")
.onErrorRedirectTo(this).createDog();
}
3 - The errors will be included at your jsp
All the validation errors will be automatically included at the list ${errors} and alerts will be included at the list ${alerts} on your jsp.