Property annotations can be bound to the attribute, its getter or setter. It is not required to comply to the java properties standard (meaning that you can annotate a private field with no public getters or setters), but you may need to provide them anyway to use EL expressions like ${action.customer.name}
Validation annotations
Validation annotations are used to configure a Validator instance and bind it to some events. Since java does not allow attaching the same annotation more than once to the same java property, some of them include a "plural" form (StringValidations, NumberValidations).
- StringValidation: Validates string properties (minimum and maximum length, format mask, etc)
- RequiredValidation: Fails if the field is null or an empty String. It also works with empty arrays, Collections and Maps.
- NumberValidation: Validates number instances (double, BigDecimal, long, integer) for precision, scope, minimum and maximum values, etc. The default minimum value is 0, and float is specifically not supported because of its lack of precision.
- *DateValidation: Validates a java.util.Date, java.sql.Date, java.sql.Time, java.sql.Timestamp and Joda date types. Minimum and maximum values can be specified as absolute dates or relative to the current day ("today + 2d", "today - 5m").
Validators contribute their metadata to JSP tags bound to the same property. For example, a validator that knows the maximum length of a field will contribute the maxlength attribute, RequiredValidator will add a "required" CSS class, etc.
Validators are triggered on some events indicated by the 'on' and 'except' attributes. Both accept wildcards:
For cases where the validated property cannot be annotated (legacy classes, coding policy, etc) most of the Loom annotations include a propertyPath attribute that specify the nested attribute to validate:
Keep in mind that the recommended practice is to annotate the model classes instead.
The configured validator has a default error message specified in the messages.properties file, but it can also be overriden on a per field basis by using the message attribute:
It is recommended that you prefix your validation messages with "loom." to have it automatically included in the javascript validations.
NestedAnnotations
Annotations are usually set in the model attributes, in which case the action class must include @NestedAnnotations to inspect the annotated attribute for validation annotations:
Important note: Loom will not look inside any attribute class unless @NestedAnnotations is used.
JPA annotations
JPA annotations are also translated to the corresponding Validator instances:
Both @Basic and @Column are supported.
RetrieveEntity
The @RetrieveEntity annotation marks a persistent attribute. If its id is included in the current request, the instance will be read from the database. Other attributes will be populated after retrieving the instance. If there is more than one @RetrieveEntity annotations they will be processed in the declaration order.
In the following example, three database retrievals will be performed in the specified order:
If the primary key value is not included in the request, there will be no retrieval. If a @Version attribute is found it will be compared with the one present in the request and if it's not a match a LocaleAwareException will be thrown.
Inject annotations
Starting with loom 1.5 @Autowired is supported for Spring applications, and now with 2.3 @Inject is also supported in any Action class or tags extending AbstractTag:
Note that the use of interceptors is not yet supported, which means that you cannot use annotations such as @Transactional in Action classes.
ImageValidation
Validate a file attribute that should contain an image. Attributes such as width, height, file size and extension are supported: