【问题标题】:JSP,EL property not found未找到 JSP、EL 属性
【发布时间】:2012-01-07 07:07:45
【问题描述】:

我正在用 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 并且作者属性是这样声明的:

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

类在 guestbook 包中(你可以猜到),条目向量被传递给 pageContext。

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

【问题讨论】:

    标签: java jsp jstl el


    【解决方案1】:

    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

    【讨论】:

      【解决方案2】:

      如果没有找到 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 启动时运行这个配置器类。通过将此类添加为 web.xml 中的 servlet 侦听器来做到这一点:

        <listener>
          <listener-class>your.package.PublicFieldSupportingELResolverConfigurer</listener-class>
        </listener>
      

      现在您可以在 JSP 中引用公共字段。

      【讨论】:

      • 抛出 StackOverflowException :) 看来return context.getELResolver().getValue( context, base, property); 调用了相同的getValue 实现。
      【解决方案3】:

      我在构建路径中遇到了问题。 javax.servlet.jsp.jstl-1.2.1.jar 已删除,但未从构建路径中删除。从 Build Path Property 'xxx' not found 中删除后,问题消失了。

      【讨论】:

        猜你喜欢
        • 2015-02-15
        • 1970-01-01
        • 1970-01-01
        • 2013-03-21
        • 2011-04-01
        • 1970-01-01
        • 2015-08-22
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多