Struts2 + Freemarker + DisplayTag:如何使它工作

时间:2010-07-14 11:07:06

标签: struts2 freemarker displaytag

我目前正在将我们的应用程序从Webwork升级到Struts2。今天我遇到了一个奇怪的错误:升级后displayTag停止工作。

这是从我的FTL文件中删除的:

<#assign display=JspTaglibs["http://displaytag.sf.net"]>

<@s.set name="entries" value="historyEntries" scope="page"/>

<@display.table class="data" name="pageScope.entries" sort="list" 
      pagesize=30 id="entry" defaultsort=5 defaultorder="descending">
  <@display.column property="folderName" title="Folder" sortable=true/>
</@display.table>

我得到的错误是:

freemarker.template.TemplateModelException:   
javax.servlet.jsp.JspException: Exception:   
[.LookupUtil] Error looking up property "folderName" 
in object type "freemarker.template.SimpleSequence". 
Cause: Unknown property 'folderName'

标准struts标记工作正常,我的配置中添加了JspSupportServlet。任何想法,为什么这不起作用?

2 个答案:

答案 0 :(得分:0)

我找到了一种方法来解决这个问题(不确定它是否是唯一的方式,或者它是否是最好的,但对我来说很有用)。

问题的根源是freemarker.template.SimpleSequence没有开箱即用的实现任何标准集合API,它不是集合,可枚举等。

为了解决这个问题,我创建了自定义FreemarkerManager并提供了自定义BeansWrapper

@Override
protected BeansWrapper getObjectWrapper() {
    BeansWrapper wrapper = super.getObjectWrapper();
    class CustomBeansWrapper extends BeansWrapper {
        private BeansWrapper internalWrapper;

        public Xp2BeansWrapper(BeansWrapper wrapper) {
            this.internalWrapper = wrapper;
        }

        //delegate methods


        public TemplateModel wrap(Object object) throws TemplateModelException {
            TemplateModel model = internalWrapper.wrap(object);
            if (model instanceof SimpleSequence) {
                class SimpleSequenceWithIterator extends SimpleSequence {
                    private SimpleSequence internalSequence;
                    public SimpleSequenceWithIterator(SimpleSequence sequence) {
                        this.internalSequence = sequence;
                    }

                    //delegate methods

                    //IteratorUtils from Apache Commons is used internally 
                    //by DisplayTag library, it can use public iterator() method
                    public Iterator iterator() throws TemplateModelException {
                        return toList().iterator();
                    }

                }
                return new SimpleSequenceWithIterator((SimpleSequence) model);
            }
            return model;
        }


    }
    return new CustomBeansWrapper(wrapper);

}

现在我只需更改struts.properties中的一个设置:

struts.freemarker.manager.classname=xyz.CustomFreemarkerManager

答案 1 :(得分:0)

您还可以证明您的部署是否将所有依赖项复制到WEB-INF / lib。 TaglibFactory在那里搜索/ META-INF /里面的每个TLD。

查看https://stackoverflow.com/a/37092269/1113510