首先让我说,使用 Struts2 + Freemarker 是一个真正的爆炸.然而,有些事情让我发疯,因为我不明白为什么会这样.我在这里问,也许其他人有想法可以分享.
First let me say that using Struts2 + Freemarker is a real blast. Yet there's something is driving me crazy, because I cannot understand why it happens. I ask here as maybe someone else has an idea to share about it.
我有一个动作,有一个属性.说
I've got an action, with a property. Say
private String myText;
然后我有一个 setter 和一个 getter:
Then I've got a setter and a getter:
public void setMyText(String myText)
{
this.myText = myText;
}
public String getMyText()
{
if (myText == null)
myText = "(empty)";
return this.myText;
}
结果(在 struts.xml 中)是一个 freemarker 结果.所以在我的 Freemarker 模板中有如下一行:
The result (in struts.xml) is a freemarker result. So in my Freemarker template there's a line like the following:
<p>The text is: ${myText}</p>
现在考虑我在没有任何文本参数的情况下调用该操作:假设 url 是
Now consider I'm calling the action without any text parameter: say the url is
http:localhost:8080/myapp/myaction
由于getter提供了一个默认值,当action被处理并将结果传递给我的模板时,该属性设置为默认值;所以我得到(浏览器端的html)
As the getter provides a default value, when the action is processed and the result passed to my template, the property is set to the default; so I get (html on the browser side)
<p>The text is: (empty)</p>
如果我使用参数集调用我的操作,而不是(我的意思是:
If I call my action with the parameter set, instead (I mean with something like:
http:localhost:8080/myapp/myaction?myText=hallo
) 事情出错了.Freemarker 触发以下异常:
) things go wrong. Freemarker fires the following 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 f.e.b.ArrayModel)
似乎myText"被找到了两次...我究竟做错了什么?或者,至少,有没有人可以向我解释为什么会发生这种情况?
It seems that "myText" is found twice... What am I doing wrong? Or, at least, is there anyone that can explain to me why it happens?
P.S.:确实找到了两次;以下是解决问题的方法:
P.S.: it's really found twice; the following is a way to workaround the problem:
<#if myText?is_sequence>${myText[0]}<#else>${myText}</#if>
但在我看来,以这种方式包装每个变量似乎是不可行的.
Yet it seems to me not viable to wrap every variable in that way.
P.P.S.:进一步提示:在 freemarker 模板中,前几行调用了另一个操作.比如:
P.P.S.: a further hint: in the freemarker template there's a call to another action some lines before. Something like:
<@s.action var="innerAction" name="getTable" namespace="/foo" />
如果我评论上面的行,一切正常.
If I comment the line above, everything works fine.
myText
可以是 freemarker 上下文中的变量,但如果你想使用 action 属性
The myText
could be a variable from the freemarker context, but if you want to use action property
<p>The text is: ${action.myText}</p>
注意,action
前缀不是访问动作属性所必需的.解析 freemarker 变量时应用 属性解析 方法:
Note, that action
prefix is not required to access action properties. A property resolution method is applied when resolving freemarker variables:
财产解析:
您的操作属性会自动解析 - 就像在速度视图.
Your action properties are automatically resolved - just like in a velocity view.
例如 ${name}
将导致 stack.findValue("name")
,它通常会导致 action.getName()
被执行.
for example ${name}
will result in stack.findValue("name")
, which
generally results in action.getName()
being executed.
搜索过程用于解析变量,搜索按顺序跟踪范围,直到找到一个值:
A search process is used to resolve the variable, searching the following scopes in order, until a value is found :
稍后您可以从上下文中读取哪些对象是可访问的.
And later you can read what objects are accessible from the context.
上下文中的对象:
FreeMarker 视图中存在以下变量
The following variables exist in the FreeMarker views
req
- 当前的 HttpServletRequest
res
- 当前的 HttpServletResponse
stack
- 当前的 OgnlValueStack
ognl
- OgnlTool
实例此类包含对任意对象执行 OGNL 表达式的有用方法,以及使用生成选择列表的方法<s:select>
模式.(即取 list
属性的名称,alistKey
和 listValue
)struts
- StrutsBeanWrapper
action
- 当前的 Struts 动作exception
- 如果视图是 JSP 异常或 Servlet 异常视图,则可选 Exception
实例req
- the current HttpServletRequest
res
- the current HttpServletResponse
stack
- the current OgnlValueStack
ognl
- the OgnlTool
instance
This class contains useful methods to execute OGNL expressions against arbitary objects, and a method to generate a select list using
the <s:select>
pattern. (i.e. taking the name of the list
property, a
listKey
and listValue
)struts
- an instance of StrutsBeanWrapper
action
- the current Struts actionexception
- optional the Exception
instance, if the view is a JSP exception or Servlet exception view错误可能是由于从值堆栈中搜索并返回您未预料到的内容,具体取决于执行时堆栈的结构.
The error might be caused by searches from the value stack and returning something that you didn't expect depending on the structure of the stack at the moment of execution.
在变量中添加前缀以指出属性的确切位置应该可以修复在值堆栈中搜索时代码中的冗余.
Adding a prefix to the variable to point out the exact location of the property should fix the redundancy in the code when searching in the value stack.
这篇关于Freemarker 和 Struts 2,有时它评估为一个序列+扩展哈希的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持跟版网!