JSP, EL свойство не найдено - PullRequest
8 голосов
/ 27 ноября 2011

Я создаю простую гостевую книгу в 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 ]

9 голосов
/ 27 ноября 2011

JSP EL не распознает открытые поля в ваших классах, он работает только с методами-получателями (что в любом случае является хорошей практикой - никогда не отображайте состояние ваших классов как открытые поля).

Поэтому используйте

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 голосов
/ 29 марта 2013

Вы также можете изменить 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) {
    }
}

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

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

Теперь вы можете ссылаться на открытые поля в ваших JSP.

0 голосов
/ 02 марта 2015

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

...