2011-11-27 4 views
8

Я создаю простую гостевую книгу в JSP, чтобы изучить эту технологию. В настоящее время у меня есть два класса: гостевая книга/GuestBook.class и гостевая книга/Entry.class (я еще не закончил приложение, поэтому у меня есть только эти классы), которые добавляются в WEB-INF/libs /, и они включены правильно , В моем файле index.jsp я использую класс guestbook.GuestBook; его метод возвращает вектор. Когда я перебирать записи, и я хотел бы напечатать автор записи, я вижу:JSP, EL property не найден

javax.el.PropertyNotFoundException: Property 'author' not found on type guestbook.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

Классов в пакете гостевой книге (как вы можете догадаться), записи в векторе перешел на страницуКонтекст.

Я не знаю, что не так с моим способом сделать это. Может ли кто-нибудь помочь мне, пожалуйста, с этим? (Заранее благодарю!)

ответ

8

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.

3

Вы также можете изменить EL-resolver для доступа к общедоступным полям, если геттер не найден. Для этого сначала необходимо создать специальную 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) { 
    } 
} 

Наконец вам нужно запустить этот configurer-класс, когда сервлет запускается. Сделайте это, добавив этот класс в качестве слушателя сервлет в вашем web.xml:

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

Теперь вы можете обратиться к общественным полям в JSPs.

+0

Throws a StackOverflowException :) Кажется, что 'return context.getELResolver(). GetValue ( context, base, property);' вызывает ту же самую реализацию getValue. –

0

У меня была проблема в пути сборки. javax.servlet.jsp.jstl-1.2.1.jar был удален, но не удален из пути сборки. После удаления из свойства Build Path свойства «xxx» не обнаружена проблема исчезла.

Смежные вопросы