我正在JSP中创建一个简单的留言簿,以便学习这项技术。目前我有两个类:guestbook / GuestBook.class和guestbook / Entry.class(我还没有完成应用程序,所以我只有这些类),这些类被添加到WEB-INF / libs /中并且它们被正确包含在内。在我的文件index.jsp中我使用的是guestbook.GuestBook类;它的方法返回Vector。当我迭代条目并且我想打印条目的作者时,我可以看到:
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>
和
entry.class.name
返回guestbook.Entry
这些类在包留言簿中(您可以猜到),条目向量传递给pageContext。
我不知道我的做法有什么问题。有人可以帮我吗? (先谢谢!)
答案 0 :(得分:9)
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
。
答案 1 :(得分:3)
如果找不到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) {
}
}
然后你需要一个类来帮助你配置它:
public class PublicFieldSupportingELResolverConfigurer implements ServletContextListener {
public void contextInitialized(ServletContextEvent event) {
JspFactory.getDefaultFactory()
.getJspApplicationContext(event.getServletContext())
.addELResolver(new PublicFieldSupportingELResolver());
}
public void contextDestroyed(ServletContextEvent event) {
}
}
最后,您需要在servlet启动时运行此configurer-class。通过在web.xml中添加此类作为servlet侦听器来执行此操作:
<listener>
<listener-class>your.package.PublicFieldSupportingELResolverConfigurer</listener-class>
</listener>
现在您可以参考JSP中的公共字段。
答案 2 :(得分:0)
我在Build Path中遇到了问题。 javax.servlet.jsp.jstl-1.2.1.jar已删除但未从Build Path中删除。从Build Path Property'xxx'中删除后,未发现问题消失了。