我在 Spring 中遇到了动态列表绑定的问题。我正在尝试创建一个基本上如下所示的“添加联系人”页面:
单击“添加电话”按钮时,我希望下方出现另一个“电话类型”和“电话号码”按钮,以便用户可以输入多个电话号码。这是我面临问题的地方。
下面是我的代码:
域类 - 联系人:
在我的表单中,名字、姓氏、电子邮件和生日是域类“联系人”的实例变量以及列表电话部分的电话类型和电话号码。
@Entity
@Table(name = "CONTACTS_JPA2")
public class Contact {
@Id
@Column(name = "CONTACT_ID")
@GeneratedValue
private int Id;
@Column(name = "FIRST_NAME")
private String firstname;
@Column(name = "LAST_NAME")
private String lastname;
@SuppressWarnings("unchecked")
@OneToMany(mappedBy = "contact", cascade = CascadeType.ALL)
private List<Phone> phones = LazyList.decorate(new ArrayList<Phone>(),FactoryUtils.instantiateFactory(Phone.class));
@Column(name = "EMAIL_ID")
private String emailid;
@Column(name = "BIRTHDAY")
private Date birthday;
/*Getters and Setters*/
}
上课电话:
@Entity
@Table(name = "PHONE")
public class Phone {
@Id
@Column(name = "ID")
private int Id;
@Column(name = "PHONE_NBR")
private String phonenumber;
@Column(name = "PHONE_TYPE")
private String phonetype;
@ManyToOne()
@JoinColumn(name = "CONTACT_ID")
private Contact contact;
/*Getters and Setter*/
}
HTML 表单(JSP):
<form:form id = "addcontactform" name="addcontact" method="POST" commandName="contact">
<table>
<tr>
<td>First Name:</td>
<td><form:input name = "firstname" id = "firstname" path="firstname" value=''/></td>
<td>Last Name:</td>
<td><form:input name = "lastname" id = "lastname" path="lastname" value=''/></td>
</tr>
<tr>
<td>Email:</td>
<td><form:input name = "emailid" id = "emailid" path="emailid"/></td>
</tr>
<tr>
<td>Phone Type:</td>
<td>
<spring:bind path = "contact.phones[0].phonetype">
<form:select id ="phonetype" name="phonetype" path="${status.expression}">
<option value="-- Select Phone Type --">-- Select Phone Type --</option>
<option value="Home">Home</option>
<option value="Cell">Cell</option>
<option value="Work">Work</option>
</form:select>
</spring:bind>
</td>
<td>Phone Number:</td>
<td>
<spring:bind path = "contact.phones[0].phonenumber">
<form:input name = "phonenumber" id = "phonenumber" path="${status.expression}" value=''/>
</spring:bind>
</td>
<td><form:button type = "button" id = "addphone">Add Phone</form:button>
</tr>
<tr>
<td>Birthday:</td>
<td><form:input id = "birthday" path="birthday" value=''/></td>
</tr>
</table>
</div>
<input type="submit" id = "mysubmit" name="mysubmit" value="Add Contact" />
</div>
</form:form>
上述表单上的 Javascript:
我在这里要做的是,当单击“添加电话”按钮时,我会向服务器发送一个 AJAX 请求,其中包含要插入的行数。
<script type="text/javascript" src="${pageContext.request.contextPath}/resources/scripts/jquery.min.js"></script>
<script type="text/javascript">
$(document).ready(function(){
$('#addphone').click(function(){
phonecount++;
alert('Addinh phone '+phonecount);
$.get("displayaddphone", {count : phonecount},callback);
function callback(data){
alert('in Callback');
$("#addphone").before(data);
};
return false;
});
</script>
在 AJAX 请求上调用的控制器方法:它将行数添加到模型并返回一个 jsp - addnewphone.jsp
@RequestMapping(value = "/displayaddphone")
public String appendaddphone(@RequestParam(value="count") int addphonecount,ModelMap model){
model.addAttribute("addphonecount", addphonecount);
return "addnewphone";
}
addnewphone JSP:这包含新行的 HTML 片段。
<%@ taglib uri="http://www.springframework.org/tags/form" prefix="form"%>
<%@ taglib uri="http://www.springframework.org/tags" prefix="spring" %>
<tr>
<td>Phone Type:</td>
<td>
<form:select id ="phonetype" name="phonetype" path="contact.phones[${addphnbr}].phonetype">
<option value="-- Select Phone Type --">-- Select Phone Type --</option>
<option value="Home">Home</option>
<option value="Cell">Cell</option>
<option value="Work">Work</option>
</form:select>
</td>
<td>Phone Number:</td>
<td>
<form:input name = "phonenumber" id = "phonenumber" path="contact.phones[${addphnbr}].phonenumber" value=''/>
</td>
</tr>
我正在尝试将此视图(包含在变量“数据”中)传递到上面 javascript 中的 AJAX 回调函数中,并使用 - $(“#addphone”).before(data) 将其添加到我原来的“添加联系人”表单中;
单击“添加电话按钮”时出现以下错误:
SEVERE: Servlet.service() for servlet [appServlet] in context with path [/ContactList-JPA2] threw exception [java.lang.IllegalStateException: Neither BindingResult nor plain target object for bean name 'contact' available as request attribute] with root cause
java.lang.IllegalStateException: Neither BindingResult nor plain target object for bean name 'contact' available as request attribute
at org.springframework.web.servlet.support.BindStatus.<init>(BindStatus.java:141)
at org.springframework.web.servlet.tags.form.AbstractDataBoundFormElementTag.getBindStatus(Abs tractDataBoundFormElementTag.java:178)
at org.springframework.web.servlet.tags.form.AbstractDataBoundFormElementTag.getPropertyPath(AbstractDataBoundFormElementTag.java:198)
at org.springframework.web.servlet.tags.form.AbstractDataBoundFormElementTag.getName(AbstractDataBoundFormElementTag.java:164)
at org.springframework.web.servlet.tags.form.AbstractDataBoundFormElementTag.writeDefaultAttributes(AbstractDataBoundFormElementTag.java:127)
at org.springframework.web.servlet.tags.form.AbstractHtmlElementTag.writeDefaultAttributes(AbstractHtmlElementTag.java:421)
at org.springframework.web.servlet.tags.form.SelectTag.writeTagContent(SelectTag.java:199)
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.addnewphone_jsp._jspx_meth_form_005fselect_005f0(addnewphone_jsp.java:117)
at org.apache.jsp.WEB_002dINF.views.addnewphone_jsp._jspService(addnewphone_jsp.java:76)
at org.apache.jasper.runtime.HttpJspBase.service(HttpJspBase.java:70)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:722)
at org.apache.jasper.servlet.JspServletWrapper.service(JspServletWrapper.java:432)
at org.apache.jasper.servlet.JspServlet.serviceJspFile(JspServlet.java:390)
at org.apache.jasper.servlet.JspServlet.service(JspServlet.java:334)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:722)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:305)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:210)
at org.apache.catalina.core.ApplicationDispatcher.invoke(ApplicationDispatcher.java:690)
at org.apache.catalina.core.ApplicationDispatcher.processRequest(ApplicationDispatcher.java:477)
at org.apache.catalina.core.ApplicationDispatcher.doForward(ApplicationDispatcher.java:402)
at org.apache.catalina.core.ApplicationDispatcher.forward(ApplicationDispatcher.java:329)
at org.springframework.web.servlet.view.InternalResourceView.renderMergedOutputModel(InternalResourceView.java:238)
at org.springframework.web.servlet.view.AbstractView.render(AbstractView.java:262)
at org.springframework.web.servlet.DispatcherServlet.render(DispatcherServlet.java:1157)
at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:927)
at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:827)
at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:882)
at org.springframework.web.servlet.FrameworkServlet.doGet(FrameworkServlet.java:778)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:621)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:722)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:305)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:210)
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:311)
at org.springframework.security.web.access.intercept.FilterSecurityInterceptor.invoke(FilterSecurityInterceptor.java:116)
at org.springframework.security.web.access.intercept.FilterSecurityInterceptor.doFilter(FilterSecurityInterceptor.java:83)
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:323)
at org.springframework.security.web.access.ExceptionTranslationFilter.doFilter(ExceptionTranslationFilter.java:113)
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:323)
at org.springframework.security.web.session.SessionManagementFilter.doFilter(SessionManagementFilter.java:101)
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:323)
at org.springframework.security.web.authentication.AnonymousAuthenticationFilter.doFilter(AnonymousAuthenticationFilter.java:113)
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:323)
at org.springframework.security.web.servletapi.SecurityContextHolderAwareRequestFilter.doFilter(SecurityContextHolderAwareRequestFilter.java:54)
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:323)
at org.springframework.security.web.savedrequest.RequestCacheAwareFilter.doFilter(RequestCacheAwareFilter.java:45)
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:323)
at org.springframework.security.web.authentication.www.BasicAuthenticationFilter.doFilter(BasicAuthenticationFilter.java:150)
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:323)
at org.springframework.security.web.authentication.AbstractAuthenticationProcessingFilter.doFilter(AbstractAuthenticationProcessingFilter.java:182)
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:323)
at org.springframework.security.web.authentication.logout.LogoutFilter.doFilter(LogoutFilter.java:105)
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:323)
at org.springframework.security.web.context.SecurityContextPersistenceFilter.doFilter(SecurityContextPersistenceFilter.java:87)
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:323)
at org.springframework.security.web.FilterChainProxy.doFilter(FilterChainProxy.java:173)
at org.springframework.web.filter.DelegatingFilterProxy.invokeDelegate(DelegatingFilterProxy.java:346)
at org.springframework.web.filter.DelegatingFilterProxy.doFilter(DelegatingFilterProxy.java:259)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:243)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:210)
at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:225)
at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:123)
at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:472)
at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:168)
at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:98)
at org.apache.catalina.valves.AccessLogValve.invoke(AccessLogValve.java:927)
at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:118)
at com.springsource.insight.collection.tcserver.request.HttpRequestOperationCollectionValve.invoke(HttpRequestOperationCollectionValve.java:88)
at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:407)
at org.apache.coyote.http11.AbstractHttp11Processor.process(AbstractHttp11Processor.java:1001)
at org.apache.coyote.AbstractProtocol$AbstractConnectionHandler.process(AbstractProtocol.java:585)
at org.apache.tomcat.util.net.JIoEndpoint$SocketProcessor.run(JIoEndpoint.java:312)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1110)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:603)
at java.lang.Thread.run(Thread.java:722)
基本上,我正在尝试在单独的 jsp 中构建要添加到主页中的 HTML,并尝试将其动态添加到我的表单中。对于我的场景来说,这完全是正确的方法吗?请指教。