Monday, May 10, 2010

Validation Internationalization (Struts 2)

Struts 2 has a very powerful form validation system using the commons validation. If you are just getting your feet wet I recommend you read http://struts.apache.org/2.x/docs/guides.html.

After implementing the validation I had 2 issues. The first was internationalization of the error messages contained in the -validation.xml. The second was country specific validation for the same form.

Internationalization Error Messages


The struts validation has its own system for internationalization of error messages in properties files. As I mentioned on the opening page we are re-factoring our way into a struts 2 architecture. We already have a system wide internationalization system that is database driven and it would be too expensive to switch to a properties file based system. So the challenge is using the cool parts of struts without using the full thing. I created my -validation.xml in the same directory as my action class name MyAction-validation.xml. (note. your fields in -validation.xml must be defined in both the .html form file and in the action class to validate. That took almost half a day to figure out because I added new fields in the html and didn't get to adding them to the action.)
<validators>
<...........>
<field name="email">
<field-validator type="requiredstring">
<message>enroll.validator.email.req</message>
</field-validator>
<field-validator type="email">
<message>enroll.validator.isp.email.invalid</message>
</field-validator>
</field>

<..............>
</validators>

Solution:


Notice the message is not something like "Your email address is required". I used a tag 'enroll.validator.email.req' instead. The other part of the solution required me to extend the them xhtml and use an object in the session to find the actual message from the tag. In controlheader-core.ftl you will find <span class="errorMessage">${error?html}</span>. I changed that to <span
class="errorMessage">${Session.LANGXLAT.xlat(error?html)}</span>. The LANGXLAT is the name of the attribute in the session. It is a custom translator object that takes a tag and returns the text in the language the user is browsing in. (note: when I extended the theme it wasn't copying into my class path because I had the java compiler output going into /WEB-INF/classes but the theme files were not java and so I had to have a separate deployment step copy the template folder from my src to WEB-INF/classes. My preferred ide is JetBrains IntelliJ and it has some configuration issues I have had to deal with. I blame it on not be able to know everything now.)

<s:debug />


There is a bit of magic happening with the validation system. Its often tough to figure out whats going on or why your fields aren't getting validated. The tag from struts-tags <s:debug /> is very helpful. If you don't use any tags use that tag. Just include <%@ taglib prefix="s" uri="/struts-tags" %> at the top of your file and <s:debug /> at the bottom. It will print out a bunch of data that is in the stack and whats been validated or the error messages.

Interpolated Values


Struts validation has the ability to interpolate values into the error messages (ie.<message>bar must be between ${min} and ${max}, current value is ${bar}.</message>). I haven't had to deal with this yet in my solution but I am sure I would create some sort of syntax, comma separated, to capture the values from the <message> and then parse them out later when I put into my 'view'.

Recommended Books:
Apache
Struts 2 Web Application DevelopmentApache
Struts 2 Web Application Development: Design, Develop, Test, and Deploy
Your Web Applications Using the Struts 2 Framework
ISBN: 9781847193391
by Dave Newton
Packt Publishing Copyright Pact Publishing © 2009 (384 pages)
This book had some good information. Some things were still left to trial and error.

No comments: