我正在尝试使用FTL编写代码来生成JVM线程转储,我在迭代TreeMap时遇到了问题。
这是我的动作类的片段:
----- ------启动
public AppsnapAction() {
traces = new TreeMap<Thread, StackTraceElement[]>(COMP);
traces.putAll(Thread.getAllStackTraces());
}
有问题的方法。
public Map<Thread, StackTraceElement[]> getAppTraces() {
// log.debug("HelloMe..in getAppTraces"+ traces);
return traces;
}
----结束--------
这是FTL的片段:
- - - - - - - - 启动
<h1>My Trace</h1>
<#list appTraces?keys as trace>
<h4><a name="${trace_index}">${trace}</a></h4>
<pre>
<#list appTraces[trace] as traceline>
at ${traceline}
</#list>
</pre>
</#list>
------ -------完
代码在此行中断: “&lt; #list appTraces [trace] as traceline&gt;”
有以下例外:
2013-09-15 22:58:35,701 [http-8080-1] ERROR freemarker.runtime -
get(Thread [ContainerBackgroundProcessor [StandardEngine [Catalina]],5,main])java.util.TreeMap实例失败 有问题的指示:
==&GT; list appTraces [trace] as traceline [在第42行,/resources / template /td.Page.ftl第5列]
程序员的Java回溯:
freemarker.template.TemplateModelException: get(Thread[ContainerBackgroundProcessor[StandardEngine[Catalina]],5,main]) failed on instance of java.util.TreeMap
at freemarker.ext.beans.BeanModel.get(BeanModel.java:223)
at freemarker.core.DynamicKeyName.dealWithStringKey(DynamicKeyName.java:136)
at freemarker.core.DynamicKeyName._getAsTemplateModel(DynamicKeyName.java:94)
at freemarker.core.Expression.getAsTemplateModel(Expression.java:89)
at freemarker.core.IteratorBlock.accept(IteratorBlock.java:94)
at freemarker.core.Environment.visit(Environment.java:213)
Caused by: java.lang.ClassCastException: java.lang.String cannot be cast to java.lang.Thread
at com.jivesoftware.helloworld.action.AppsnapAction$1.compare(AppsnapAction.java:1)
at java.util.TreeMap.getEntryUsingComparator(TreeMap.java:351)
at java.util.TreeMap.getEntry(TreeMap.java:322)
at java.util.TreeMap.get(TreeMap.java:255)
at freemarker.ext.beans.MapModel.invokeGenericGet(MapModel.java:127)
at freemarker.ext.beans.BeanModel.get(BeanModel.java:185)
... 202 more
有关如何遍历内循环的任何想法吗?
答案 0 :(得分:1)
你刚刚遇到了一个顶级的FreeMarker烦恼:[]
运算符不支持非字符串键,至少在FreeMarker 2.4之前。因此,最简单的解决方法可能是将对象包装器更改为BeansWrapper
上的simpleMapWrapper
。就像,new BeansWrapper(); bw.setSimpleMapWrapper(true); Configuration.setObjectWrapper(bw);
。这个包装器提供了这个hack:appTraces(trace)
。 myMap[stringKey]
和myMap.foo
仍然可以使用。缺点是,如果您已经拥有大量模板,其中一些模板可能会中断,因为数据模型现在看起来略微。或者有很多不同,取决于你现在使用的是什么对象包装器...无论如何,如果你来自默认的对象包装器,它通常不会破坏任何东西,除非你在数据模型中有XML。