0

我已经使用 freemarker 作为视图模板编写了一个 Jsp 标签库。

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 应用程序的一部分。

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.

我无法在 freemarker 中使用嵌套的 jsp 标签。


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,我已经使用了上面的环境,但它也没有工作。我是否正确使用它?

4

2 回答 2

1

自定义 JSP 标记支持只是一个 FreeMarker 扩展,它通过专门用于此的 FreeMarker 数据模型实现。(它恰好是 freemarker.jar 的一部分,但从技术上讲,它也可能是第 3 方扩展。)此数据模型定义了JspTaglibs变量等。(此外,数据模型根不是 Map 或 JavaBean,而是来自彼此叠加的 Servlet 范围。)此数据模型由FreemarkerSerlvet.

因此,当您在 中创建自己的 FreeMarker 引擎和自己的数据模型时AlterTag.java,您就切断了所有这些。要么您尝试建立一个类似的数据模型(我不知道是否有人设法将其与FreemarkerServlet...分开),或者您必须在使用的模板中运行freemarker.core.Environment模板index.ftl。您可以使用 TLS 从 TLS 获取当前环境Environment.getCurrentEnvironment(),然后您可以使用一种Environment方法来包含您的模板,假设模板加载器可以访问它。所以你没有自己的数据模型......相当混乱。

问题是,FreeMarker 旨在使用自己的宏/指令/函数功能来制作库。一些开发人员认为自定义 JSP 标签可以像 FreeMarker 指令一样暴露出来......添加它本身是为了帮助您在“JSP 模型 2”框架内迁移(该模型本身就是一个非常尴尬的 hack,用于在 JSP 上强制 MVC)。如果您将 JSP 支持扩展到此之外……现在,您很有可能必须深入挖掘。

于 2013-06-17T13:16:10.730 回答
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);
于 2013-06-20T06:44:00.793 回答