Freemarker“.vars”名称不能包含短划线?

时间:2011-06-09 23:30:11

标签: freemarker

我们正在使用Freemarker版本2.3.16,我刚刚在我们的某个应用程序中找到了一个奇怪的错误。它归结为现在我们的一些产品代码字符串中有连字符。这些代码用于使用.vars从全局范围中提取本地化文本的哈希值。

减少这个问题让我想到了一个任何人都可以尝试的例子:

    模板中的
  • ${.vars["foo-bar"]}输出0

  • ${.vars["foo+bar"]}输出nullnull

  • ${.vars["foobar"]}正确触发InvalidReferenceException

这三个都应该触发异常。相反,似乎正在评估.vars参数字符串! : - (

http://freemarker.sourceforge.net/docs/app_faq.html#faq_strange_variable_name意味着这应该有用。

几周前我在Freemarker邮件列表中看到过类似的问题,建议在参数字符串前加上“@”。这可能适用于其他哈希值,但它不适用于.vars。我刚刚做了一个工作示例(.vars["resources_title"])并更改它使它抛出一个InvalidReferenceException(.vars["@resources_title"])。我也尝试了带连字符的引用,它也引发了异常。

升级到2.3.18似乎没有什么区别。

4 个答案:

答案 0 :(得分:1)

适合我。就像已经mentioned on the freemarker-user mailing list:也许你使用了一个奇怪的数据模型,甚至是一个花哨的ObjectWrapper。但是像这样的讨论可能更适合freemarker-user邮件列表......

答案 1 :(得分:1)

抱歉延误。在关于放置断点的地方的一些好的邮件列表帮助后,我在6月10日写回了列表:


短篇小说:这不是Freemarker问题。相反,Struts团队选择硬连线Freemarker将.vars名称视为OGNL表达式,并且似乎没有办法告诉OGNL 解析它们。因此,在Struts下,“ - ”和“+”(可能还有其他字符)不能出现在.vars名称中。

长篇故事......

  • freemarker.core.BuiltinVariable(第192行)是Freemarker开始处理.vars表达式的地方

  • freemarker.core.Environment(1088行)将控制权移交给“rootDataModel”,Struts团队将其作为org.apache.struts2.views.freemarker.ScopesHashModel的实例

  • 该类的第70行(使用Struts的2.1.8.1版本)调用“stack.findValue”; “stack”已被连线为com.opensymphony.xwork2.ognl.OgnlValueStack

  • 的实例
  • 在第236行,该类依次要求OgnlUtil的实例找到该对象,并且该名称被假定为OGNL表达式并被解析,将“foo-bar”转换为(foo - bar)

在此过程中,似乎没有选择不将.vars名称视为表达式(FreemarkerResult中的注释提示可能性,但代码不遵循通过)。从理论上讲,我可以让FreemarkerManager的实现创建ScopesHashModel的变体,但是要用它来更改所有相关的类需要做很多工作。

(似乎没有办法逃避OGNL表达式中的“ - ”字符。似乎有5到6年前的讨论要做到这一点,但.... .vars( "foo\\-bar" )未能找到“ - “在”之后,所以大概是“ - ”是不可避免的?)

: - (

我不清楚将.vars名称作为表达式处理的用例是什么......但我认为Struts现在不会改变。我没有覆盖半打Struts类,而是更改了将ResourceBundles加载到值堆栈的代码:它现在更改了名称以替换“ - ”和“_”,同样我的.vars名称也被更改了同样的方式在模板和... tada。有用。呜。

答案 2 :(得分:1)

如果添加了转义foo \ -bar,它就可以工作。 “仅单个反斜杠”

答案 3 :(得分:0)

由于freemarker版本2.3.22可以在变量名称(details here)中使用点(。),减号( - )或冒号(:)。

在我的情况下,如果我尝试使用freemarker 2.3.21变量,它会失败,如:

api["x-link"]

如果我将freemarker更改为版本2.3.22,则可以正常工作。