-
Notifications
You must be signed in to change notification settings - Fork 7
v0.7.2 Documentation
Springjutsu Validation replaces standard JSR-303 validation annotations with robust XML validation definitions offering several possibilities not found in a standard bean validation library:
- Simple creation and definition of custom rules
- Options for form-specific contextual validation within Spring MVC and Spring Web Flow
- Execution of conditional validation rules based on the outcome of another rule
- Encapsulation of common patterns of multiple rules into reusable templates
- Programmatic access via Expression Language to request parameters and other request data
- Full i8n internationalization support by loading error messages and field labels from a spring message source
- Easily apply validation rules and conditional validation to collection members
In Springjutsu Validation all validation is comprised of combinations of rules.
<!-- A rule looks like this. -->
<rule path="address.zipCode" type="exactLength" value="5"/>
As you might guess, the above rule constrains a field named "zipCode" found on a sub-bean field named "address" to be exactly 5 characters long.
When a rule fails error messages are created by looking up message codes from a spring MessageSource using conventions which can be specified within the configuration options. This error message is registered as a field error on the standard Spring Errors object.
Let's assume that the address bean was of type org.mycompany.coolproject.model.PostalAddress in our project. Let's also assume we have the following message properties defined:
# look up error messages - errors.<rule type>
errors.exactLength={0} must be exactly {1} characters long.
# look up field labels - <simple class name>.<field name>
postalAddress.zipCode=Postal Code
Springjutsu Validation fills in the message args, and the generated error message is:
Postal Code must be exactly 5 characters long.
This is usage at its most basic. But, before looking at more advanced usage we'll cover how to acquire Springjutsu Validation and configure it for use within your application.
(Please note that Springjutsu Validation requires a minimum Spring Framework version of 3.1.0.RELEASE)
The first step in adding Springjutsu Validation to a project is to acquire the appropriate artifacts from Maven Central. The dependency is as follows:
<dependency>
<groupId>org.springjutsu</groupId>
<artifactId>validation</artifactId>
<version>0.7.2</version>
</dependency>
If you don't use maven for your dependencies, you can alternatively acquire the current validation jar directly from maven central: http://repo1.maven.org/maven2/org/springjutsu/validation/0.7.2/
Once the validation jar is safely nestled into your project, you can set it up as your default Validator with Spring by updating your Spring configuration thusly:
<?xml version="1.0" encoding="UTF-8"?>
<!-- Note the validation namespace added to spring namespaces -->
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:mvc="http://www.springframework.org/schema/mvc"
xmlns:validation="http://www.springjutsu.org/schema/validation"
xsi:schemaLocation="
http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.1.xsd
http://www.springframework.org/schema/mvc
http://www.springframework.org/schema/mvc/spring-mvc-3.1.xsd
http://www.springjutsu.org/schema/validation
http://www.springjutsu.org/schema/validation-0.7.2.xsd">
<!-- Create a springjutsu validation manager -->
<validation:configuration validatorName="springjutsuValidator" />
<!-- Enable Spring @MVC annotation driven controller model referencing our validator -->
<mvc:annotation-driven validator="springjutsuValidator"/>
<!-- Other beans... don't forget your message source! -->
</beans>
As you can see, a bean named "springjutsuValidator" is created by the validation:configuration namespace element, and is set as the default spring validator by name reference. For additonal information on registering MVC validators, consult the spring documentation: http://static.springsource.org/spring/docs/3.2.x/spring-framework-reference/htmlsingle/#validation-mvc-configuring
This is all the basic configuration that is required to begin using Springjutsu Validation. Configuration options accessible through the validation:configuration element will be shown in later sections.
Rules are defined in XML using the element. The only required attribute for a rule is the "type" attribute, which indicates the type of rule being evaluated. The attributes declarable for a rule are:
Attribute Name | Usage |
---|---|
type | Indicates the rule type being evaluated |
path | Indicates the path to the field being validated. When not specified, the root object under validation is passed to the rule instead of a specified field. Can also be an EL string. |
value | Indicates an argument to a rule. Can be a static string or an EL string. Can be left unspecified for rules not requiring an argument. |
message | Indicates an error message to display instead of the rule's default message. Use to customize the displayed message when the outcome of a rule has special meaning. |
errorPath | Overrides "path" attribute to indicate the field that should receive the error. Use to validate one field, but report the error on a different one. |
collectionStrategy | See Validating Collection Members. |
Several rules come built into Springjutsu Validation and are configured by default. These are:
Rule Type | Usage |
---|---|
alphabetic | Will pass if the model is either all letters, empty, or null |
alphanumeric | Will pass if the model is all letters and numbers, empty, or null |
Will pass if the model is a valid email address, empty, or null | |
maxLength | Will pass if the String value of the model is less than or equal to the number of characters specified by the argument, empty, or null |
minLength | Will pass if the String value of the model is greater than or equal to the number of characters specified by the argument, empty, or null |
numeric | Will pass if the model is all numbers, empty, or null |
required | Will pass if the model is neither null or empty |
notEmpty | Same as required but has better semantics for use in conditional validation |
matches | Will pass if the String value of the model is the same as the String value of the argument |
If you would prefer that the default rules not be registered, they can be disabled through the configuration element:
<validation:configuration validatorName="springjutsuValidator">
<validation:rules-config addDefaultRuleExecutors="false"/>
</validation:configuration>
A rule is evaluated using a class called a RuleExecutor. Springjutsu validation provides a few extension options for creating custom RuleExecutor classes:
Class Name | Purpose |
---|---|
org.springjutsu.validation.executors.RuleExecutor | This is the most basic interface. It provides a simple boolean validate method which accepts a model to be validated, and an optional argument, and should return true if the rule passed. |
org.springjutsu.validation.executors.ValidWhenEmptyRuleExecutor | This is a convenient extension point for creating validation rules that will pass when the model is null or empty. Use it to create rules that shouldn't fail when the model isn't present. The doValidate method has the same semantics as the RuleExecutor's validate method. |
org.springjutsu.validation.executors.RegexMatchRuleExecutor | This is a convenient extension point for creating rules which should simply require that the String value of model being validated should match a regular expression returned by the abstract getRegularExpression method. It is the basis of the alphabetic, numeric, and alphanumeric rules. |
An important note is that all Springjutsu Validation Rule Executors are registered as spring beans. This means they can have autowired dependencies injected from the Spring Container.
Let's say we're writing an issue tracker and have a field that allows the user to specify the username of an assignee. We need to ensure that the assignee for that username exists and is active. Let's create a rule executor to fulfill this requirement.
public class ValidUsernameRuleExecutor extends ValidWhenEmptyRuleExecutor {
@Autowired
private UserService userService; // pretending this is part of our project.
@Override
public boolean doValidate(Object model, Object argument) {
User user = userService.findByUsername((String) model);
return user != null && user.isActive();
}
}
There we go. One rule executor using autowired dependencies to validate that our username corresponds to an existing and active user. Next we need to register the RuleExecutor with Springjutsu validation. We have two options.
Option 1: Use the ConfiguredRuleExecutor annotation at the class level.
// Make our rule available using the rule type "validUsername"
@ConfiguredRuleExecutor(name="validUsername")
public class ValidUsernameRuleExecutor extends ValidWhenEmptyRuleExecutor {
// implementation
}
Option 2: Configure the RuleExecutor manually in XML.
<validation:configuration validatorName="springjutsuValidator">
<validation:rules-config addDefaultRuleExecutors="false">
<!-- Make our rule available using the rule type "validUsername" -->
<validation:rule-executor name="validUsername" class="com.mycompany.project.validation.ValidUsernameRuleExecutor" />
</validation:rules-config>
</validation:configuration>
An XML validation file is actually a spring bean definition file. Validation rules are declared on a per-class basis: our recommendation is to have one file per class. Since this means adding multiple bean definition files to your spring context, you may want to review Spring's documentation on constructing contexts from multiple files. The use of ANT paths is especially simple. http://static.springsource.org/spring/docs/3.2.x/spring-framework-reference/htmlsingle/#resources-app-ctx
Each class has its rules defined in an entity element.
<?xml version="1.0" encoding="UTF-8"?>
<beans:beans xmlns="http://www.springjutsu.org/schema/validation"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:beans="http://www.springframework.org/schema/beans"
xsi:schemaLocation="
http://www.springjutsu.org/schema/validation
http://www.springjutsu.org/schema/validation-0.7.2.xsd
http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.1.xsd">
<!-- Going to define rules for our Person class -->
<entity class="com.mycompany.project.model.Person">
<!-- and rules can go here -->
<rule path="firstName" type="alphabetic" />
<rule path="firstName" type="maxLength" value="50" />
<!-- etc... -->
</entity>
</beans:beans>
For focus and brevity, the following examples will assume the above namespaces and wrapping beans:beans element are present, and include instead only the entity elements.