为什么spring总是将<form:checkbox>解析为true?</form:checkbox>

时间:2014-07-28 19:39:53

标签: java spring-mvc

问题是spring 3将<form:checkbox>元素呈现为true。但是@Controller将其值设置为false。

在jsp页面上是:

<form:form id="hostelSearchForm" modelAttribute="hs" method="POST"
                cssClass="mainForm">
    <div class="checkbox">
                                <fmt:message key="family" var="family" />
                                <form:checkbox path="family" label="${family}" />
                            </div>
                            <div class="checkbox">
                                <fmt:message key='children' var='children' />
                                <form:checkbox path="children" label="${children}" />
                            </div>
.......
<input id="hostelSearchFormButton" type="button" 
                            value="${searchButtonLabel}" />
</form:form>

@Controller内部,我转发给jsp新创建的modelAttribute,其中所有默认值均为布尔值为假。

在jsp上,复选框呈现为false。但是他们的attrbiute valuetrue(我在页面源上看到),当我提交表单时,我收到的所有复选框都是true,我没有检查。

在我的春天@Controller我决定使用@InitBinder来解决我的问题:

@InitBinder
    public void initBooleanBinder(WebDataBinder binder) {
        binder.registerCustomEditor(Boolean.class, new PropertyEditorSupport() {
            @Override
            public void setAsText(String text) throws IllegalArgumentException {
                System.out.println("bind boolean property string " + text);
                super.setValue(text != null ? text.equals("on") : false);
            }

            @Override
            public void setValue(Object value) {
                System.out.println("bind boolean property " + value);
                if (value instanceof Boolean)
                    super.setValue((boolean) value ? "ON" : "OFF");
                else
                    super.setValue(value);
            }
        });
    }

但只在呈现jsp页面之前调用它。调用方法setValue,并且值按预期方式为false。但是,在提交表单时,这些值为true,并且不会调用@InitBinder

修改

表格由以下方式呈现:

@RequestMapping(value = "/search", method = RequestMethod.GET)
    public String search(Model model, HttpServletRequest request) {
        logger.debug("Forwarding to hostel search page");

        CountryInfo countryInfo = restTemplate.getForObject(
                "http://api.geonames.org/countryInfoJSON?username=geonameUser2014", CountryInfo.class);
        List<Country> countries = countryInfo.getCountries();
        List<Gender> genders = Arrays.asList(Gender.values());

        model.addAttribute("countries", countries);
        model.addAttribute("genders", genders);
        model.addAttribute("hs", new HostelSearch());
        return "hostel/search";
    }

运行此方法后,将呈现<form:form>(如上所示),复选框为:

<input id="smoking1" name="smoking" type="checkbox" value="true"/><label for="smoking1">Smoking</label><input type="hidden" name="_smoking" value="on"/>

值已经错了。表单最初使用错误的值进行渲染!在bean hs中我对smoking roperty有误,但在jsp页面上它是真的。

如何解决这个问题?

1 个答案:

答案 0 :(得分:2)

你没有提供足够的信息所以我必须猜测。 <form:checkbox>标记由Spring在两个标记中翻译:{{1​​}}给出

<form:checkbox path="family" label="${family}" />

未检查时,浏览器不会传输HTML <input name="family" type="checkbox" value="value_of_family_whatever_it_is"/> <input type="hidden" value="1" name="_family"/> 。这就是隐藏标签的原因。 如果您使用普通提交按钮,一切都很好,因为Spring知道隐藏标记并使用它来知道哪些标记以渲染形式存在,并设置为false所有复选框参数,它看到了隐藏标签。

但正如你所说,你使用ajax提交但不告诉如何,你现在必须验证如何用HTML翻译jsp以及你的javascript发送给控制器的内容。