绑定到集合的Spring MVC复选框标记需要对象,但验证需要object.id

时间:2010-11-18 10:26:23

标签: spring-mvc validation checkbox spring-roo

在我的Spring MVC项目中,我有一个Class1的更新页面,它必须显示一个form:checkbox标签列表,它绑定到Class1上的实体集合。

Class1.java:

class Class1 {
  private Set<Class2> set;
  //... other fields 
}

在updateclass1.jspx中:

<c:forEach items="${allClass2Instances}" var="class2">
   <form:checkbox label="${class2.name}" path="set" value="${class2}"/><br/>
</c:forEach>

使用上面的checkbox标签,当我显示页面时,如果Class2实例是class1上Set的一部分,则勾选复选框,如果不是,则选中unticeed。但是当我点击提交时,我收到以下错误:

Failed to convert property value of type 'java.lang.String[]' to required type 'java.util.Set' for property 'set'; nested exception is org.springframework.core.convert.ConversionFailedException: Unable to convert value "Name 1" from type 'java.lang.String' to type 'java.lang.Long'; nested exception is java.lang.NumberFormatException: For input string: "Name1"

据我所知,填充页面时,form:checkbox标签需要一个实例来设置正确的已检查/未检查值,但是在提交时,JSP会将一个class2.toString()值数组发送给需要ID的转换器。相反,当我将标签更改为以下内容时:

<form:checkbox label="${class2.name}" path="set" value="${class2.id}"/><br/>

绑定工作正常,但是当我查看更新页面时,复选框没有被正确选中/取消选中,因为标签不知道传入的值是对象ID。

如何使提交后的绑定与复选框标记所期望的一致?

如果重要 - 这都在Roo生成的脚手架页面内。

1 个答案:

答案 0 :(得分:0)

想出如何使这项工作现在。如果有人想出一个更整洁的解决方案,请添加它,我会将其标记为正确。

上述问题是由于需要$ {InstanceOfClass2}来评估不同地方的不同内容所致:

  1. 在评估标记时,<form:checkbox>需要一个表达式,该表达式计算为Class2的实际实例
  2. 标记完成后,生成的<input type="checkbox">标记的value属性需要等于Class2实例的数字ID字段
  3. 解决方案是在我的Class1Controller中添加一个转换器,例如:

    Converter<Class2, String> getClass2Converter() {
        return new Converter<Class2, String>() {
            public String convert(Class2 instance) {
                return "" + instance.getId();
            }
        };
    }
    

    因此,表达式$ {InstanceOfClass2}计算复选框标签的Class2实例,但是当写入时,实际的HTML将转换为数字ID。

    使用Roo时,这种方法非常混乱。所有与Class1相关的其他脚手架都希望使用同一个Converter,所以我开始在任何地方看到一大堆你想要看到Class2.name或其他类似字段的ID。我通过修改Spring Roo <field:display>自定义标记解决了这个问题 - 添加了一个属性fmtCollectionToString,如果存在,则强制标记通过迭代它们并在每个元素上调用toString来评估集合,而不是调用spring:eval整个集合,似乎也最终调用了转换器。

    就像我说的,整洁的解决方案非常感谢!如果有一种方法可以使转换器在不同情况下表现不同,例如 - 仍然希望听到它。