未找到JSP,EL属性
我正在JSP中创建一个简单的留言簿以学习此技术。目前我有两个类:留言簿/ GuestBook.class和留言簿/ Entry.class(我还没有完成应用程序,所以我只有这些类),它们被添加到WEB-INF/libs /中,并且它们被正确包含。在我的文件index.jsp中,我使用了guestbook.GuestBook类;其方法返回Vector。当我遍历条目,我想打印的条目的作者,我可以看到:未找到JSP,EL属性
javax.el.PropertyNotFoundException: Property 'author' not found on type guestbook.Entry
我必须补充的是Entry类是公共和作者属性以这样的方式宣布:
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>
和
entry.class.name
回报guestbook.Entry
类在包留言(你可以猜),参赛矢量传递给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>
虽然后一种形式不会XML转义作者姓名,所以不建议。
最后,Vector
类已过时,您应该使用ArrayList
来代替。
如果未找到吸气剂,您还可以修改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) {
}
}
然后,你需要一个类来帮助您进行配置:
public class PublicFieldSupportingELResolverConfigurer implements ServletContextListener {
public void contextInitialized(ServletContextEvent event) {
JspFactory.getDefaultFactory()
.getJspApplicationContext(event.getServletContext())
.addELResolver(new PublicFieldSupportingELResolver());
}
public void contextDestroyed(ServletContextEvent event) {
}
}
最后,你需要在运行此配置者级servlet启动。通过在web.xml中将此类添加为servlet侦听器来执行此操作:
<listener>
<listener-class>your.package.PublicFieldSupportingELResolverConfigurer</listener-class>
</listener>
现在您可以参考JSP中的公共字段。
我在构建路径中遇到问题。 javax.servlet.jsp.jstl-1.2.1.jar已被删除,但未从Build Path中删除。从构建路径属性'xxx'中删除后未发现问题消失。
引发StackOverflowException :)看起来,'返回context.getELResolver()。getValue( 上下文,基地,财产);'调用相同的'getValue'实现。 –