【问题标题】:How can I handle a tri-state Boolean with Spring MVC 3 Form radiobutton tags?如何使用 Spring MVC 3 Form 单选按钮标签处理三态布尔值?
【发布时间】:2011-10-09 11:04:23
【问题描述】:

我的一个对象中有一个三态 Boolean 属性(true、false 和 null),但我不知道如何使用 Spring Forms 标记正确绑定它。我想使用一系列 3 个单选按钮(true、false 和 null),但 Spring 似乎不喜欢我目前尝试的。

这是支持 POJO:

public class Spirit {
    /*** Private Fields **/
    private Integer id;
    private String name;
    private Boolean isAlive;

    /*** Constructor **/
    public Spirit() {}

    /*** Getters **/
    public Integer getId() {return id;}
    public String getName() {return name;}
    public Boolean isAlive() {return isAlive;}

    /*** Setters **/
    public void setId(Integer id) {this.id = id;}
    public void setName(String name) {this.name = name;}
    public void isAlive(Boolean isAlive) {this.isAlive = isAlive;}
}

这是我正在使用的表格(不起作用):

<sf:form method="POST" modelAttribute="spirit">
    <table>
        <tr>
            <th><label for="spirit_name">Name</label></th>
            <td><sf:input path="name" id="spirit_name" /></td>
        </tr>
        <tr>
            <th><label for="spirit_isAlive">Livelyness</label></th>
            <td>N/A: <sf:radiobutton path="isalive" value="null" /> Alive: <sf:radiobutton path="isalive" value="true" /> Dead: <sf:radiobutton path="isalive" value="false" /></td>
        </tr>
    </table>
    <sf:hidden path="id"/>
    <input type="submit" value="save" />                
</sf:form>

我得到的错误:

SEVERE: Servlet.service() for servlet jsp threw exception
org.springframework.beans.NotReadablePropertyException: Invalid property 'isAlive' of bean class [com.example.Spirit]: Bean property 'isAlive' is not readable or has an invalid getter method: Does the return type of the getter match the parameter type of the setter?
    at org.springframework.beans.BeanWrapperImpl.getPropertyValue(BeanWrapperImpl.java:707)
    at org.springframework.beans.BeanWrapperImpl.getPropertyValue(BeanWrapperImpl.java:699)
    at org.springframework.validation.AbstractPropertyBindingResult.getActualFieldValue(AbstractPropertyBindingResult.java:98)
    at org.springframework.validation.AbstractBindingResult.getFieldValue(AbstractBindingResult.java:224)
    at org.springframework.web.servlet.support.BindStatus.<init>(BindStatus.java:120)
    at org.springframework.web.servlet.tags.form.AbstractDataBoundFormElementTag.getBindStatus(AbstractDataBoundFormElementTag.java:174)
    at org.springframework.web.servlet.tags.form.AbstractDataBoundFormElementTag.getPropertyPath(AbstractDataBoundFormElementTag.java:194)
    at org.springframework.web.servlet.tags.form.AbstractDataBoundFormElementTag.getName(AbstractDataBoundFormElementTag.java:160)
    at org.springframework.web.servlet.tags.form.AbstractDataBoundFormElementTag.autogenerateId(AbstractDataBoundFormElementTag.java:147)
    at org.springframework.web.servlet.tags.form.AbstractCheckedElementTag.autogenerateId(AbstractCheckedElementTag.java:78)
    at org.springframework.web.servlet.tags.form.AbstractDataBoundFormElementTag.resolveId(AbstractDataBoundFormElementTag.java:138)
    at org.springframework.web.servlet.tags.form.AbstractSingleCheckedElementTag.writeTagContent(AbstractSingleCheckedElementTag.java:82)
    at org.springframework.web.servlet.tags.form.AbstractFormTag.doStartTagInternal(AbstractFormTag.java:102)
    at org.springframework.web.servlet.tags.RequestContextAwareTag.doStartTag(RequestContextAwareTag.java:79)
    at org.apache.jsp.WEB_002dINF.views.spirits.edit_jsp._jspx_meth_sf_005fradiobutton_005f0(edit_jsp.java:523)
    at org.apache.jsp.WEB_002dINF.views.spirits.edit_jsp._jspService(edit_jsp.java:201)

another question 非常相似,但这种情况下的解决方案是简单地将类型更改为 boolean,而不是 Boolean。不幸的是,更改三态的 get/set 方法只能作为最后的选择。我做错了什么?

【问题讨论】:

    标签: java forms spring spring-mvc binding


    【解决方案1】:

    最后,我最终做的是对 JSP 发送和绑定的值使用 &lt;select&gt; 框,然后通过 javascript 操作 UI 以隐藏实际的选择框并根据用户与自定义控件交互。

    这很有效,因为我最终需要超过 3 个状态,但缺点是它需要一个额外的类来对状态进行建模。

    【讨论】:

      【解决方案2】:

      您不应在 JSP 标记中指定 value=null。这将导致浏览器在 HTTP POST 中发送 isalive=null 值。

      由于无法将"null"(字符串)绑定到Boolean,这理所当然地会引发错误。

      如果用户没有选择单选按钮,那么浏览器将不会为表单参数发送任何内容(或者它会发送isalive=,我忘了是哪个 - 但没关系)。在这种情况下,Spring 不会尝试绑定该字段,这将使您的 POJO 带有 isAlive 字段和 null 值。

      总而言之 - 如果您在 HTML/JSP 标记中设置 value=null,您就是在告诉浏览器 POST 一个 string 文字 null。把它放在一边。

      【讨论】:

      • 让用户不选择单选按钮很好,但是(不使用javascript)如何取消选择单选按钮呢?据我所知,本机浏览器 UI 无法做到这一点,这就是为什么我在第一个位置有 3 个单选按钮。
      • 它根本不会发送isalive
      • 为什么需要取消选择? (如果这样做,只需将布尔模型属性设置回 null)。
      • 在这种情况下,您不会将value="" 设置为“取消选择”选项吗?请注意,根据the standard,始终需要选择其中一个单选按钮。对于您希望用户选择“true”、“false”或“unselected”的输入元素,下拉菜单可能是更好的选择。
      • @dbreaux - 我需要对真正的三态进行建模,因此 5 种不同的状态转换中的任何一种都是有效的,因此需要“取消选择”。
      猜你喜欢
      • 2011-07-24
      • 2021-10-23
      • 2014-01-20
      • 2010-12-04
      • 1970-01-01
      • 2011-08-24
      • 2016-04-05
      • 1970-01-01
      • 2015-10-16
      相关资源
      最近更新 更多