I'v done several research to find an answer to this topic. I'm so frustrated with Struts 2 'cause is unconceivable that this common problem, when you have to make a CRUD of an invoice and invoice detail with dynamic rows, isn't resolved yet.
Suppose I have these beans:
On the other hand I have an Action:
On the interface I use some ajax to create dynamically rows with the detail of the invoice. To fill the ValueStack with:
All I want is to validate if a conversion error ocurred or if the user left some fields empty. But notice that the list indexes are generated dinamycally so it seems impossible to use some *-validation.xml to do the validation.
A incomplete way to get around is to iterate invoice.getDetail() in validate() method at the Action. But it isn't what I need because I need to know when the user put invalid data or if the user left empty some field in the detail, and make short-circuit the conversion error and the other validations.
In my research I found that some years ago WebWork had a collection validator:
Sorry if you have progressed since your last post. I would solve this problem by using annotations to define the validation and place the annotations on the model beans themselves. This way the validation is applied uniformly and independent of the number of instances actually submitted.
You should put a class level annotation as follows:
On the getter for the InvoiceDetail collection you need the following. This annotation tells Struts 2 to check the objects on the Collection for validation instructions. To read more see Struts2 VisitorFieldValidator.
On your model bean you then need the @Validation annotation again and then your actual property annotations on the setters. For example I use the following in one of my beans:
This just checks that name is set and it is not an empty string. I should mention that the message properties of the above annotations are arbitrary and must be set but it is up to you whether you make use of the output - I usually prefer to just use a CSS error class to highlight the field.