Freemarker和Struts 2,有时候它会计算为序列+ extended_hash

首先让我说使用Struts2 + Freemarker是一个真正的爆炸。 但是有些东西让我发疯,因为我无法理解为什么会这样。 我在这里问,也许其他人有想法分享它。

我有一个行动,有财产。 说

private String myText; 

然后我有一个二传手和一个吸气剂:

 public void setMyText(String myText) { this.myText = myText; } public String getMyText() { if (myText == null) myText = "(empty)"; return this.myText; } 

结果(在struts.xml中)是一个freemarker结果。 所以在我的Freemarker模板中有一行如下:

 

The text is: ${myText}

现在考虑我正在调用没有任何文本参数的动作:说url是

 http:localhost:8080/myapp/myaction 

由于getter提供了一个默认值,当处理动作并将结果传递给我的模板时,该属性被设置为默认值; 所以我得到(浏览器端的HTML)

 

The text is: (empty)

如果我用参数集调用我的动作,而不是(我的意思是:

 http:localhost:8080/myapp/myaction?myText=hallo 

)事情出错了。 Freemarker触发以下exception:

 Exception occurred during processing request: For "${...}" content: Expected a string or something automatically convertible to string (number, date or boolean), but this has evaluated to a sequence+extended_hash (String[] wrapped into febArrayModel) 

似乎“myText”被发现两次……我做错了什么? 或者,至少,有没有人可以向我解释为什么会发生这种情况?

PS:真的发现了两次; 以下是解决问题的方法:

 ${myText[0]}${myText} 

然而,在我看来以这种方式包装每个变量是不可行的。

PPS:进一步暗示:在freemarker模板中,之前有一些行调用了另一个动作。 就像是:

  

如果我评论上面的一行,一切正常。

myText可以是freemarker上下文中的变量,但是如果要使用action属性

 

The text is: ${action.myText}

请注意,访问操作属性不需要action前缀。 解析freemarker变量时应用属性解析方法:

财产解决

您的动作属性会自动解析 – 就像在速度视图中一样。

例如${name}将导致stack.findValue("name") ,这通常会导致执行action.getName()

搜索过程用于解析变量,按顺序搜索以下范围,直到找到值:

  • 自由标记变量
  • 价值堆栈
  • 请求属性
  • 会话属性
  • servlet上下文属性

稍后您可以阅读可从上下文访问的对象。

上下文中的对象

FreeMarker视图中存在以下变量

  • req – 当前的HttpServletRequest
  • res – 当前的HttpServletResponse
  • stack – 当前的OgnlValueStack
  • ognl – OgnlTool实例此类包含用于对任意对象执行OGNL表达式的有用方法,以及使用该模式生成选择列表的方法。 (即获取list属性的名称,listKey和listValue)
  • struts – StrutsBeanWrapper的一个实例
  • action – 当前的Struts动作

  • exception – 如果视图是JSPexception或Servletexception视图,则为Exception实例的可选项

该错误可能是由值堆栈中的搜索引起的,并返回一些您不希望的内容,具体取决于执行时堆栈的结构。 在变量中添加前缀以指出属性的确切位置应该在值堆栈中搜索时修复代码中的冗余。