Spring checkbox JSP Tag is broken when using Converter for type Boolean

∥☆過路亽.° 提交于 2019-12-05 10:22:07

This seems possible to overcome. That is you want a human readable Formatter to display yes/no to the user for boolean values in the model. But you still want the checkbox HTML elements to work and it appears those HTML checkbox elements/widgets/JSP tags expects true/false string to be used (or a boolean Java type) it doesn't appear to use the converter to get the arbitrary yes/no string back to a boolean type.

This problem for me manifests itself as the initial state of the checkbox is never ticked when the model has a Boolean.TRUE value set. This means any read-modify-update of the record (without editing that field ends up transitioning from 'true' to 'false' when it was not changed by the user). This is due to the initial state in the UI being inconsistent with the model (it shows always unchecked i.e. false state) even when model is true state. The displayed value is of an unchecked checkbox in the HTML edit record screen, even when the model has Boolean.TRUE for that value. This is because "yes" does not get interpreted as "true" by the HTML checkbox elements and it defaults to false (as that is the default boolean value).

So define your Formatter/Converter (as you are already doing). But in your @Controller add:

@InitBinder
public void initBinder(WebDataBinder binder) {
    binder.registerCustomEditor(Boolean.class, "friesWithThat", new CustomBooleanEditor(false));
}

This appears to make the string display value continue to be yes/no but the value used and passed to the checkbox HTML elements continues to be true/false.

Now when editing/updating the record (in CRUD) the initial state of the checkbox is consistent with the model and saving the data (without editing any fields) does not transition the checkbox state (which is my understanding of the problem you have).

So from this I think we can understand that Converters/Formatters are for general display of data and that PropertyEditors are for mapping model data so the data needed by the UI widget.

Probably you should write your own type called Choice which has Choice.YES and Choice.NO as ordinal enumerations which correspond to 1 or 0 based on the values stored in the database.

Then you can have your own display tags and input tags defined within the application for this type which would address this issue.

Adding to the previous answer, from spring 3.2 you can register the property editor for all controllers and all Boolean fields like this:

package your.package.path;

import org.springframework.beans.propertyeditors.CustomBooleanEditor;
import org.springframework.web.bind.WebDataBinder;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.InitBinder;
import org.springframework.web.context.request.WebRequest;

@ControllerAdvice
public class GlobalBindingInitializer {

    @InitBinder
    public void registerCustomEditors(WebDataBinder binder, WebRequest request) {
        binder.registerCustomEditor(Boolean.class, new CustomBooleanEditor(false));
    }
}

if you are coming from Spring Roo basic configuration remember also to add this line in your webmvc-config.xml

    <context:include-filter expression="org.springframework.web.bind.annotation.ControllerAdvice" type="annotation"/>

like this:

<context:component-scan base-package="your.package.path" use-default-filters="false">
    <context:include-filter expression="org.springframework.stereotype.Controller" type="annotation"/>
    <context:include-filter expression="org.springframework.web.bind.annotation.ControllerAdvice" type="annotation"/>
</context:component-scan>
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!