问题描述
首先让我说使用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.
我有一个行动,有财产。
Say
I've got an action, with a property.Say
private String myText;
然后我有一个二传手和一个吸气剂:
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>
现在考虑我正在调用没有任何文本参数的操作:说网址是
Now consider I'm calling the action without any text parameter: say the url is
http:localhost:8080/myapp/myaction
由于getter提供了一个默认值,当处理动作并将结果传递给我的模板时,该属性被设置为默认值;所以我得到(浏览器端的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()
。
搜索过程用于解析变量,按顺序搜索以下范围内的
,直到找到值:
A search process is used to resolve the variable, searching the following scopes in order, until a value is found :
- freemarker变量
- 价值堆栈
- 请求属性
- 会话属性
- servlet上下文属性
- freemarker variables
- value stack
- request attributes
- session attributes
- servlet context attributes
后来你可以阅读什么对象s可以从上下文访问。
And later you can read what objects are accessible from the context.
上下文中的对象
- req - 当前的HttpServletRequest
- res - 当前的HttpServletResponse
- stack - 当前的OgnlValueStack
- ognl - OgnlTool实例
此类包含对任意对象执行OGNL表达式的有用方法,以及使用
模式生成选择列表的方法。 (即获取list属性的名称,
listKey和listValue) - struts - StrutsBeanWrapper的一个实例
-
action - 当前的Struts操作
- 异常 - 如果视图是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 pattern. (i.e. taking the name of the list property, a listKey and listValue)
- struts - an instance of StrutsBeanWrapper
action - the current Struts action
- exception - 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,有时候它会计算为序列+ extended_hash的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!