Monday, 8 August 2011

Using Spring 3 @NumberFormat Annotation

The Guys as Spring have provided a very useful annotation called @NumberFormat that allows you to, well... format numbers. It works on numbers sent to the presentation layer from the controller and visa-versa and can be applied to any class derived from java.lang.Number. It will format numbers into three styles as defined by the NumberFormat.Style enum: CURRENCY, PERCENT and NUMBER.

The code below demonstrates how to apply this annotation to a simple savings account object:

public class SavingsAccount {

@NumberFormat(style = Style.CURRENCY)
private final BigDecimal amount;

@NumberFormat(style = Style.NUMBER, pattern = "#,###.###")
private final BigDecimal interest;

@NumberFormat(style = Style.PERCENT)
private final BigDecimal interestRate;

Taking each of the styles in turn, CURRENCY will take your number and output it in the following format: ###,###.## adding the currency symbol taken from the browsers current locale. If a currency symbol is not found, then a ‘?’ character is appended to the output string. When using the CURRENCY style, @NumberFormat will also perform rounding on your string to two decimal places as suggested by the format string above. If a pattern attribute is used with this style, then the @NumberFormat annotation has no effect.

Adding a PERCENT style to @NumberFormat will add a ‘%’ symbol to your number. Beware here, the percentage conversion is based on numbers between 0 and 1; hence, 0 = 0% and 1 = 100%. So, if your number is 50 don’t expect to see 50% on the screen as you’ll see 5000%.

The PERCENT style also has a set of rounding rules, rounding your number to ZERO decimal places. For example: 0.40000 = 40%, 0.40099 = 40% and 0.4099 = 41%.

Like CURRENCY, if a pattern attribute is used with this style, then the @NumberFormat annotation has no effect

The final @NumberFormat style is NUMBER. This will format numbers using the pattern attribute and will round to the appropriate number of places.

When displaying numbers formatted by @NumberFormat, you must use Spring’s JSP tags. If you’ve looked at Spring’s mvc-basic example, you’ll noticed that they use the <form:form … /> tag. This is fine if you’re populating a form; however, if all you need to do is to display some data on the screen, then the only way I could find of doing it was to use the <spring:bind … /> tag:

<div class="field">
 <spring:message code="savings.amount"/>
 <spring:bind path="savingsAccount.amount">${status.value}</spring:bind>
<div class="field">
 <spring:message code="savings.interest"/> : 
 <spring:bind path="savingsAccount.interest">${status.value}</spring:bind>
<div class="field">
 <spring:message code="savings.interest.rate"/> :
 <spring:bind path="savingsAccount.interestRate">${status.value}</spring:bind>

There are no special config settings required to use @NumberFormat annotation, but remember that you do need the usual <mvc:annotation-driven /> entry in your Spring config file.

No comments: