2013-06-16 3 views
0

Я написал библиотеку тегов Jsp, используя freemarker в качестве шаблона представления.Не удалось получить доступ к вложенным тегам Jsp в Freemarker

custom.tld размещается в META-INF/tags /.

Мой тег Lib в комплекте как Jar. customTag.jar. Он имеет следующие шаблоны

AlertTag.ftl 
ButtonTag.ftl 

AlertTag.ftl зависит от ButtonTag.ftl.

AlertTag.ftl: -

<#assign custom = JspTaglibs["http://www.abc.com/taglibs/custom"]> 

<h5>${this.title}</h5> 
<div class="alert ${this.typeClass} ${this.classes!}"> 
    <@custom.button btnType="close" <span class="alt">close</span></@custom.button> 
</div> 

Это customTag.jar является частью другого веб-приложения.

web.xml: -

<taglib> 
    <taglib-uri>http://www.abc.com/taglibs/custom</taglib-uri> 
    <taglib-location>/WEB-INF/custom.tld</taglib-location> 
</taglib> 

Теперь, когда index.ftl в веб-приложение пытается использовать тег <@custom.Alert id="abc"> он бросает следующее исключение

Expression JspTaglibs is undefined on line 1, column 17 in freemarker/AlertTag.ftl. 
The problematic instruction: 
---------- 
==> assignment: custom=JspTaglibs["http://www.abc.com/taglibs/custom"] [on line 1, column 1 in freemarker/AlertTag.ftl] 
---------- 

Java backtrace for programmers: 
---------- 
freemarker.core.InvalidReferenceException: Expression JspTaglibs is undefined on line 1, column 17 in freemarker/AlertTag.ftl. 

Я не могу использовать вложенный JSP тег FreeMarker.


AlertTag.java

Configuration cfg = new Configuration(); 
    cfg.setClassForTemplateLoading(this.getClass(), "/"); 

    Template ftlTemplate = cfg.getTemplate(view); 
    JspWriter writer = pageContext.getOut(); 
    data.put("id", id) 

    Map<String, Object> rootMap = new HashMap<String,Object>(); 
    rootMap.put("this", data); 
    Environment environment = ftlTemplate.createProcessingEnvironment(rootMap, writer); 
    environment.process(); 
    //ftlTemplate.process(rootMap, writer); 

@Daniel, я использовал окружающую среду, как описано выше, но он не работал ни. Правильно ли я использую его?

+0

Как вы вызываете 'AlertTag.ftl' себя? – ddekany

+0

Я вызываю его из index.ftl в веб-приложении. '<@ custom.Alert id =" abc ">' – Mady

+0

Я предполагаю, что @ custom.Alert' является собственным тегом JSP, в отличие от простой макро/директивы FreeMarker. Итак, я имею в виду, как технически будет вызываться «AlertTag.ftl». Поскольку я подозреваю, что тег JSP создаст свой собственный экземпляр ядра FreeMarker, который не имеет ничего общего с тем, что используется для 'index.ftl', и, следовательно, там, где поддерживается поддержка тегов tag. – ddekany

ответ

0

Я, наконец, смог решить эту проблему. Спасибо @ddekanny и моим коллегам за то, что вы показали дорогу.

Добавление моего шаблона в текущую среду, созданная FreemarkerServlet, решила мою проблему.

Environment currentEnvironment = Environment.getCurrentEnvironment(); 
Configuration cfg = currentEnvironment.getTemplate().getConfiguration(); 

cfg.setClassForTemplateLoading(this.getClass(), "/"); 

Template ftlTemplate = cfg.getTemplate(view); 
JspWriter writer = pageContext.getOut(); 

currentEnvironment.setVariable("this", new SimpleHash(data)); 
currentEnvironment.setOut(writer); 
currentEnvironment.include(ftlTemplate); 
1

Пользовательская поддержка тегов JSP - это просто расширение FreeMarker, которое реализовано через специализированную для этого модель данных FreeMarker. (Это, случается, часть freemarker.jar, но технически это может быть и стороннее расширение.) Эта модель данных определяет JspTaglibs переменную среди других. (Кроме того, вместо карты или JavaBean корень модели данных находится из областей сервлетов, расположенных друг над другом.) Эта модель данных настроена на FreemarkerSerlvet.

Итак, когда вы создаете свой собственный движок FreeMarker и собственную модель данных в AlterTag.java, вы отрезаете все это. Либо вы пытаетесь настроить аналогичную модель данных (я не знаю, удавалось ли кому-либо отделить это от FreemarkerServlet ...), либо вам нужно было запустить шаблон в freemarker.core.Environment, который использует index.ftl. Вы можете получить текущую среду от TLS с помощью Environment.getCurrentEnvironment(), тогда вы можете использовать метод Environment для включения вашего шаблона, предполагая, что загрузчик шаблонов может получить к нему доступ. И поэтому у вас нет собственной модели данных ... довольно беспорядочно.

Thing is, FreeMarker был разработан, чтобы использовать свои собственные функции макро/директивы/функции для создания библиотек. У некоторых разработчиков была такая идея, что пользовательские теги JSP могут быть выставлены так, как если бы они были директивами FreeMarker ... это полезный взлом, если вы пытаетесь перейти на представления FTL, но у вас много тегов JSP, и поэтому FreemarkerSerlvet, который сам был добавлен, чтобы помочь вам выполнить миграцию в рамках «JSP Model 2» (модель, которая сама по себе является довольно неудобным взломом, чтобы заставить MVC на JSP). Если вы растянете поддержку JSP за этим ... прямо сейчас, шансы высоки, что вам придется копать глубоко.

+0

Я редактировал вопрос и использовал переменную среды, как вы сказали. См. Приведенное выше изменение, но идентификатор не работал. Не слишком уверен, если я правильно его использую. – Mady

+0

Tagging .. @ ddekanny – Mady

+1

Вы должны были использовать * такую ​​же * 'Среда', что' index.ftl' запускается внутри, а не новый (используйте 'Environment.getCurrentEnvironment()'). В основном, чтобы получить ту же модель данных. И вы действительно не должны воссоздавать «Конфигурация» для каждой обработки шаблона ... каждый раз вы теряете кеш шаблона. Опять же, я предупреждаю вас, что решение этой проблемы - это, вероятно, глубокая вода, и вам нужно будет понять FM и, возможно, даже исправить сервлет вида. Это не проблема. – ddekany

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