When registering a customerEditor in spring to format a number with a given numberFormat instance, it is easy to apply this to a specific field in the jsp, e.g.:
NumberFormat numberFormat = getNumberFormat(0, 0, 2);
PropertyEditor propertyEditor =
new CustomNumberEditor(Double.class, numberFormat, true);
binder.registerCustomEditor(Double.class, "myDoubleField", propertyEditor);
This will result in a correct format of the number based on the applications locale (regarding commas and dots for thousand/decimal separator) and with the specified decimals before and after the seperator.
However, if I have a list of unknown size containing doubles how can I format these in a smart way? I could of course run through the list and register one for each entry in the list, but it seems cumbersome and wrong.
Since spring is binding to lists with indicises the field names would have names like "myDoubleField[0] .... myDoubleField[n]"
which therefore makes it hard...
Is there an easy workaround for this? Or is there a workaround at all?
Thanks a lot in advance, I hope someone can point me in a correct direction!
Solved by replacing old cumbersome way of registering custom editors, by using a global PropertyEditorRegistrar.
Initializing controllers with this in constructor:
public myController(PropertyEditorRegistrar customPropertyEditorRegistrar) {
this.customPropertyEditorRegistrar = customPropertyEditorRegistrar;
}
and registering this in initBinder:
@Override
protected void initBinder(HttpServletRequest request, ServletRequestDataBinder binder) throws Exception {
customPropertyEditorRegistrar.registerCustomEditors(binder);
}
Forces all elements to be formatted in the way specified in the CustomerPropertyEditorRegistrar.
Eg. with doubles:
public final class CustomPropertyEditorRegistrar implements PropertyEditorRegistrar {
// Double
PropertyEditor doubleEditor = getLocaleBasedNumberEditor(Double.class, true);
registry.registerCustomEditor(double.class, doubleEditor);
registry.registerCustomEditor(Double.class, doubleEditor);
}
Specific fields can the be overwritten in the old manner, if another formatting is desired for a specific field.
//Hoof
If you are displaying a list of values in an array/ArrayList and you want to format specific fields in the elements and not just a blanket converter for all Integer objects you can do this:
Firstly the example class I will use:
public class ListOfTimes {
private List<TimeStoredInSecondsSinceMidnight> times;
public static class TimeStoredInSecondsSinceMidnight {
private Integer id;
private Integer currentTime;
...
}
...
}
Imagine you have an instance with a few times added into it and then it is added into your model as timesList
. In the foreach loop of your view you have something like this:
<form:input id="time" path="times[${count.index}].currentTime" size="5"/>
<form:input id="recordId" path="times[${count.index}].id" size="5"/>
Of course this will result in a list of input boxes with your integers in but if you apply a property editor like this:
binder.registerCustomEditor(Integer.class, propertyEditor);
propertyEditor
will be invoked on both id and currentTime, not what is desired. If we add the field name to the registerCustomEditor
call it will not work either (neither id
or currentTime
are edited with propertyEditor
):
binder.registerCustomEditor(Integer.class, "currentTime", propertyEditor);
Because the name has [n]
for each element... after finding this:
http://static.springsource.org/spring/docs/3.0.x/javadoc-api/org/springframework/validation/DataBinder.html#registerCustomEditor%28java.lang.Class,%20java.lang.String,%20java.beans.PropertyEditor%29
Reading the comments in the above link says that the following will do what we want:
binder.registerCustomEditor(Integer.class, "times.currentTime", propertyEditor);
id
is untouched (uses the default editor) and currentTime
uses the custom propertyEditor
.
I know this is probably old news to most Spring MVC devs but I found this page and I am sure others will too.
Every field in that list should have the same number format, right?
I'm not sure if this going to work,
but you can try to register default editor, and redefine editors for other fields:
binder.registerCustomEditor(Double.class, defaultEditor);
binder.registerCustomEditor(Double.class, "field1", specificEditor1);
binder.registerCustomEditor(Double.class, "field2", specificEditor2);