如何从 freemarker 设置 struts 参数标签的值
How do I set the value of a struts param tag from freemarker
我在设置 @s.a
标签内的 @s.param
标签的值时遇到问题。
我使用的是表格:
<@s.a action="doit">
<@s.param name="thename" value=someThing/>
</@s.a>
它适用于某些参数,但只为其他参数生成空白值。
我也试过:
value=$someThing
value=${someThing}
value="someThing"
value="${someThing}"
各种形式似乎在某些情况下有效,但在其他情况下无效,我就是想不通。
我认为您可能遇到了 freemarker 和 struts 之间的 3 个不同陷阱之间的交互:
- 由 freemarker 与 struts
评估的表达式
- 本地 freemarker 变量与
Action
class 上的属性
String
与非 String
变量(例如 Long
)
首先,strutsparam
标签上的value
属性实际上是由struts求值的。这意味着如果你使用 value="someThing"
的形式,freemarker 只会将 "someThing"
传递给 struts。 Struts 然后将评估该字符串并尝试在您的操作中查找 getSomeThing()
。
如果您使用 value=someThing
形式,那么 freemarker 将评估 someThing
。如果您的操作有一个 getSomeThing()
方法 returns "anotherThing"
,那么它将发送 "anotherThing"
到 struts。 struts 将评估该字符串并尝试在您的操作中寻找 getAnotherThing()
,并且可能会失败。你可能会说,"Okay, I'll just never let freemarker evaluate the strings I give to value
, and always let struts do the evaluating." 然而:
其次,你在freemarker本地创建的任何变量对struts是不可见的。因此,如果 someThing
不是您操作中的 属性,而是在评估模板(比如循环变量)时由 freemarker 创建,那么 struts 将无法看到它如果您使用 value="someThing"
.
形式,可能会失败
Third,让事情更加混乱,数字类型(可能还有其他类型)在 freemarker 中评估并传递给 struts 时工作正常,而字符串则不t(正如我们在第一个陷阱中看到的)。因此,如果 someThing
是数字类型,则以下内容将起作用:
<@s.a action="doit">
<@s.param name="thename" value=someThing/>
</@s.a>
你会得到一个像 /doit.action?thename=1234
这样的 url,如果 someThing
是一个字符串,它就不会工作,因为 struts 会尝试计算任何 someThing
的计算结果为。
结论
那么您应该使用什么形式来确保所有类型(String
s 和数字)以及本地定义和基于操作的变量与 @s.param
一起工作?似乎您必须始终在 freemarker 中强制求值,然后将结果作为字符串文字传递给 struts。方法是:
<@s.a action="doit">
<@s.param name="thename" value="'${someThing}'"/>
</@s.a>
或:
<@s.a action="doit">
<@s.param name="thename">${someThing}</@s.param>
</@s.a>
请注意,这意味着变量将由 freemarker 格式化,您可能需要像 ?c
这样的数字类型,以确保您不会在其中使用逗号。
我在设置 @s.a
标签内的 @s.param
标签的值时遇到问题。
我使用的是表格:
<@s.a action="doit">
<@s.param name="thename" value=someThing/>
</@s.a>
它适用于某些参数,但只为其他参数生成空白值。
我也试过:
value=$someThing
value=${someThing}
value="someThing"
value="${someThing}"
各种形式似乎在某些情况下有效,但在其他情况下无效,我就是想不通。
我认为您可能遇到了 freemarker 和 struts 之间的 3 个不同陷阱之间的交互:
- 由 freemarker 与 struts 评估的表达式
- 本地 freemarker 变量与
Action
class 上的属性
String
与非String
变量(例如Long
)
首先,strutsparam
标签上的value
属性实际上是由struts求值的。这意味着如果你使用 value="someThing"
的形式,freemarker 只会将 "someThing"
传递给 struts。 Struts 然后将评估该字符串并尝试在您的操作中查找 getSomeThing()
。
如果您使用 value=someThing
形式,那么 freemarker 将评估 someThing
。如果您的操作有一个 getSomeThing()
方法 returns "anotherThing"
,那么它将发送 "anotherThing"
到 struts。 struts 将评估该字符串并尝试在您的操作中寻找 getAnotherThing()
,并且可能会失败。你可能会说,"Okay, I'll just never let freemarker evaluate the strings I give to value
, and always let struts do the evaluating." 然而:
其次,你在freemarker本地创建的任何变量对struts是不可见的。因此,如果 someThing
不是您操作中的 属性,而是在评估模板(比如循环变量)时由 freemarker 创建,那么 struts 将无法看到它如果您使用 value="someThing"
.
Third,让事情更加混乱,数字类型(可能还有其他类型)在 freemarker 中评估并传递给 struts 时工作正常,而字符串则不t(正如我们在第一个陷阱中看到的)。因此,如果 someThing
是数字类型,则以下内容将起作用:
<@s.a action="doit">
<@s.param name="thename" value=someThing/>
</@s.a>
你会得到一个像 /doit.action?thename=1234
这样的 url,如果 someThing
是一个字符串,它就不会工作,因为 struts 会尝试计算任何 someThing
的计算结果为。
结论
那么您应该使用什么形式来确保所有类型(String
s 和数字)以及本地定义和基于操作的变量与 @s.param
一起工作?似乎您必须始终在 freemarker 中强制求值,然后将结果作为字符串文字传递给 struts。方法是:
<@s.a action="doit">
<@s.param name="thename" value="'${someThing}'"/>
</@s.a>
或:
<@s.a action="doit">
<@s.param name="thename">${someThing}</@s.param>
</@s.a>
请注意,这意味着变量将由 freemarker 格式化,您可能需要像 ?c
这样的数字类型,以确保您不会在其中使用逗号。