【问题标题】:Freemarker and Struts 2, sometimes it evaluates as a sequence+extended_hashFreemarker 和 Struts 2,有时它评估为一个序列+扩展哈希
【发布时间】:2015-12-28 08:33:36
【问题描述】:

首先让我说,使用 Struts2 + Freemarker 是一个真正的爆炸。 然而,有些事情让我发疯,因为我不明白为什么会这样。我在这里问,也许其他人有想法可以分享。

我有一个动作,有一个属性。 说

private String myText;

然后我有一个 setter 和一个 getter:

public void setMyText(String myText)
{
  this.myText = myText;
}

public String getMyText()
{
  if (myText == null)
    myText = "(empty)";

  return this.myText;
}

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

<p>The text is: ${myText}</p>

现在考虑我在没有任何文本参数的情况下调用操作:假设 url 是

http:localhost:8080/myapp/myaction

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

<p>The text is: (empty)</p>

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

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

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

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”被找到了两次... 我究竟做错了什么?或者,至少,有没有人可以向我解释为什么会这样?

P.S.:确实找到了两次;以下是解决问题的方法:

<#if myText?is_sequence>${myText[0]}<#else>${myText}</#if>

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

P.P.S.:进一步提示:在 freemarker 模板中,前几行调用了另一个操作。比如:

<@s.action var="innerAction" name="getTable" namespace="/foo" />

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

【问题讨论】:

    标签: java jsp struts2 freemarker


    【解决方案1】:

    myText 可以是来自 freemarker 上下文的变量,但如果你想使用 action 属性

    <p>The text is: ${action.myText}</p>
    

    注意,action 前缀不是访问操作属性所必需的。解析freemarker变量时应用property resolution方法:

    财产解析:

    您的操作属性会自动解析 - 就像在 速度视图。

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

    搜索过程用于解析变量,搜索 按顺序跟踪范围,直到找到一个值:

    • freemarker 变量
    • 值栈
    • 请求属性
    • 会话属性
    • servlet 上下文属性

    稍后您可以从上下文中读取哪些对象是可访问的。

    上下文中的对象:

    FreeMarker 视图中存在以下变量

    • req - 当前HttpServletRequest
    • res - 当前HttpServletResponse
    • stack - 当前OgnlValueStack
    • ognl - OgnlTool 实例 此类包含对任意对象执行 OGNL 表达式的有用方法,以及使用生成选择列表的方法 &lt;s:select&gt; 模式。 (即取 list 属性的名称,a listKeylistValue)
    • struts - StrutsBeanWrapper 的一个实例
    • action - 当前的 Struts 操作
    • exception - 如果视图是 JSP 异常或 Servlet 异常视图,则 Exception 实例是可选的

    该错误可能是由于从值堆栈中搜索并返回您未预料到的内容,具体取决于执行时堆栈的结构。

    在变量中添加前缀以指出属性的确切位置应该可以修复在值堆栈中搜索时代码中的冗余。

    【讨论】:

    • 谢谢罗曼。真的很到位。我会在接下来的几个小时内进行一些测试并让您知道(我的意思是:我想知道添加“action.”是否会解决问题,或者,如果问题仍然存在,我会在同一个模板中调用第二个操作)
    • 成功了! (抱歉耽搁了;我只能在几分钟前查看您的建议)。正如您所写,预先添加action. 修复了冗余。再次感谢您!
    猜你喜欢
    • 2019-08-20
    • 2022-11-10
    • 2022-01-24
    • 2016-10-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-08-16
    相关资源
    最近更新 更多