Spring MVC - 下拉对象选择 - 没有主要标识符

时间:2010-11-11 14:28:24

标签: java spring jsp spring-mvc

一个相当常见的用例出现在有一个Java对象列表的地方,从中可以在Web表单上进行选择 - 通常你会使用对象的主键作为值,这样控制器可以做查找,或者只是将键绑定到创建/更新的对象。

我的问题是,可供选择的列表不是持久的,键控对象,它们是来自服务的商业模型,没有合理的方法根据所包含的数据检索它们。下面是一些伪代码,其中给页面提供了Foo的列表,我们可以轻松地与控制器通信,提交Foo的名称,但是如果还有其他Foo字段需要提交呢?

控制器:

referenceData() {
    ...
    List foos = fooService.getFoosForBar( bar )
    return { 'foos', foos }
}

JSP:

<form>
   ...
<spring:bind path="formData.foo">
    <select name="<c:out value="${status.expression}" />">
        <c:forEach items="${foos}" var="foo">
            <option value="<c:out value="${foo.name}"/>">
                <c:out value="${foo.name}"/>
            </option>
        </c:forEach>
    </select>
</spring:bind>
   ...
</form>

一些示例解决方案是使用隐藏字段提交Foo的其他属性并在选择更改时保持它们同步,但我不希望在这样的情况下使用JavaScript,这可能会增加混淆。当然也有其他方法可以实现这一目标。

我的问题是,是否存在完成此任务的标准做法?或者我应该想出自己的方式呢?如果可能的话,我宁愿不再重新发明轮子,这看起来很普遍,只是它可能不是最好的方法。

2 个答案:

答案 0 :(得分:6)

根据您的限制,您必须将foos的其他数据成员编码为选项的值。
<option label="${foo.name}" value="${foo.encodedValues}"/>
encodedValues方法可能如下所示:


    private String SEPARATOR = ",";

    public String getEncodedValues()
    {
        final StringBuffer returnValue = new StringBuffer();

        returnValue.append(field1);
        returnValue.append(SEPARATOR);
        returnValue.append(field2);
        returnValue.append(SEPARATOR);
        returnValue.append(field3);

        return returnValue.toString();
    }

如果您有许多需要编码值的选择,您可能需要创建一个类来对这些值进行编码和解码以集中代码。

答案 1 :(得分:3)

您可以使用列表中元素的索引将其返回到POST请求中。

<spring:bind path="formData.fooIndex">
  <select name="<c:out value="${status.expression}" />">
    <c:forEach items="${foos}" var="foo" varStatus="i">
        <option value="<c:out value="${i.index}"/>">
            <c:out value="${foo.name}"/>
        </option>
    </c:forEach>
  </select>
</spring:bind>

在POST处理程序中,使用foos.get(formData.getFooIndex()) 如果foos可以在GET和POST请求之间更改,则需要将foos置于会话中,以便您在POST处理程序中明确引用与GET处理程序中相同的对象。