简体   繁体   English

Spring mvc,如何绑定具有集合作为其属性的域对象

[英]Spring mvc, how to bind a domain object that has a collection as its property

I have a domain object called Order, and it has a collection attribute called serviceOrders where a collection of service --- order m:m association relationships are hold. 我有一个名为Order的域对象,它有一个名为serviceOrders的集合属性,其中包含一个服务集合---订单m:m关联关系。

public class Order implements Serializable {

 private Long id = null;
 private BigDecimal amountPaid;
 private BigDecimal accountReceivable; 
 private User user;
 private Set serviceOrders = new HashSet();
 private Date closed;
 private Date created = new Date();
 private String status;

also there is a method for adding the association called addServiceOrder 还有一种添加名为addServiceOrder的关联的方法

public void addServiceOrder(ServiceOrder serviceOrder) {
  if (serviceOrder == null)
   throw new IllegalArgumentException("Can't add a null serviceOrder.");
  this.getServiceOrders().add(serviceOrder);
 }

how should I use commandName to set this collection with "path", I think it would only call its get set method of the Command Object. 我应该如何使用commandName将此集合设置为“path”,我认为它只会调用其命令对象的get set方法。 how should I add serviceOrder to this command Object. 我应该如何将serviceOrder添加到此命令对象中。 I have no idea about this problem. 我不知道这个问题。 any help would be highly appreciated 任何帮助将受到高度赞赏

假设您的ServiceOrder实例具有唯一ID,则您的服务方法应为#add(Long id)。

Ok bear with me on this one but the solution is simple an annoying at the same time. 好的,请耐心等待,但解决方案很简单,同时也很烦人。 I ran into this a couple of months ago. 几个月前我碰到了这个。 I am going to show you my solution using the jstl libraries in my view for handling the collections. 我将在我的视图中使用jstl库向您展示我的解决方案,以处理集合。

<c:forEach items="${Questions}" var="quest" varStatus="itemsIndex">
        <fieldset>
          <legend>${quest.section}</legend>
          <form:form id="group${itemsIndex.index}" modelAttribute="ChoiceList" action="" method="POST" onsubmit="javascript:ajaxSave($(this).serialize()); return false;">
            <a id="Group${quest.id}"></a>
            <c:forEach items="${quest.qisQuestionsCollection}" var="quest2" varStatus="itemsRow">
              <div style="font-weight: bold; margin: 10px 0px">${quest2.shortText}</div>
              ( ${quest2.qisQuestionTypes.description} )<br/>
          ( ${quest2.helpText} )<br/>
              <a id="Question${quest2.id}"></a>
              <c:choose>
                <c:when test="${quest2.qisQuestionTypes.questionType == 'CHOOSEANY'}">
                  <c:forEach items="${quest2.qisChoicesCollection}" var="quest3" varStatus="indexStatus">
                    <c:forEach items="${ChoiceFields}" var="CField">
                      <c:set scope="request" value="${quest3}" var="ChoiceData"/>
                      <c:set scope="request" value="${CField}" var="ChoiceProperty"/>
                      <%
                                answerMap = (HashMap<QisChoice, Answer>) request.getAttribute("AnswerList");
                                choice = (QisChoice) request.getAttribute("ChoiceData");
                                if (answerMap.containsKey(choice.getChoiceID())) {
                                  Answer theAnswer = (Answer) answerMap.get(choice.getChoiceID());
                                  if (theAnswer != null) {
                                    if (theAnswer.getChoiceValue() != null) {
                                      request.setAttribute("itemValue", theAnswer.getChoiceValue());
                                      request.setAttribute("itemSelected", true);
                                    } else {
                                      request.setAttribute("itemSelected", false);
                                      request.setAttribute("itemValue", getReflectedValue(
                                              (QisChoice) request.getAttribute("ChoiceData"),
                                              (AccessorStruct) request.getAttribute("ChoiceProperty")));
                                    }
                                  }
                                } else {
                                  request.setAttribute("itemSelected", false);
                                  request.setAttribute("itemValue", getReflectedValue(
                                          (QisChoice) request.getAttribute("ChoiceData"),
                                          (AccessorStruct) request.getAttribute("ChoiceProperty")));
                                }
                                request.setAttribute("itemValue2", getReflectedValue(
                                        (QisChoice) request.getAttribute("ChoiceData"),
                                        (AccessorStruct) request.getAttribute("ChoiceProperty")));
                      %>
                      <c:choose>
                        <c:when test="${CField.visible == 'HIDDEN'}">
                          <form:hidden value="${itemValue2}" path="question[${itemsRow.index}].choice[${indexStatus.index}].${CField.beanName}" />
                        </c:when>
                        <c:otherwise>
                          <c:choose>
                            <c:when test="${itemSelected}">
                              <form:checkbox value="${itemValue}" label="${quest3.description}" path="question[${itemsRow.index}].choice[${indexStatus.index}].${CField.beanName}" checked="true" /><br/>
                            </c:when>
                            <c:otherwise>
                              <form:checkbox value="${itemValue}" label="${quest3.description}" path="question[${itemsRow.index}].choice[${indexStatus.index}].${CField.beanName}" /><br/>
                            </c:otherwise>
                          </c:choose>

                        </c:otherwise>
                      </c:choose>
                    </c:forEach>
                  </c:forEach>
                </c:when>

            <input type="submit" value="Save Section"
                   class="button-main" />
          </fieldset>
        </form:form>
      </c:forEach>`

The Key bit is in this line Key位在此行中

<form:checkbox value="${itemValue}" label="${quest3.description}" path="question[${itemsRow.index}].choice[${indexStatus.index}].${CField.beanName}" checked="true" /><br/>

To link up the command object with its collection for the postback you have to show the indice of the element as part of the spring path. 要将命令对象与其回发集合链接以进行回发,您必须将该元素的指示显示为弹簧路径的一部分。 In my case I have two levels of collections to track 在我的情况下,我有两个级别的集合来跟踪

<c:forEach items="${quest.qisQuestionsCollection}" var="quest2" varStatus="itemsRow">

varStatus gives you access to a bean object with the index property you can use to your advantage. varStatus使您可以使用您可以使用的索引属性访问bean对象。

In your case you can do just use the index property of the foreach jstl function in the jsp to generate the indice like I did and append it to the array index notation of your command object. 在你的情况下,你可以只使用jsp中的foreach jstl函数的index属性来生成像我一样的indice并将它附加到命令对象的数组索引表示法。 The command object must of course follow the same flow as the path collection names. 命令对象当然必须遵循与路径集合名称相同的流程。 This works for an infinite number of levels but gets more annoying as we go. 这适用于无数级别,但随着我们的进展会变得更加烦人。

This is a large live example so if you need something smaller show me your markup and I will walk you throgh it. 这是一个很大的现场例子,所以如果你需要更小的东西,请告诉我你的标记,我会告诉你。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM