Note that there are some explanatory texts on larger screens.

plurals
  1. POCan't configure <form:input> within <foreach> tag
    text
    copied!<p>I am using the Spring form tag library in my JSP. My command object contains a List and i want to make bindings for each object of the list in my JSP. But STS gives me an Exception that tells that: </p> <blockquote> <p>Bean property 'testList[0]' is not readable or has an invalid getter method: Does the return type of the getter match the parameter type of the setter?]</p> </blockquote> <p>Here is full Exception code:</p> <pre><code>SEVERE: Servlet.service() for servlet [appServlet] in context with path [/mvc] threw exception [org.springframework.beans.NotReadablePropertyException: Invalid property 'testList[0]' of bean class [java.util.ArrayList]: Bean property 'testList[0]' is not readable or has an invalid getter method: Does the return type of the getter match the parameter type of the setter?] with root cause org.springframework.beans.NotReadablePropertyException: Invalid property 'testList[0]' of bean class [java.util.ArrayList]: Bean property 'testList[0]' is not readable or has an invalid getter method: Does the return type of the getter match the parameter type of the setter? at org.springframework.beans.BeanWrapperImpl.getPropertyValue(BeanWrapperImpl.java:729) at org.springframework.beans.BeanWrapperImpl.getNestedBeanWrapper(BeanWrapperImpl.java:576) at org.springframework.beans.BeanWrapperImpl.getBeanWrapperForPropertyPath(BeanWrapperImpl.java:553) at org.springframework.beans.BeanWrapperImpl.getPropertyValue(BeanWrapperImpl.java:719) at org.springframework.web.servlet.support.BindStatus.&lt;init&gt;(BindStatus.java:147) at org.springframework.web.servlet.tags.form.AbstractDataBoundFormElementTag.getBindStatus(AbstractDataBoundFormElementTag.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.autogenerateId(AbstractDataBoundFormElementTag.java:151) at org.springframework.web.servlet.tags.form.AbstractDataBoundFormElementTag.resolveId(AbstractDataBoundFormElementTag.java:142) at org.springframework.web.servlet.tags.form.AbstractDataBoundFormElementTag.writeDefaultAttributes(AbstractDataBoundFormElementTag.java:126) at org.springframework.web.servlet.tags.form.AbstractHtmlElementTag.writeDefaultAttributes(AbstractHtmlElementTag.java:421) at org.springframework.web.servlet.tags.form.InputTag.writeTagContent(InputTag.java:142) 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.test_jsp._jspx_meth_form_005finput_005f0(test_jsp.java:217) at org.apache.jsp.WEB_002dINF.views.test_jsp._jspx_meth_c_005fforEach_005f0(test_jsp.java:167) at org.apache.jsp.WEB_002dINF.views.test_jsp._jspx_meth_form_005fform_005f0(test_jsp.java:122) at org.apache.jsp.WEB_002dINF.views.test_jsp._jspService(test_jsp.java:82) 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:749) at org.apache.catalina.core.ApplicationDispatcher.processRequest(ApplicationDispatcher.java:487) at org.apache.catalina.core.ApplicationDispatcher.doForward(ApplicationDispatcher.java:412) at org.apache.catalina.core.ApplicationDispatcher.forward(ApplicationDispatcher.java:339) 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:1180) at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:950) at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:852) 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.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:222) 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:99) at org.apache.catalina.valves.AccessLogValve.invoke(AccessLogValve.java:929) at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:118) at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:407) at org.apache.coyote.http11.AbstractHttp11Processor.process(AbstractHttp11Processor.java:1002) at org.apache.coyote.AbstractProtocol$AbstractConnectionHandler.process(AbstractProtocol.java:585) at org.apache.tomcat.util.net.JIoEndpoint$SocketProcessor.run(JIoEndpoint.java:310) 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) </code></pre> <p>Here is my .jsp page :</p> <pre><code>&lt;%@ taglib uri="http://www.springframework.org/tags/form" prefix="form"%&gt; &lt;%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %&gt; &lt;html&gt; &lt;head&gt; &lt;title&gt;Home&lt;/title&gt; &lt;/head&gt; &lt;body&gt; &lt;h1&gt; Hello! &lt;/h1&gt; &lt;form:form action="saveStudent" method="POST" modelAttribute = "testList"&gt; &lt;c:forEach items="${testList}" var="test" varStatus="pStatus"&gt; Test Question: &lt;form:input path = "testList[${pStatus.index}].testQuestion" value = "${test.testQuestion}"/&gt; Option one: &lt;form:input path = "testList[${pStatus.index}].optionOne" value= "${test.optionOne}"/&gt; Option two: &lt;form:input path = "testList[${pStatus.index}].optionTwo" value= "${test.optionTwo}"/&gt; Option three: &lt;form:input path = "testList[${pStatus.index}].optionThree" value= "${test.optionThree}"/&gt; &lt;/c:forEach&gt; &lt;input type="submit" value="Submit" /&gt; &lt;/form:form&gt; &lt;/body&gt; &lt;/html&gt; </code></pre> <p>Here is my method code: </p> <pre><code>@RequestMapping(value = "/test", method = RequestMethod.GET) public String redactTest(Model model, HttpServletRequest request) { List&lt;Test&gt; testList = db.getTests(); model.addAttribute("testList", testList); return "test"; } </code></pre> <p>What i'm doing wrong? Any suggestions? Thanks! </p> <p>OK, i have a solution: first i've added TestWrapper class which contains List with get and set:</p> <pre><code>public class TestWrapper { private List&lt;Test&gt; testList = null; public TestWrapper(List&lt;Test&gt; testList) { this.testList = testList; } public void setTestList(List&lt;Test&gt; testList) { this.testList = testList; } public List&lt;Test&gt; getTestList() { return testList; } } </code></pre> <p>Then i've changed my method code: </p> <pre><code>@RequestMapping(value = "/test", method = RequestMethod.GET) public String redactTest(Model model, HttpServletRequest request) { List&lt;Test&gt; testList = db.getTests(); TestWrapper testWrapper = new TestWrapper(testList); model.addAttribute("testWrapper", testWrapper); return "test"; } </code></pre> <p>and after i've changed my .jsp:</p> <pre><code>&lt;%@ taglib uri="http://www.springframework.org/tags/form" prefix="form"%&gt; &lt;%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %&gt; &lt;html&gt; &lt;head&gt; &lt;title&gt;Home&lt;/title&gt; &lt;/head&gt; &lt;body&gt; &lt;h1&gt; Hello! &lt;/h1&gt; &lt;form:form action="saveStudent" method="POST" modelAttribute = "testWrapper"&gt; &lt;c:forEach items="${testWrapper.testList}" var="test" varStatus="i"&gt; Test Question: &lt;form:input path = "testList[${i.index}].testQuestion" value = "${test.testQuestion}"/&gt; Option one: &lt;form:input path = "testList[${i.index}].optionOne" value= "${test.optionOne}"/&gt; Option two: &lt;form:input path = "testList[${i.index}].optionTwo" value= "${test.optionTwo}"/&gt; Option three: &lt;form:input path = "testList[${i.index}].optionThree" value= "${test.optionThree}"/&gt; &lt;/c:forEach&gt; &lt;input type="submit" value="Submit" /&gt; &lt;/form:form&gt; &lt;/body&gt; &lt;/html&gt; </code></pre> <p>And now it works! Hope it will help someone :)</p>
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload