javascript spring mvc 3 动态列表绑定 + jquery + AJAX

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/13198145/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-26 18:02:40  来源:igfitidea点击:

spring mvc 3 dynamic list binding + jquery + AJAX

javascriptspringjqueryspring-mvc

提问by Mike G

I am facing an issue with dynamic list binding in Spring. I am trying to create an "Add Contact" page which basically looks like this:

我在 Spring 中面临动态列表绑定的问题。我正在尝试创建一个“添加联系人”页面,它基本上如下所示:

Contact Form

联系表

When the "Add Phone" button is clicked I want another "Phone Type" and "Phone Number" button to appear below so that the user can enter multiple phone numbers. This is where I am facing issues.

单击“添加电话”按钮时,我希望下面出现另一个“电话类型”和“电话号码”按钮,以便用户可以输入多个电话号码。这是我面临问题的地方。

Below is my code:

下面是我的代码:

Domain Class - Contact:

域类 - 联系方式:

In my form, The First Name, Last Name, Email and Birthday are instance variable of the domain class "Contact" and Phone Type and Phone Number of the part of List Phones.

在我的表单中,名字、姓氏、电子邮件和生日是域类“联系人”的实例变量以及列表电话部分的电话类型和电话号码。

    @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*/

    }

Class Phone:

班级电话:

    @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 Form(JSP):

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 on the above form:

上面表单上的Javascript:

What I am trying to do here is, when the "Add Phone" button is clicked, I send out an AJAX request to the server with the count of the row to be inserted.

我在这里尝试做的是,当单击“添加电话”按钮时,我向服务器发送一个 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>

Controller method called on AJAX request: It adds the row count to the model and returns a jsp - addnewphone.jsp

在 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: This contains the HTML fragment for the new row.

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>

I am trying to pass this view(contained in the variable 'data') into my AJAX callback function in the above javascript and add it to my original "Add Contact" form using - $("#addphone").before(data);

我正在尝试将此视图(包含在变量“数据”中)传递到上述 javascript 中的 AJAX 回调函数中,并使用 - $("#addphone").before(data) 将其添加到我原来的“添加联系人”表单中;

I am getting the following error when I click the "Add Phone button":

单击“添加电话”按钮时出现以下错误:

    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)

Basically, I am trying to contruct the HTML that I want to add in my main page in a separate jsp and trying to add that to my form dynamically. Is this a correct approach at all for my scenario. Please advice.

基本上,我试图在单独的 jsp 中构建我想要添加到主页中的 HTML,并尝试将其动态添加到我的表单中。对于我的场景,这是否是一种正确的方法。请指教。

采纳答案by Jeevan Patil

You are accepting something like contact.phones[${addphnbr}].phonetype in your jsp. And your controller has not sent this information along with jsp. That is why this error.

您正在 jsp 中接受类似 contact.phones[${addphnbr}].phonetype 的内容。并且您的控制器还没有将这些信息与 jsp 一起发送。这就是这个错误的原因。

Your controller should provide "contact" attribute to your jsp. Now you are sending "addphonecount" to jsp and you dont seem to use it on jsp. You might need to send "contact" instead.

您的控制器应该为您的 jsp 提供“contact”属性。现在您正在向 jsp 发送“addphonecount”,而您似乎没有在 jsp 上使用它。您可能需要改为发送“联系人”。

@RequestMapping(value = "/displayaddphone")
public String appendaddphone(@RequestParam(value="count") int addphonecount,ModelMap model){
    // define "contact" object, suppose for example
    Contact contact = populateContact();
    model.addAttribute("contact", contact);
    return "addnewphone";
}