如何使用Spring MVC 3 Form radiobutton标签处理三态布尔?

时间:2011-07-20 14:25:54

标签: java forms spring spring-mvc binding

我的一个对象中有一个三态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方法仅作为最后选择。我做错了什么?

2 个答案:

答案 0 :(得分:2)

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

由于无法将"null"(字符串)绑定到Boolean,因此这会引发错误。

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

总而言之 - 如果在HTML / JSP标记中设置value=null,则告诉浏览器POST一个字符串文字null。把它留下来吧。

答案 1 :(得分:0)

最后,我最终做的是使用<select>框来表示JSP发送和绑定的值,然后通过javascript操纵UI来隐藏实际的选择框并更新它用户与自定义控件交互。

这非常有效,因为我最终需要超过3个州,但缺点是它需要额外的类来模拟状态。