SpringMVC Checkbox: Custom Binding / PropertyEdito

2019-09-07 01:29发布

It's something really simple but I couldn't find a good example:

I have a custom data type that I'd like to bind to a SpringMVC checkbox, it looks like this: YES/NO:

public enum YesNoDataType {
   YES("Yes"), 
   NO("No");
}

SpringMVC checkboxes auto-map to Booleans, now I need to map Selected->YES, Empty->NO.

I know I have to implement one of these 4 PropertyEditorSupport methods, but which ones, and how?

<form:checkbox path="testYesNo"></form:checkbox>

Model

private YesNoDataType testYesNo; 

Controller

binder.registerCustomEditor(YesNoDataType.class, new PropertyEditorSupport() {

          // Which ones to override?

            @Override
            public void setValue(Object value) {
                // TODO Auto-generated method stub
                super.setValue(value);
            }

            @Override
            public Object getValue() {
                // TODO Auto-generated method stub
                return super.getValue();
            }

            @Override
            public String getAsText() {
                // TODO Auto-generated method stub
                return super.getAsText();
            }

            @Override
            public void setAsText(String text) throws IllegalArgumentException {
                // TODO Auto-generated method stub
                super.setAsText(text);
            }

});

1条回答
闹够了就滚
2楼-- · 2019-09-07 02:23

I tried defining and registering some Converters (YesNoDataType / Boolean), but I see in SpringMVC's CheckboxTag.java that they're all useless. No converters or binding tweaks will work because the tag explicitly checks for Booleans and Strings only:

protected void writeTagDetails(TagWriter tagWriter) throws JspException {
    tagWriter.writeAttribute("type", getInputType());

    Object boundValue = getBoundValue();
    Class<?> valueType = getBindStatus().getValueType();

    if (Boolean.class.equals(valueType) || boolean.class.equals(valueType)) {
        // the concrete type may not be a Boolean - can be String
        if (boundValue instanceof String) {
            boundValue = Boolean.valueOf((String) boundValue);
        }
        Boolean booleanValue = (boundValue != null ? (Boolean) boundValue : Boolean.FALSE);
        renderFromBoolean(booleanValue, tagWriter);
    }

    else {
        Object value = getValue();
        if (value == null) {
            throw new IllegalArgumentException("Attribute 'value' is required when binding to non-boolean values");
        }
        Object resolvedValue = (value instanceof String ? evaluate("value", value) : value);
        renderFromValue(resolvedValue, tagWriter);
    }
}

The String binding is irrelevant to me. In the getValue() String binding (Clause #2), a checkbox is selected if its value="" attribute matches the string in the model. What I need is a True/False boolean binding, but my Converter needs to be plugged into Clause #1 to obtain a Boolean from a custom type. Just very frustrated that Spring is so restrictive as soon as you try to go outside the narrow parameters of what's common. The issue is still outstanding.

查看更多
登录 后发表回答