Search code examples
javajspvalidationstruts2struts2-convention-plugin

Short-circuit in Struts2 validation


Let's assume that there a field of type BigDecimal in an action class as follows.

@Namespace("/admin_side")
@ResultPath("/WEB-INF/content")
@ParentPackage(value = "struts-default")
public final class TestAction extends ActionSupport
{
    private BigDecimal price;

    //Setter and getter.        

    @Validations(
    requiredFields = {
        @RequiredFieldValidator(fieldName = "price", type = ValidatorType.FIELD, message = "Price is mandatory.")},
    fieldExpressions = {
        @FieldExpressionValidator(fieldName = "price", expression = "price>0", shortCircuit = true, message = "Price cannot be less than or equal to zero.")})
    @Action(value = "Add",
    results = {
        @Result(name = ActionSupport.SUCCESS, type = "redirectAction", params = {"namespace", "/admin_side", "actionName", "Test"}),
        @Result(name = ActionSupport.INPUT, location = "Test.jsp")},
    interceptorRefs = {
        @InterceptorRef(value = "defaultStack", params = {"params.acceptParamNames", "price", "validation.validateAnnotatedMethodOnly", "true"})
    })
    public String insert() {
        return ActionSupport.SUCCESS;
    }

    //This method is worth nothing. It is used just to return an initial view on page load.
    @Action(value = "Test",
    results = {
        @Result(name = ActionSupport.SUCCESS, location = "Test.jsp"),
        @Result(name = ActionSupport.INPUT, location = "Test.jsp")},
    interceptorRefs = {
        @InterceptorRef(value = "defaultStack", params = {"params.acceptParamNames", "", "params.excludeMethods", "load", "validation.validateAnnotatedMethodOnly", "true"})})
    public String load() throws Exception {
        return ActionSupport.SUCCESS;
    }
}

And following is the form.

<s:form namespace="/admin_side" action="Test" id="dataForm" name="dataForm">
    <s:fielderror fieldName="price"/>
    <s:textfield id="price" name="price"/>

    <s:submit value="Submit" action="Add"/>
</s:form>

I want to achieve,

  1. If the field is left blank then, the only message, Price is mandatory. should be displayed through @RequiredFieldValidator
  2. If a non-numeric value like "abc" is entered then, it should only display the conversion error message from a property file.
  3. If a negative value is attempted then, the only message, Price cannot be less than or equal to zero. should appear through @FieldExpressionValidator.

Either one conversion error or one validation error should appear at a time.

Is this possible? I do by far not understand properly the function of the shourtCircuit attribute.


Solution

  • At the first glance haven't seen so much. But looking at the Type Conversion Error Handling I'd say that there's a way to handle conversion errors. By adding a conversion validator to the configuration which is short-circuit validator. Short-circuit means that if such validator has errors other validators are skipped.

     conversionErrorFields = @ConversionErrorFieldValidator(fieldName = "price", message = "Price has invalid value", shortCircuit = true) 
    

    place this code under @Validations annotation.