PropertyNotFoundException на странице JSP
У меня есть класс Java-бина, как показано ниже
public class Users extends dbConnect
{
private int UserId;
public int getUserId()
{
return UserId;
}
public void setUserId(int userId)
{
UserId = userId;
}
}
У меня есть метод doGet в My Servlet, который получает значение в классе javabean и показывает его на странице JSP. Метод ListUsers возвращает список из базы данных.
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException
{
List<Users> arrUserList = new ArrayList<Users>();
Users objUser = new Users();
arrUserList = objUser.listUsers();
for(Users Userobj : arrUserList)
{
System.out.println(Userobj.getUserId());
}
request.setAttribute("arrUserDetails", arrUserList);
RequestDispatcher rst = request.getRequestDispatcher("ListUsers.jsp");
rst.forward(request, response);
}
Когда я печатаю значение UserId в цикле for над его отображением UserId. Но оно не отображается на моей странице JSP.
<%@ page import="com.acme.users.Users"%>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%>
<c:forEach items="${arrUserDetails}" var="account">
<tr>
<td>
<c:out value="${account.UserId}" />
</td>
</tr>
</c:forEach>
Его отображение javax.el.PropertyNotFoundException. Я проверил стек на исключение и убедился, что имя компонента и метод получения одинаковы. Но он все еще показывает ошибку.
Сообщение в консоли, как показано ниже
Feb 16, 2013 2:44:19 PM org.apache.catalina.core.ApplicationDispatcher invoke
SEVERE: Servlet.service() for servlet jsp threw exception
javax.el.PropertyNotFoundException: Property 'UserId' not found on type com.acme.users.Users
at javax.el.BeanELResolver$BeanProperties.get(BeanELResolver.java:223)
at javax.el.BeanELResolver$BeanProperties.access$400(BeanELResolver.java:200)
at javax.el.BeanELResolver.property(BeanELResolver.java:311)
at javax.el.BeanELResolver.getValue(BeanELResolver.java:85)
at javax.el.CompositeELResolver.getValue(CompositeELResolver.java:67)
at org.apache.el.parser.AstValue.getValue(AstValue.java:169)
at org.apache.el.ValueExpressionImpl.getValue(ValueExpressionImpl.java:189)
at org.apache.jasper.runtime.PageContextImpl.proprietaryEvaluate(PageContextImpl.java:985)
at org.apache.jsp.ListUsers_jsp._jspx_meth_c_005fout_005f0(ListUsers_jsp.java:170)
at org.apache.jsp.ListUsers_jsp._jspx_meth_c_005fforEach_005f0(ListUsers_jsp.java:124)
at org.apache.jsp.ListUsers_jsp._jspService(ListUsers_jsp.java:84)
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:419)
at org.apache.jasper.servlet.JspServlet.serviceJspFile(JspServlet.java:391)
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:304)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:210)
at org.apache.catalina.core.ApplicationDispatcher.invoke(ApplicationDispatcher.java:684)
at org.apache.catalina.core.ApplicationDispatcher.processRequest(ApplicationDispatcher.java:471)
at org.apache.catalina.core.ApplicationDispatcher.doForward(ApplicationDispatcher.java:402)
at org.apache.catalina.core.ApplicationDispatcher.forward(ApplicationDispatcher.java:329)
at com.acme.users.ListUsers.doGet(ListUsers.java:36)
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:304)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:210)
at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:240)
at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:164)
at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:462)
at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:164)
at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:100)
at org.apache.catalina.valves.AccessLogValve.invoke(AccessLogValve.java:562)
at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:118)
at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:395)
at org.apache.coyote.http11.Http11Processor.process(Http11Processor.java:250)
at org.apache.coyote.http11.Http11Protocol$Http11ConnectionHandler.process(Http11Protocol.java:188)
at org.apache.coyote.http11.Http11Protocol$Http11ConnectionHandler.process(Http11Protocol.java:166)
at org.apache.tomcat.util.net.JIoEndpoint$SocketProcessor.run(JIoEndpoint.java:302)
at java.util.concurrent.ThreadPoolExecutor$Worker.runTask(Unknown Source)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(Unknown Source)
Почему это происходит?
2 ответа
Вы используете UserId
который является именем поля (и который нарушает соглашения об именах Java, кстати - как это делает dbConnect
как имя класса).
JSP хочет использовать свойства - геттеры и сеттеры. Метод, который вы пытаетесь заставить его вызвать getUserId
, но имя свойства (в терминах JavaBeans) просто userId
, Поэтому, если вы измените свой код на:
<c:out value="${account.userId}" />
он должен работать. Вы также должны изменить свой класс, чтобы использовать поле под названием просто userId
, или даже id
(учитывая, что это уже пользователь - эта часть неявная).
Было бы целесообразно просмотреть учебные руководства по JSP/JSTL/JavaBeans - вы заметите, что все они используют имена свойств, начинающиеся со строчной буквы, например ${foo.age}
позвонить getAge()
метод.
Из документации для конструктора PropertyDescriptor (который также присутствует в спецификации JavaBeans):
Создает PropertyDescriptor для свойства, которое следует стандартному соглашению Java, с помощью методов доступа getFoo и setFoo. Таким образом, если имя аргумента "fred", предполагается, что метод записи - "setFred", а метод чтения - "getFred" (или "isFred" для логического свойства). Обратите внимание, что имя свойства должно начинаться со строчной буквы, которая будет прописной в именах методов.
(Акцент мой.)
Не ясно, есть ли какое- либо имя метода, которое позволило бы ${account.UserId}
работать - если нет, то я бы сказал, что сообщение об ошибке может быть намного яснее. (Или это может быть немного более прощающим.)
Дополнительные баллы:
- Непонятно, почему ваш класс называется
Users
когда он представляет отдельного пользователя - Не ясно, что он должен расширять класс, который имеет какое-либо отношение к соединениям с базой данных - пользователь, в конце концов, не является соединением с базой данных. Я подозреваю, что вы должны стараться, чтобы каждый класс отвечал только за одну концепцию.
Ну ты пробовал account.userId
и это сработало, я думаю.
Это потому, что когда вы используете account.UserId
будет искать недвижимость userId
и не UserId
следовательно, это говорит об этой ошибке.
Из Javadocs BeanELResolver, который получает свойство объектов
public java.lang.Object getValue(ELContext context, java.lang.Object base, java.lang.Object property)
Предоставленное имя свойства сначала будет приведено к строке. Если свойство является читаемым свойством базового объекта в соответствии со спецификацией JavaBeans (это важно), то возвращает результат вызова getter. Если получатель выдает исключение, оно передается вызывающей стороне. Если свойство не найдено или не читается,
PropertyNotFoundException
брошен
Так как вы нарушаете спецификацию JavaBeans, он не может найти свойство на основе спецификации JavaBeans и, следовательно, выдает это исключение