Запретить FreeMarker обертывать класс, реализующий коллекцию, в SimpleSequence

У меня есть класс Page, реализующий java.util.Collection, а также другие методы, такие как hasPreviousPage, getTotalPages и т. д. Freemarker заключает этот класс в класс SimpleSequence. Это скроет методы, не являющиеся частью java.util.Collection.

т.е. когда я пишу ${page.getTotalPages()} я получил эту ошибку:

Ожидаемый хэш. myPage оценивается как freemarker.template.SimpleSequence [...]

Как я могу указать Freemarker предоставить как методы для перебора Collection, чтобы такой код <#list page as item> продолжал работать, так и пользовательские?

Спасибо за любое предложение/ссылку.


person protoboolean    schedule 20.08.2010    source источник
comment
Я нашел ЧАСТИЧНОЕ РЕШЕНИЕ погуглив: если объект данных обернут в BeanModel, все методы исходного объекта доступны, хотя объект не будет распознан как итерируемый. Итак, import freemarker.ext.beans.BeanModel; импортировать freemarker.ext.beans.BeansWrapper; Страница страницы = dao.getObjects(); Карта карты = новая карта(); map.put(myPage, new BeanModel(page, BeansWrapper.getDefaultInstance()); затем карта передается в шаблон.   -  person protoboolean    schedule 23.08.2010


Ответы (2)


Если вы не можете или не должны изменять этот класс... вы можете расширить DefaultObjectWrapper или BeansWrapper, чтобы он специально обрабатывал некоторые классы. Примером этого является сам DefaultObjectWrapper (он специально оборачивает объекты DOM и объекты Jython). Вы можете деформировать объект с помощью BeanModel, но добавить дополнительную подпеременную под названием «items», которая возвращает тот же объект, но завернутый в SimpleSeqence. Затем вы просто настраиваете FreeMarker для глобального использования вашего пользовательского ObjectWrapper (Configuration.setObjectWrapper), и вам не нужно нигде трогать код приложения.

person ddekany    schedule 08.06.2011

Две мысли, хотя ни одна из них не отвечает на ваш вопрос (что кажется вполне разумным).

1) Думаю, вместо ${page.totalPages} можно было бы использовать ${page.getTotalPages()}.

2) Подумайте, имеет ли смысл для Page содержать объект коллекции (так что вы бы использовали <#list page.items as item>), а не реализовывать коллекцию, что немного необычно, если вы на самом деле не создаете новую коллекцию данных структура.

person Toper    schedule 23.08.2010
comment
1) Да, я должен был вызвать getTotalPages(), исправив вопрос сейчас. 2) Я согласен, но этот класс уже используется где-то еще, поэтому я подумывал попробовать представить его как есть в модели, прежде чем начинать рефакторинг. Кстати, я только что обнаружил, как FreeMarker может отображать любой метод обернутого объекта. Это использование оболочки BeansWrapper вместо DefaultObjectWrapper. - person protoboolean; 23.08.2010