【问题标题】:Struts2 Tiles setting a var to a tiles attribute as stringStruts2 Tiles 将 var 设置为 tiles 属性作为字符串
【发布时间】:2014-08-28 14:34:31
【问题描述】:

我使用 struts 2.3.16 和 tile 2.0.6。

具有空属性的图块定义(以及其他):

<put-attribute name="pageSidePanel" value="" />

其他一些定义对其进行了扩展,他们可以选择填入值:

<put-attribute name="pageSidePanel" value="/panels/greenPanel.jsp" />

或者也留空。

我尝试通过使用struts“set”标签和一些基本的if/else逻辑来测试这个属性是否为空。例如:

<s:set var="sidePanelName"><tiles:getAsString name='pageSidePanel'/></s:set>
<s:if test='%{#sidePanelName.isEmpty()}'>TRUE</s:if><s:else>FALSE</s:else>

结果出乎我的意料。我进行了 11 次逻辑测试,有两种变体:11 次测试使用主题标签,另外 11 次没有:

#sidePanelName vs sidePanelName

我用 2 个不同的 JSP 页面进行了测试,一个实际上在图块中输入了值,另一个没有。所以总共有 44 个逻辑测试:

  1. 在tiles属性为空的页面上使用#进行11次测试
  2. 在tiles属性为空的页面上不使用#的11个测试
  3. 11 次使用# 测试在tiles 属性填入值的页面上
  4. 11 测试不使用 # 在其中以值填充了 tiles 属性的页面上

只有情况 3 是正确的。所有其他情况都给出了错误的结果。例如,在情况 1 中,如果我测试 #var == null 我得到错误,但如果我测试 var == null(没有主题标签)i 得到正确。所以我需要澄清两件事:

  1. 使用#或者不使用有什么影响?
  2. tiles属性有没有值有什么影响,struts var是把它当作null还是空字符串,还是取决于我是否使用了#?

作为参考,这里是所有测试:

<s:set var="sidePanelName"><tiles:getAsString name='pageSidePanel'/></s:set>

<s:if test='#sidePanelName != ""'>TRUE</s:if><s:else>FALSE</s:else>
<s:if test="#sidePanelName != ''">TRUE</s:if><s:else>FALSE</s:else>
<s:if test='#sidePanelName == ""'>TRUE</s:if><s:else>FALSE</s:else>
<s:if test="#sidePanelName == ''">TRUE</s:if><s:else>FALSE</s:else>
<s:if test='%{!#sidePanelName.isEmpty()}'>TRUE</s:if><s:else>FALSE</s:else>
<s:if test='%{#sidePanelName.length() > 0}'>TRUE</s:if><s:else>FALSE</s:else>
<s:if test='%{#sidePanelName.length() == 0}'>TRUE</s:if><s:else>FALSE</s:else>
<s:if test='%{#sidePanelName.equals("")}'>TRUE</s:if><s:else>FALSE</s:else>
<s:if test='%{#sidePanelName.equalsIgnoreCase("")}'>TRUE</s:if><s:else>FALSE</s:else>
<s:if test='#sidePanelName == null'>TRUE</s:if><s:else>FALSE</s:else>
<s:if test='#sidePanelName != null'>TRUE</s:if><s:else>FALSE</s:else>

<s:if test='sidePanelName != ""'>TRUE</s:if><s:else>FALSE</s:else>
<s:if test="sidePanelName != ''">TRUE</s:if><s:else>FALSE</s:else>
<s:if test='sidePanelName == ""'>TRUE</s:if><s:else>FALSE</s:else>
<s:if test="sidePanelName == ''">TRUE</s:if><s:else>FALSE</s:else>
<s:if test='%{!sidePanelName.isEmpty()}'>TRUE</s:if><s:else>FALSE</s:else>
<s:if test='%{sidePanelName.length() > 0}'>TRUE</s:if><s:else>FALSE</s:else>
<s:if test='%{sidePanelName.length() == 0}'>TRUE</s:if><s:else>FALSE</s:else>
<s:if test='%{sidePanelName.equals("")}'>TRUE</s:if><s:else>FALSE</s:else>
<s:if test='%{sidePanelName.equalsIgnoreCase("")}'>TRUE</s:if><s:else>FALSE</s:else>
<s:if test='sidePanelName == null'>TRUE</s:if><s:else>FALSE</s:else>
<s:if test='sidePanelName != null'>TRUE</s:if><s:else>FALSE</s:else>

【问题讨论】:

  • 你应该使用s:property标签来输出tiles:getAsString的值。

标签: jsp struts2 tiles2


【解决方案1】:

&lt;tiles:getAsString&gt; 标记将返回空字符串,如果您尚未在图块定义中定义它的值。所以你的代码

<s:set var="sidePanelName"><tiles:getAsString name='pageSidePanel'/></s:set>

将与空的&lt;s:set&gt; 标记相同。

<s:set var="sidePanelName"></s:set>

一个没有value属性的空&lt;s:set&gt;标签会将top分配给一个变量(在大多数情况下它将是当前的动作实例)。

尝试使用&lt;s:property value="#sidePanelName"/&gt; 打印其值。您可能会看到类似your_package.YourClass@hash 的内容。

【讨论】:

  • &lt;tiles:getAsString&gt; 如果未找到命名值,则抛出 JSPException
  • 我的意思是在这种情况下它不会返回空字符串。
  • @RomanC:是的,如果根本没有定义的话。但是OP说有定义但值为空。
  • @RomanC: ignore 属性可以用来忽略异常。
  • 没错,set 标签被评估为top。但就我而言,这不是一个动作。好的,+1 的好答案。
【解决方案2】:

您不能在 null 对象上调用方法...

然后

  • isEmpty()length() 是不可调用的,因为在对象本身上调用,而
  • 对于与equals()equalsIgnoreCase() 的比较,如果在已知对象(如"".equalsIgnoreCase(#sidePanelName))上调用它们,它们可以在不生成NPE 的情况下调用。

顺便说一句,如果对象为null,"".equalsIgnoreCase(#sidePanelName)也会给出false,因为它不等于空字符串,它只是null...


P.S:注意你的描述,有误导性:

我有一个不是字符串类型

的tiles属性

[...]

只要字符串不为空/已填充/至少有一个字符,结果都是正确的-

【讨论】:

  • 我清理了问题并添加了更多详细信息/结果。您能否用这些新信息澄清您的答案?特别是问题:如果tiles属性为空,struts变量是否为空?
  • 阅读this,尤其是其中链接的答案,以避免22次测试:)
  • 谢谢,这对我来说是必要的文献!
猜你喜欢
  • 2013-08-12
  • 1970-01-01
  • 2012-12-04
  • 2013-10-07
  • 1970-01-01
  • 1970-01-01
  • 2014-03-07
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多