1

The following code displays links using <s:a> of Struts starting from 1 to 10.

<s:set var="currentPage" value="2"/>
<s:set var="begin" value="1"/>
<s:set var="end" value="10"/>

<s:iterator begin="%{begin}" end="%{end}" step="1" var="row" status="loop">
    <s:if test="%{#currentPage eq #row}">    <!--???-->
        <span><s:property value="%{#row}"/></span>
    </s:if>

    <s:else>
        <s:url id="pageURL" action="someAction" escapeAmp="false">
            <s:param name="currentPage" value="%{row}"/>
        </s:url>

        <s:a href="%{pageURL}" name="btnPage" cssClass="paging">
            <s:property value="%{#row}"/>
        </s:a>
    </s:else>
</s:iterator>

When currentPage (which is 2) matches the conditional expression test="%{#currentPage eq #row}", it just displays text using <s:property> inside <span> instead of showing a link. That's fine.


When I use these same tags but using appropriate properties in its corresponding action class like so,

<s:iterator begin="%{begin}" end="%{end}" step="1" var="row" status="loop">
    <s:if test="%{currentPage eq #row}">   <!--???-->
        <span class="current"><s:property value="%{#row}"/></span>
    </s:if>

    <s:else>
        <s:url id="pageURL" action="someAction" escapeAmp="false">
            <s:param name="currentPage" value="%{row}"/>
        </s:url>

        <s:a href="%{pageURL}" name="btnPage" cssClass="paging">
            <s:property value="%{#row}"/>
        </s:a>
    </s:else>
</s:iterator>

In this case, currentPage (and all other) is a property of type Long in the action class. Here, the conditional test regarding the previous case which is test="%{#currentPage eq #row}" is evaluated to false.

It requires the omission of # before currentPage. Hence, the expression becomes test="%{currentPage eq #row}" (otherwise, it always evaluates to false).

I don't understand why does the first case require test="%{#currentPage eq #row}" and the second case require test="%{currentPage eq #row}"? Is there anything I might be missing?

Roman C
  • 49,761
  • 33
  • 66
  • 176
Tiny
  • 27,221
  • 105
  • 339
  • 599

1 Answers1

2

When you <s:set> a value it's not on the value stack, but instead in the "value stack context".

Using the bare currentPage reference only searches the actual stack, not the context.

Using #currentPage doesn't check the stack itself, but instead references the stack context.

See these other answers as well:

  1. what's the difference between #{} ${} and %{}?
  2. Struts 2 "%" sign and '#" sign in OGNL
Community
  • 1
  • 1
Dave Newton
  • 158,873
  • 26
  • 254
  • 302
  • Are all action objects/variables stored into the value stack under `ActionContext`? – Tiny Dec 30 '13 at 19:37
  • @Tiny The action itself is on the top of the stack (normally) once you hit the view layer, although you can put your own values on top of it, e.g., using `` or `` etc. – Dave Newton Dec 30 '13 at 19:48
  • `Using the bare currentPage reference only searches the actual stack, not the value stack context` is not true. – Roman C Jun 20 '16 at 11:59