Spring MVC表单:以一对多的关系动态添加表单选择选项

时间:2014-09-22 14:39:28

标签: spring forms jsp

我有一个复杂对象的弹簧形式,其中包含一对一关系对象中的电子邮件地址对象列表,该对象包含一对多电子邮件地址。用例如下:用户想要向表单中的现有电子邮件地址添加新的电子邮件地址。这是通过弹出窗口和jQuery完成的,jQuery在select语句中附加一个新的选项元素:

<option value="0">new.email@address.com</option>

加载形式中的所有预先填充的选项当然已经设置了ID,例如:

<option value="1">existing.email@email.com</option>

在我的控制器中,提交的表单包含ID字段(1表示预填充对象,0表示&#39;新&#39;电子邮件地址),但实际值在表单中为null - 即first@email.com不与表单一起提交并绑定到EmailAddress对象中的emailAddress字段:

此代码:

List<EmailAddress> emailAddress = batchJob.getDestinationExtras().getMailsInternal();
for (EmailAddress e : emailAddress) {
    logger.info(e.getEmailAddressId() + " "+e.getEmailAddress());
} 

结果输出: 1 null 0 null

这对于现有对象来说不是问题,因为使用ID可以简单地使用hibernate从数据库中检索它们,或者在解析阶段(我正在使用EmailAddress对象的格式化程序实现)。但对于新的&#39;用户动态创建的对象我遇到问题,因为它们尚未存在于数据库中,因此无法以这种方式检索实际的电子邮件地址值。

什么可以解决这个问题?

JSP标记如下:

<form:select multiple="true" path="destinationExtras.mailsInternal" id="internalMailsList">
    <form:options items="${internalMailsList}" itemValue="emailAddressId" itemLabel="emailAddress" />
</form:select>

下面涉及的对象的相关部分 - 省略不相关的其他字段和ID字段:

@Entity
@Table(name="batchjob")
public class BatchJob {

    (...) id + other fields

    @ManyToOne(cascade=CascadeType.ALL)
    @JoinColumn(name="destinationextrasid")
    private DestinationExtras destinationExtras;

    (...) getters and setters
}

@Entity
@Table(name="destinationextras")
public class DestinationExtras {

    @OneToMany(cascade = CascadeType.ALL)
    @JoinColumn(name="emailaddressid")
    private List<EmailAddress> mailsInternal;

}


@Entity
@Table(name="emailaddresses")
public class EmailAddress {

    @Id
    @GeneratedValue(strategy=GenerationType.SEQUENCE, generator="SEQ_EMAILADDRESSID")
    @SequenceGenerator(name="SEQ_EMAILADDRESSID",sequenceName="SEQ_EMAILADDRESSID",allocationSize=1)
    private int emailAddressId;

    @Column(name="email_address")
    private String emailAddress;
}

1 个答案:

答案 0 :(得分:0)

当它出错时,考虑一下低级HTTP协议...... JQuery非常聪明,Spring也是如此,但它们只能通过HTTP进行通信!在提交包含<select>字段的表单时,唯一发送的是所选选项的

因此,如果您希望Spring使用新电子邮件的文本,您可以尝试将其放在<option>字段的值中,例如:

<option value="new.email@address.com">new.email@address.com</option>

但我认为您必须更改所有选择以系统地将文本用作值并在控制器中更改它,以避免混合整数ID和文本。您的选择将是:

<form:options items="${internalMailsList}" itemValue="emailAddress" itemLabel="emailAddress" />

你也可以在jQuery的帮助下添加一个隐藏字段,并将电子邮件文本作为值,如果找到0的值,则使用它,如下所示:

<input type="hidden" name="newmail" value="new.email@address.com"/>
<select ...>
    <option value="0">new.email@address.com</option>

个人而言,我会优先考虑第二种方式,但这实际上取决于你的控制器结构。