javax.el.PropertyNotFoundException: использование JSTL в JSP

У меня есть JSP, в котором я пытаюсь использовать теги JSTL для отображения данных из экземпляра класса в памяти. Данные состоят из серии строк, где каждая строка является адресом RSS-канала.

В JSP у меня есть следующий код:

<table border = "1">
    <tr>
        <c:forEach var = "rssFeedURL" items = "${rssfom.rssFeedURLs}">
            <td align = "left">${rssFeedURL}</td>
        </c:forEach>
    </tr>
</table>

По сути, rssfom является экземпляром следующего класса:

public class RSSFeedOccurrenceMiner extends RSSFeedMiner {

   private HashMap<String, Counter> keywordFrequencies;

   public RSS_Feed_OccurrenceMiner() {
      super();
      this.keywordFrequencies = new HashMap();
   }
   ...
}

Он наследуется от класса RSSFeedMiner, который содержит следующие переменные и методы:

private ArrayList<String> rssFeedURLs;

public ArrayList<String> getRSSFeedURLs() {
    return rssFeedURLs;
}

public void setRSSFeedURLs(ArrayList<String> rssFeedURLs) {
    this.rssFeedURLs = rssFeedURLs;
}

Итак, в JSP я думал, что смогу использовать приведенный выше код, но когда страница запускается, я просто получаю пустую таблицу. И в журналах сервера я обычно нахожу сообщение:

javax.el.PropertyNotFoundException: свойство «rssFeedURLs» не найдено для типа RSSFeedOccurrenceMiner

Что правильно, учитывая мое использование наследования. Так может ли кто-нибудь сказать мне, допускает ли JSTL наследование или в моем коде чего-то не хватает?

Я действительно не хочу использовать скриптлет в JSP.


person Mr Morgan    schedule 07.11.2010    source источник


Ответы (3)


Ваш метод получения не соответствует соглашению об именах JavaBeans. Оно должно называться getRssFeedURLs (даже если у вас есть аббревиатура, она должна быть написана с большой буквы, как обычное слово). В EL, когда вы указываете имя свойства, фактически вызывается геттер для этого свойства. Чтобы выяснить имя геттера, он делает первую букву в имени свойства, которое вы указали, заглавной (так что rssFeedURLs преобразуется в RssFeedURLs) и добавляет get к его началу. Таким образом, вы получите getRssFeedURLs. Однако вы назвали свой метод getRSSFeedURLs. Java не может найти метод, поэтому вы получаете исключение PropertyNotFoundException.

Если вы неправильно назовете свои геттеры, вы не сможете получить к ним доступ с помощью EL.

person Vivin Paliath    schedule 07.11.2010
comment
Правда, я немного переименовал метод, но не вижу в этом вины в данном случае. - person Mr Morgan; 07.11.2010
comment
@ Мистер Морган, вы переименовали метод в getRssFeedURLs и попробовали? - person Vivin Paliath; 07.11.2010
comment
@Vivin Palaith: я у тебя в долгу. Переименование метода в соглашение Java сработало отлично. У меня были проблемы с JSTL раньше, но никогда не было так. Большое спасибо. - person Mr Morgan; 07.11.2010
comment
Большое спасибо еще раз. Это заняло бы у меня несколько часов, чтобы решить. - person Mr Morgan; 07.11.2010
comment
О, классно. Очередное голосование за драйв. - person Vivin Paliath; 08.11.2010
comment
Соглашение об именах JavaBeans поддерживает имена с заглавной буквы, такие как getRSSFeedURLs(). Его метод назван правильно, но он использовал неправильный EL. Должно было быть RSSFeedURLs вместо rssFeedURLs. - person erickson; 30.06.2016

Если имя свойства начинается с двух или более заглавных букв, то к нему следует обращаться так же и в EL. Итак, для доступа к геттеру getRSSFeedURLs() нужен ${rssfom.RSSFeedURLs}.

Это также указано в спецификации JavaBeans.

8.8 Использование заглавных букв в предполагаемых именах.

Когда мы используем шаблоны проектирования для вывода имени свойства или события, нам нужно решить, каким правилам следует следовать для написания выведенного имени с заглавной буквы. Если мы извлечем имя из середины обычного имени Java в стиле MixCase, то имя по умолчанию будет начинаться с заглавной буквы. Программисты Java привыкли к тому, что обычные идентификаторы начинаются со строчных букв. Энергичный вклад рецензентов убедил нас в том, что мы должны следовать тому же общепринятому правилу для имен свойств и событий.

Таким образом, когда мы извлекаем имя свойства или события из середины существующего имени Java, мы обычно преобразуем первый символ в нижний регистр. Однако для поддержки случайного использования всех имен в верхнем регистре мы проверяем, являются ли первые два символа имени заглавными, и если да, то оставляем их в покое. Так, например,

«FooBah» становится «fooBah»
«Z» становится «z»
«URL» становится «URL»

Мы предоставляем метод Introspector.decapitalize, реализующий это правило преобразования.

JSP EL (язык выражений, эти ${} вещи) придерживается спецификации JavaBeans. Таким образом, это не имеет прямого отношения к JSTL (те теги <c:xxx>).

person BalusC    schedule 07.11.2010
comment
Свойство в java xZone имеет геттер getXZone()... но доступ в выражении jsp el - foo.XZone, поэтому лучше избегать свойств только с одной буквой, обезглавленной в первой позиции. - person Jesus M C; 30.09.2016
comment
@Jesus: EL не смотрит на имя поля, а выводит имя из геттера. Поле полностью игнорируется EL. См. также stackoverflow.com/q/8577545 - person BalusC; 30.09.2016
comment
Да, я пытался отметить, что el выводит имя из геттера, поэтому выводит XZone как имя свойства, тогда у вас есть свойство с именем xZone в java, хотя XZone в jsp, когда на самом деле это одно и то же свойство, поэтому это может вызвать возможные ошибки - person Jesus M C; 30.09.2016

Мой ВО имеет следующий код

 public class DocumentPolicyVO {
          @JsonProperty("Id")
            private String Id;
            @JsonProperty("Id")
            public String getId() {
                return Id;
            }
     @JsonProperty("Id")
            public void setId(String Id) {
                this.Id = Id;
            }
    }

Когда я пытаюсь получить к нему доступ на странице jsp, как показано ниже, он выдает следующую ошибку javax.el.PropertyNotFoundException: свойство «Id» не найдено для типа DocumentPolicyVO

<select name="settingsListExcludingEnvironmentList" class="selectComboboxCheck">
                                                  <c:forEach var="settingsType" items="${settingsListExcludingEnvironmentList}">
                                                      <option value="${settingsType.Id}">${settingsType.Name}</option>
                                                  </c:forEach>
                                        </select>

Пожалуйста, кто-нибудь может объяснить причину.

person Ankur Mehrotra    schedule 09.06.2016
comment
Если у вас есть другой вопрос, задайте его, нажав кнопку Задать вопрос. - person Bhargav Rao; 09.06.2016