Parameter mapping

JavAjax offers a simple way to bind a request parameter to a method input parameter: @Param annotation.
This annotation can be used at parameter level, or inside a @ParameterMapping annotation specified at method level. In any case, number and order of @Param annotations must match input parameters.
Validation is always performed before the Action method is actually invoked, using one of the standard Validator classes based on the data type of the method parameter, or using the Validator declared on the @Param annotation.

protected Response myMethod(@Param("inputParam") String value){
    ...
}

@ParameterMapping(
    params={@Param("inputParam")}
)
protected Response myMethod(String value){
    ...
}

Framework level validation

The annotation @Param can be configured to inform the framework about the validation that should be done on the parameter, before the method is actually called. As already said, data conversion is always done and eventually an invalid.format validation error is raised, but more specific validation steps can be added.
@ParameterMapping {
  params={
    @Param(value="userName", mandatory=true, minLength=5)
    , @Param(value="email", mandatory=true, minLength=5, match="^[a-z0-9_-\\.]?@.?\\..?$"))
    , @Param(value="yearOfBirth", minValue=5)
  }
}
protected Response myMethod(String userName, String email, int year) {
  ...
}

Custom validation

Sometimes a more specific validation is needed, i.e. when we need to validate the parameter against a pattern or a range. In this case we can use a custom Validator, implementing the Validator<?> class or extending one of the custom validators. One example is the EmailValidator, already available in the framework, which extends the StringValidator and checks if the given value is a valid email address.
Validators can be used directly on a @Param annotation, to be used on a specific parameter, or declared in the Filer init parameter "custom.validators", so that all the parameters of that Class will be validated using this Validator. This is strongly suggested when a custom data type is used and you want to validate the value received.
Following the example above, we can validate the email address using a Validator class instead of a pattern:

@ParameterMapping {
  params={
    @Param(value="userName", mandatory=true, minLength=5)
    , @Param(value="email", mandatory=true, validator=EmailValidator.class))
    , @Param(value="yearOfBirth", minValue=5)
  }
}
protected Response myMethod(String userName, String email, int year) {
  ...
}

To validate a custom data type, we can implement the Validator class...
public class MyDateValidator implements Validator<MyDate> {
  @Override
  public void validate(RequestContext context, Param param, Object value) throws ValidationException
  {
    ... your code here...
  }
}

...and declare the new validator in the Filter configuration
<init-param>
  <param-name>custom.validators</param-name>
  <param-value>myPackage.MyDateValidator</param-value>
</init-param>

In-Method validation

When framework or custom validation are passed, the method is invoked and executed. In the case more specific validation is needed, it can be performed in the method and generating, if needed, ValidationError objects.
If method execution should not be interrupted, these objects can be added to the RequestContext, otherwise can be added to an ValidationException, which will be then thrown, interrupting the execution.

This code will generate a message without interrupting the method execution
if(a < b) {
      getContext().addMessage(new ValidationError("fieldName", "my.first.message"));
}

This code will generate a message interrupting the method execution
if(a > c) {
      throw new ValidationException("fieldName", "my.second.message");
}

where "my.first.message" and "my.second.message" are keys to retrieve the message text from the properties file.