Struts2 Tiles sets var attribute for tile attribute as string

I am using struts 2.3.16 and tiles 2.0.6.

Defining fragments with an empty attribute (among others):

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

      

Some other definitions extend it and they can choose to either fill in the value:

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

      

or leave it blank.

I tried to check if this attribute is empty using the "set" tag for struts and some basic if / else logic. For example:

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

      

The results were not what I expected. I ran 11 logic tests in two flavors, 11 tests used a hashtag and another 11 did not:

#sidePanelName vs sidePanelName

      

I was doing tests with two different JSP pages that actually put the value into tiles and the other did not. So, there are 44 logical tests in total:

  • 11 tests using # on a page where the snippets attribute is empty
  • 11 tests don't use # on a page where the snippets attribute is empty
  • 11 tests using # on a page where tiles attribute is populated with value
  • 11 tests don't use # on a page where tile attribute is populated with value

Situation 3 was ONLY correct. The whole other situation gave the wrong results. For example, in situation 1, if I test #var == null

, I get false, but if I test var == null

(no hashtag) i

, I get true. So, I need to clarify two things:

  • What is the effect of using # or not?
  • What is the effect of the tile attribute having value or not. Does struts var treat it as null or as an empty string or does it depend on whether I used # or not?

For reference, here are all the tests:

<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>

      

+3


source to share


2 answers


The tag <tiles:getAsString>

returns an empty string if you have not defined its value in the tile definition. So your code is

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

      

will be the same as an empty tag <s:set>

.



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

      

And an empty tag <s:set>

with the w / o value

attribute assigns the variable to the top

variable (in most cases, this will be the current instance of the action).

Try to print its value with <s:property value="#sidePanelName"/>

. You will probably see something like your_package.YourClass@hash

.

+4


source


You cannot call methods on an object null

...

Then

  • isEmpty()

    and length()

    are invalid because they are called on the object itself, while
  • for comparison with equals()

    and equalsIgnoreCase()

    , they can be called without generating NPEs if they are called on a known object, for example "".equalsIgnoreCase(#sidePanelName)

    .

BTW if the object is null "".equalsIgnoreCase(#sidePanelName)

will also throw false because it is not an empty String, it is just null ...




PS: pay attention to your description which is misleading:

I have a tile attribute NOT of a string like

[...]

CORRECT results when the string is not empty / filled / has at least one character -

+1


source







All Articles