Programming Thoughts
Struts 2 - Annotation-based Validation
Interceptor Redesign
Improving a fix to a Struts 2 feature
Struts 2 is a popular MVC framework for Java-based web applications but its annotation-based validation doesn't properly work. So, an alternative was created but it has design limitations. This article considers a redesign to overcome them.
Multiple modes
The alternate design only supported two modes of conversion, described below.
- No conversion - string fields with no converter annotations, though adjusters and non-conversion validators may apply. Such fields can also be half of manual converted string/non-string pairs.
- Pair conversion - string/non-string pairs with converter annotation on the string field
The design objective of eliminating the need for string/non-string pairs creates more modes.
- Auto conversion - non-string fields with converter annotations.
- Default conversion - non-string fields with no converter annotations. A default converter for the field type will be used, logged as an error if none applies.
- Manual parameter conversion - invokes a function on the form to validate and convert from request parameters not used for other modes. Always applies where the @ManualParameterConversion annotation is set.
Taking over the role of the Parameters interceptor means multiple request parameters using the same name must be considered. Everything is designed around single value parameters as multiple value parameters are rarely used. Nonetheless, multiple parameters should be received in string arrays or string collections for use in manual conversion, creating the set only mode. Also, it must handle File parameters, leading to the last mode.
- Set only - string array fields or string collection fields with no converter annotation. Any annotations on these are ignored and manual code is expected to handle conversion and validation.
- File - single, array, or collection fields of File type. These are set from a special kind parameter uploaded by FileUploadInterceptor. Any annotations on these are ignored and manual code is expected to handle validation.
Except where a @ManualParameterConversion annotation is used, how each mode applies is summarised below.
Field type | Converter annotation | Mode | Notes |
---|---|---|---|
String | No | No conversion | |
String | Yes | Pair conversion | |
Non-string | No | Default conversion | |
Non-string | Yes | Auto conversion | |
String array | Set only | Converters don't apply to arrays | |
String collection | No | Set only | |
String collection | Yes | Auto conversion | |
Non-string array | Manual parameter conversion | Converters don't apply to arrays | |
Non-string collection | No | Default conversion | Few default converters for collection types exist |
Non-string collection | Yes | Auto conversion | |
File | File | Set from a special parameter created by FileUploadInterceptor | |
File array | File | Set from a special parameter created by FileUploadInterceptor | |
File collection | File | Set from a special parameter created by FileUploadInterceptor |
Note this differs from the standard Parameters interceptor for treatment of non-string arrays and collections as it applies the converter for each request parameter. The alternate redesign does not do this for design simplicity and to avoid confusion with collection converters, which parse a single value.
Next part
Continued in Manual Parameter Conversion and Validation.