找不到JSP,EL属性

时间:2011-11-27 12:05:26

标签: java jsp jstl el

我正在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。

我不知道我的做法有什么问题。有人可以帮我吗? (先谢谢!)

3 个答案:

答案 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'中删除后,未发现问题消失了。