Java Mailing List Archive

Home » Home (12/2007) » Struts 2 »

Re: Conditional Validation

Gary Affonso


> Can anyone tell me how to do conditional validation in struts 2?
> In one form I want validations for a particular category (say Category XYZ) only if the candidate in that. If he is NOT Category XYZ then by checking a checkbox he should be able to skip the validations for that. I am not able find any solution to this problem. I guess there are no provisions for conditional validation in Struts 2. Struts 1 had a <validwhen> tag. But I am not able to find any equivalent tag for Struts 2.

This was true for WebWork, I'm assuming it remains true for s2...

If you're using the xml-based validation framework then you can use the
"expression" validator to do validations on as many fields/conditions
(and their combinations) as you want.

Here's an example:

  <validator type="expression">
     <param name="expression">
        ! (
          ( chosenAddressId.intValue() eq -1 )
          ( regionId.intValue() eq -1 )
          ( ( countryId.intValue() eq 1 ) or (
countryId.intValue() eq 2 ) )
If you choose to use a custom address and choose US or Canada as your
country, you must choose a state/region from the drop-down menu.</message>

The HTML that the above code validates has three fields. A radio button
with a "custom" address choice, a country drop-down (select) and a
state/region drop-down (the drop-downs have IDs for values).

The above validation says that a region choice is required if the user
chooses the "custom address" radio button AND they choose US or Canada
for the country drop-down.

Be warned, though. Writing and debugging complex OGNL validation
expressions absolutely sucks (IMO). It's confusing to get the logic
right (you'll notice that I've written the checks above as positive
statements and then reversed the whole expression. I find writing the
checks in the negative to be way less intuitive) and very, very
difficult to debug (hint, while developing these you can include field
references in the message (I think it's a ${} syntax but I can't
remember) to try to get some debugging info back out to yourself.)

Your other choices are...

1) Just do validation at the top of your Action's execute method.
Your Action's execute method gets called after all the interceptors have
run. Meaning that all the form values will have been applied to the
Action's (or domain objects) properties.

So the first thing you do at the top of your execute method is a bunch
of validity checks on those properties. If those checks fail, you just
some sort of message to the Action's FieldErrors/ActionErrors
(addActionError, addFieldError, etc.) lists and return a
failure-oriented result code (commonly INPUT). Same end-result as if
you'd used the xml framework.

(Note: I think actions get their fieldError and ActionError lists by
sublclassing ActionSupport which implements validationAware. So if your
actions are not doing either you'll want to check that out.)

2) Implement the "validatable" interface
Not a whole lot different than the above but in this case you put your
validation logic in a "validate" method in your action.


If you want to do the same validation for a domain object in several
different actions, Webwork (and presumably s2) has the option to shift
XML-based validation to be domain-object-based (instead of being
action-based). Basically you write a -validation.xml file for the
*domain* object not each of the actions and then you tell the action to
delegate the validation back to the domain object. I've completely
forgotten how to do this but if that interests you you should be able to
find it in the docs easily enough.

In general, what you want to do (multi-field validation) is common,
directly supported, and fairly easy. You just need to pick which route
you want to go. I'd probably recommend doing this in the "validate"
method. You get to use java, and it's absolutely clear that this is
"validation" logic (because it's in a dedicated validate method).

That is, I'd recommend it if you're OK tying your validation logic to
the actions. If you want validation logic you can share across more
tiers of your application that's an entirely separate discussion.

WARNING: the above was true for WebWork (2.x). Or mostly. It's been
awhile since I've looked at any of this in depth and I'm going from
memory here. (and right-before-bed memory at that). But the above
should be correct enough to get you headed in the right direction.

Good luck!

- Gary


To unsubscribe, e-mail: user-unsubscribe@(protected)
For additional commands, e-mail: user-help@(protected)

©2008 - Jax Systems, LLC, U.S.A.