如何使用Freemarker执行2个相关的Custom JSP标记,而不使SimpleSequence与java.util.List不兼容Exception

时间:2014-10-09 13:31:34

标签: freemarker taglib

我正在使用Freemarker来呈现我的网站页面。我在页面中有自定义的Jsp Taglib引用。

我遇到了" java.lang.ClassCastException:freemarker.template.SimpleSequence与java.util.List"不兼容同时执行2个相关标签。

<#assign mytag=JspTaglibs["/WEB-INF/tld/mytaglib.tld"]/>
<@mytag.query view="home" params="query params">
    <@mytag.process maxItems=10 />
</@mytag.query>

第一个标记mytag.query调用查询服务并将项目列表放入pageContext。

pageContext.setAttribute("items", resultSet.getItems());

第二个标签mytag.process从pageContext中读取项目列表并处理它们。

List allItems = (List)pageContext.getAttribute("items");

我在互联网上搜索了一下,看到Freemarker有Object Wrapper功能来包装放到pageContext的对象并将它们转换为SimpleHash,SimpleSequence和SimpleCollection类型,以便通过模板代码轻松访问它们。这在http://freemarker.org/docs/pgui_datamodel_objectWrapper.html

中有解释

我不允许将taglib修改为不投射&#34;项目&#34;到java.util.List。

有没有办法告诉Freemarker不要将java.util.List转换为SimpleSequence对象?

谢谢..

2 个答案:

答案 0 :(得分:0)

2.3.22之前:呃......真的有点破碎了。它应该给你原始对象。但是看一下源代码,只有当你使用纯BeansWrapper作为objectWrapper(或者它的一些自定义子类仍然返回包含在AdapterTemplateModel或{{{ 1}},以便FreeMarker可以提取原始对象。)

更新(自2.3.22起):

这在FreeMarker 2.3.22中得到修复,但是由于修复这不是100%向后兼容(只有99.99%或类似......),你必须激活修复:

WrapperTemplateModel

这也适用于<init-param> <param-name>incompatible_improvements</param-name> <param-value>2.3.22</param-value> </init-param> ,因此您不应该更改默认的对象包装器。激活了2.3.22改进的DefaultObjectWrapper几乎不赞成纯DefaultObjectWrapper

或者,您只能为对象包装器激活2.3.22修复程序(而不是上面的整个BeansWrapper):

Configuration

答案 1 :(得分:0)

感谢您的回答。

我认为FreemarkerServlet中可能存在一个错误,因为当我尝试在如下所示的重写init方法中设置BeansWrapper时,它没有任何效果,它使用DefaultWrapper。

public void init() throws ServletException { 
   super.init(); 
   Configuration cfg = getConfiguration(); 
   cfg.setTemplateLoader(new CustomPageTemplateLoader()); 
   cfg.setLocalizedLookup(false); 
   cfg.setObjectWrapper(ObjectWrapper.BEANS_WRAPPER); 
}

但是当我在重写的createObjectWrapper方法中返回ObjectWrapper时,它起作用了。

@Override
protected ObjectWrapper createObjectWrapper() {
    return ObjectWrapper.BEANS_WRAPPER;
}