Saved BigDecimal's and Long's were processed against English locale, but presentation of numbers were based on appropriate locale of present user context.
Parse BigDecimal => 12,333,444
English => 12333444
Indonesian => 12333444
Print BigDecimal => 12345.50
English => 12345.50
Indonesian => 12345,50
Only difference for printed numbers for above locales was how decimal places is presented. For English we use dot. For Indonesian comma is used.
Parse Long => 12,333,444
English => 12333444
Indonesian => 12333444
Print Long => 12333444
English => 12333444
Indonesian => 12333444
For Long's the formatter we are going to just remove grouping commas.
So, below you can find CurrencyLocaleBigDecimalFormatter :
package pl.garciapl.test; import org.springframework.format.Formatter; import java.math.BigDecimal; import java.text.DecimalFormat; import java.text.NumberFormat; import java.text.ParseException; import java.util.Locale; public class CurrencyLocaleBigDecimalFormatter implements Formatter<BigDecimal> { @Override public BigDecimal parse(String text, Locale locale) throws ParseException { DecimalFormat format = (DecimalFormat) NumberFormat.getNumberInstance(Locale.ENGLISH); format.applyPattern("#,##0.00"); format.setParseBigDecimal(true); format.setGroupingUsed(true); return (BigDecimal) format.parse(text); } @Override public String print(BigDecimal object, Locale locale) { DecimalFormat format = (DecimalFormat) NumberFormat.getNumberInstance(locale); format.applyPattern("#,##0.00"); format.setParseBigDecimal(true); format.setGroupingUsed(false); return format.format(object); } }
and CurrencyLocaleLongFormatter :
package pl.garciapl.test; import org.springframework.format.Formatter; import java.text.DecimalFormat; import java.text.NumberFormat; import java.text.ParseException; import java.util.Locale; public class CurrencyLocaleLongFormatter implements Formatter<Long> { @Override public Long parse(String text, Locale locale) throws ParseException { DecimalFormat format = (DecimalFormat) NumberFormat.getNumberInstance(Locale.ENGLISH); format.applyPattern("#,##0.00"); format.setParseBigDecimal(false); format.setGroupingUsed(true); return (Long) format.parse(text); } @Override public String print(Long object, Locale locale) { DecimalFormat format = (DecimalFormat) NumberFormat.getNumberInstance(locale); format.applyPattern("#,##0.00"); format.setParseBigDecimal(false); format.setGroupingUsed(false); return format.format(object); } }
Also CurrencyLocaleFormatterRegistrar is needed because of Spring framework needs to register formatters in registry to use them.
package pl.garciapl.test; import org.springframework.format.Formatter; import org.springframework.format.FormatterRegistrar; import org.springframework.format.FormatterRegistry; import java.util.HashSet; import java.util.Set; public class CurrencyLocaleFormatterRegistrar implements FormatterRegistrar { private Set<Formatter> formatters = new HashSet<>(); public CurrencyLocaleFormatterRegistrar(Set<Formatter> formatters) { this.formatters = formatters; } @Override public void registerFormatters(FormatterRegistry registry) { for (Formatter element : this.formatters) { registry.addFormatter(element); } } }
And finally whole beans configuration for Spring
<bean id="currencyLocaleBigDecimalFormatter" class="ie.garciapl.test.CurrencyLocaleBigDecimalFormatter"/> <bean id="currencyLocaleLongFormatter" class="ie.garciapl.test.CurrencyLocaleLongFormatter"/> <bean id="currencyLocaleRegistrar" class="ie.garciapl.test.CurrencyLocaleFormatterRegistrar"> <constructor-arg> <set> <ref bean="currencyLocaleBigDecimalFormatter"/> <ref bean="currencyLocaleLongFormatter"/> </set> </constructor-arg> </bean>
Do not forget to plug into your conversionCurrencyService as below :
<mvc:annotation-driven conversion-service="conversionCurrencyService"/>
Reference : [1] Spring Docs - Formatters [2] Javabeat.net - Introduction to Spring Converters and Formatters [3] CurrencyLocaleBigDecimalFormatter [4] CurrencyLocaleLongFormatter [5] CurrencyLocaleFormatterRegistrar [6] CurrencyLocaleBigDecimalFormatterTest [7] CurrencyLocaleLongFormatterTest