Spring numberformatting with registercustomeredito

2019-07-27 04:45发布

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!

3条回答
ゆ 、 Hurt°
2楼-- · 2019-07-27 05:15

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.

查看更多
成全新的幸福
3楼-- · 2019-07-27 05:16

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

查看更多
ら.Afraid
4楼-- · 2019-07-27 05:30

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);

查看更多
登录 后发表回答