Java 未找到JSP、EL属性
为了学习这项技术,我正在用JSP创建一个简单的留言簿。目前我有两个类:guestbook/guestbook.class和guestbook/Entry.class(我还没有完成应用程序,所以我只有这些类),它们被添加到WEB-INF/libs/中,并且它们被正确地包含。在我的index.jsp文件中,我使用guestbook.guestbook类;它的方法返回向量。当我迭代条目并希望打印条目的作者时,我可以看到:Java 未找到JSP、EL属性,java,jsp,jstl,el,Java,Jsp,Jstl,El,为了学习这项技术,我正在用JSP创建一个简单的留言簿。目前我有两个类:guestbook/guestbook.class和guestbook/Entry.class(我还没有完成应用程序,所以我只有这些类),它们被添加到WEB-INF/libs/中,并且它们被正确地包含。在我的index.jsp文件中,我使用guestbook.guestbook类;它的方法返回向量。当我迭代条目并希望打印条目的作者时,我可以看到: javax.el.PropertyNotFoundException: Prop
javax.el.PropertyNotFoundException: Property 'author' not found on type guestbook.Entry
我必须补充一点,Entry类是public,author属性是这样声明的:
public String author;
所以它也是公开的。这是我迭代条目时的代码:
<c:forEach items="${entries}" varStatus="i">
<c:set var="entry" value="${entries[i.index]}" />
<li><c:out value="${entry.author}" /></li>
</c:forEach>
返回留言簿
这些类位于PackageGuestBook中(您可以猜到),entries向量被传递到pageContext
我不知道我这样做有什么不对。谁能帮我一下吗?(提前感谢!)JSP EL不会识别类中的公共字段,它只与getter方法一起工作(这是一个很好的实践,永远不要像这样将类的状态公开为公共字段) 所以使用
private String author;
public String getAuthor() {
return author;
}
而不是
public String author;
另外,您的JSTL过于复杂,可以简化为:
<c:forEach items="${entries}" var="entry">
<li><c:out value="${entry.author}" /></li>
</c:forEach>
甚至
<c:forEach items="${entries}" var="entry">
<li>${entry.author}</li>
</c:forEach>
${entry.author}
虽然后一种形式的XML不会转义作者姓名,但不建议这样做
最后,
Vector
类已过时,应改用ArrayList
。如果找不到getter,还可以修改EL解析器以访问公共字段。为此,您首先需要创建特殊的ELResolver:
public class PublicFieldSupportingELResolver extends ELResolver {
@Override
public Class<?> getCommonPropertyType(ELContext context, Object base) {
return null;
}
@Override
public Iterator<FeatureDescriptor> getFeatureDescriptors(ELContext context, Object base) {
return null;
}
@Override
public Class<?> getType(ELContext context, Object base, Object property) {
return null;
}
@Override
public Object getValue(ELContext context, Object base, Object property) {
try {
return context.getELResolver().getValue(
context, base, property);
} catch(RuntimeException ex) {
if(property instanceof String && base != null) {
try {
Field field = base.getClass().getDeclaredField((String) property);
Object value = field.get(base);
context.setPropertyResolved(true);
return value;
} catch (Exception e) {
throw new PropertyNotFoundException(e);
}
} else {
throw ex;
}
}
}
@Override
public boolean isReadOnly(ELContext context, Object base, Object property) {
return false;
}
@Override
public void setValue(ELContext context, Object base, Object property, Object value) {
}
}
最后,您需要在servlet启动时运行这个configurer类。通过在web.xml中添加此类作为servlet侦听器来实现此目的:
<listener>
<listener-class>your.package.PublicFieldSupportingELResolverConfigurer</listener-class>
</listener>
your.package.publicfieldsupportingelresolverconfiguer
现在,您可以在JSP中引用公共字段。我在构建路径中遇到了一个问题。
javax.servlet.jsp.jstl-1.2.1.jar已删除,但未从生成路径中删除。将其从生成路径属性“xxx”中删除后,问题消失 抛出StackOverflowException:)似乎
返回context.getELResolver().getValue(context,base,property)
调用相同的getValue
实现。
public class PublicFieldSupportingELResolverConfigurer implements ServletContextListener {
public void contextInitialized(ServletContextEvent event) {
JspFactory.getDefaultFactory()
.getJspApplicationContext(event.getServletContext())
.addELResolver(new PublicFieldSupportingELResolver());
}
public void contextDestroyed(ServletContextEvent event) {
}
}
<listener>
<listener-class>your.package.PublicFieldSupportingELResolverConfigurer</listener-class>
</listener>