3

我在我的 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>

现在它起作用了!希望它会帮助某人:)

4

0 回答 0