我在我的 JSP 中使用 Spring 表单标记库。我的命令对象包含一个列表,我想为我的 JSP 中列表的每个对象进行绑定。但是 STS 给了我一个例外,告诉我:
Bean 属性 'testList[0]' 不可读或具有无效的 getter 方法:getter 的返回类型是否与 setter 的参数类型匹配?]
这是完整的异常代码:
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.<init>(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)
这是我的 .jsp 页面:
<%@ taglib uri="http://www.springframework.org/tags/form" prefix="form"%>
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>
<html>
<head>
<title>Home</title>
</head>
<body>
<h1>
Hello!
</h1>
<form:form action="saveStudent" method="POST" modelAttribute = "testList">
<c:forEach items="${testList}" var="test" varStatus="pStatus">
Test Question: <form:input path = "testList[${pStatus.index}].testQuestion" value = "${test.testQuestion}"/>
Option one: <form:input path = "testList[${pStatus.index}].optionOne" value= "${test.optionOne}"/>
Option two: <form:input path = "testList[${pStatus.index}].optionTwo" value= "${test.optionTwo}"/>
Option three: <form:input path = "testList[${pStatus.index}].optionThree" value= "${test.optionThree}"/>
</c:forEach>
<input type="submit" value="Submit" />
</form:form>
</body>
</html>
这是我的方法代码:
@RequestMapping(value = "/test", method = RequestMethod.GET)
public String redactTest(Model model, HttpServletRequest request) {
List<Test> testList = db.getTests();
model.addAttribute("testList", testList);
return "test";
}
我做错了什么?有什么建议么?谢谢!
好的,我有一个解决方案:首先我添加了 TestWrapper 类,其中包含带有 get 和 set 的 List:
public class TestWrapper {
private List<Test> testList = null;
public TestWrapper(List<Test> testList) {
this.testList = testList;
}
public void setTestList(List<Test> testList) {
this.testList = testList;
}
public List<Test> getTestList() {
return testList;
}
}
然后我改变了我的方法代码:
@RequestMapping(value = "/test", method = RequestMethod.GET)
public String redactTest(Model model, HttpServletRequest request) {
List<Test> testList = db.getTests();
TestWrapper testWrapper = new TestWrapper(testList);
model.addAttribute("testWrapper", testWrapper);
return "test";
}
在我改变了我的.jsp之后:
<%@ taglib uri="http://www.springframework.org/tags/form" prefix="form"%>
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>
<html>
<head>
<title>Home</title>
</head>
<body>
<h1>
Hello!
</h1>
<form:form action="saveStudent" method="POST" modelAttribute = "testWrapper">
<c:forEach items="${testWrapper.testList}" var="test" varStatus="i">
Test Question: <form:input path = "testList[${i.index}].testQuestion" value = "${test.testQuestion}"/>
Option one: <form:input path = "testList[${i.index}].optionOne" value= "${test.optionOne}"/>
Option two: <form:input path = "testList[${i.index}].optionTwo" value= "${test.optionTwo}"/>
Option three: <form:input path = "testList[${i.index}].optionThree" value= "${test.optionThree}"/>
</c:forEach>
<input type="submit" value="Submit" />
</form:form>
</body>
</html>
现在它起作用了!希望它会帮助某人:)