Spring InitBinder: bind empty or null values of a

2019-03-29 06:33发布

问题:

I'm just wondering if it's possible to tell an @InitBinder that empty float values in a form would be converted to 0.

I know that float is a primitive data type but I'd still like to convert null or empty values to 0.

If that is possible, how can i achieve that?

Otherwise I'll just make a workaround using a String instead of a float

回答1:

Yes you could always do that .Spring have a CustomNumberEditor which is a customizable property editor for any Number subclass like Integer, Long, Float, Double.It is registered by default by BeanWrapperImpl,but, can be overridden by registering custom instance of it as custom editor.It means you could extend a class like this

public class MyCustomNumberEditor extends CustomNumberEditor{

    public MyCustomNumberEditor(Class<? extends Number> numberClass, NumberFormat numberFormat, boolean allowEmpty) throws IllegalArgumentException {
        super(numberClass, numberFormat, allowEmpty);
    }

    public MyCustomNumberEditor(Class<? extends Number> numberClass, boolean allowEmpty) throws IllegalArgumentException {
        super(numberClass, allowEmpty);
    }

    @Override
    public String getAsText() {
        //return super.getAsText();
        return "Your desired text";
    }

    @Override
    public void setAsText(String text) throws IllegalArgumentException {
        super.setAsText("set your desired text");
    }

}

And then register it normally in you controller:

 @InitBinder
    public void initBinder(WebDataBinder binder) {

       binder.registerCustomEditor(Float.class,new MyCustomNumberEditor(Float.class, true));
    }

This should do the task.



回答2:

Define a subclsss of CustomNumberEditor as

import org.springframework.beans.propertyeditors.CustomNumberEditor;
import org.springframework.util.StringUtils;

public class MyCustomNumberEditor extends CustomNumberEditor {

    public MyCustomNumberEditor(Class<? extends Number> numberClass) throws IllegalArgumentException {
        super(numberClass, true);
    }

    @Override
    public void setAsText(String text) throws IllegalArgumentException {
        if (!StringUtils.hasText(text)) {
            setValue(0);
        }else {
            super.setAsText(text.trim());
        }
    }

}

Then in your controller class (I create a BaseController for all my application controllers, I need this behavior for all the numeric primitive types in my application, so I simply define this in my BaseController), register binders for the various primitive types. Note that the constructor parameter of MyCustomNumberEditor must be a subclass of Number, instead of primitive class type.

   @InitBinder
public void registerCustomerBinder(WebDataBinder binder) {
    binder.registerCustomEditor(double.class, new MyCustomNumberEditor(Double.class));
    binder.registerCustomEditor(float.class, new MyCustomNumberEditor(Float.class));
    binder.registerCustomEditor(long.class, new MyCustomNumberEditor(Long.class));
    binder.registerCustomEditor(int.class, new MyCustomNumberEditor(Integer.class));
....    
}