Saturday, October 10, 2009

Number and date formatting in struts 2

Struts 2 has excellent capabilities built-in to handle internationalization. Not only in the sense of messages printed but also in formatting values and handling conversion of the submitted string to corresponding types, and adding field errors when they cannot be converted. All based on the user locale. Hit is a feature widely used, which became very apparent when release 2.1.3 (or maybe 2.1.4) broke the conversion error handling.

I have been fiddling for a while to get this parts working right in my forms. In those cases it is not automatic. There is no way for struts to know that the double I have in my model is actually a currency value and should be formatted accordingly. The struts documentation contains a section on what I need but it never worked, and turned out (perhaps) erroneous. It has been corrected in the most recent version but I'm putting up this post since google is not your friend always, you keep hitting wrong version in the docs now and then.

My issue is I have a date and currency value in my model, of the types Calendar and Double. I need the to be displayed in local format, and properly converted when submitted. First off is the format configuration, which goes in the resource boundle, in my case messages.properties.

format.money={0,number,#0.00}
format.date={0,date,yyyy-MM-dd}

This is actually swedish formats. The dot in the money format comes out correctly as a comma (how, I have no idea). This configuration is enough to make form post conversion work as expected.

Next step is getting output to work. This is easy if printing a number with s:property like this.

<s:text name="format.money">
<s:param name="value" value="model.price"/>
</s:text>

And there is the s:date tag for formatting dates. This can however not be used as easily in the s:input tags where they should go. To get those formats into the form.

<s:textfield name="model.observed" label="date"
value="%{getText('format.date',{model.observed.time})}" />
<s:textfield key="model.price" label="price"
value="%{getText('format.money',{model.price})}" />

Do not the time addition to the model.observed Calendar value, it makes sure the Date value is exposed, since the formatting does not work with Calendar type.

No comments:

Post a Comment