Richard
Richard

Reputation: 43

Struts parameters not accessible in <s:if> tag

I have a .jsp page that does the following check to see if it should display an error message:

<s:if test="#parameters.error == 1">
    <ul><li>
        <s:text name="login.error"/>
    </li></ul>
</s:if>

The error parameter comes from the request parameter (i.e. /myPage.action?error=1).

I've debugged the jsp page into the org.apache.struts2.views.jspComponentTagSupport.doStartTag() method and from there I can access the ValueStack and see that the HttpParameters object does contain an "error" parameter, which I can access via:

stack.getContext().get("parameters")).get("error")).getValue();

This will return a String with the value of 1 as expected.
However, debugging down through the code further it seems that it's not properly evaluating the test attribute of the <s:if> tag.
The ognl.ASTEq.getValueBody(OgnlContext, Object) method attempts to get the value of the 'children' of the parsed test query.
It ends up in the ognl.OgnlRuntime.getFieldValue(OgnlContext, Object, String, boolean) method which returns a NotFound result, even though the HttpParameters contains the value it's looking for ("error").

It seems like this is a bug in struts/ognl for how it's parsing the parameters on the value stack, but I'm not sure.

I'm using Struts 2.5.5. Recently upgraded from Struts 2.3.x and this code worked fine with that version so either it's a bug or something changed in how these properties are accessed that I'm not aware of.

Upvotes: 3

Views: 1492

Answers (2)

Aleksandr M
Aleksandr M

Reputation: 24396

Only in Struts 2.5.5.

If you want to check value of the error parameter then:

<s:if test="#parameters.get('error').value == 1">
    <ul><li>
        <s:text name="login.error"/>
    </li></ul>
</s:if>

If you want to check whether parameter exists:

<s:if test="#parameters.contains('error')">
</s:if>

Andrea is right about the cause and about using request parameters.

Upvotes: 3

Andrea Ligios
Andrea Ligios

Reputation: 50203

From a short research, it could be due to Issue WW-4572, AKA the refactoring of the Parameter management, from a Map of Objects to an HttpParameter class containing Parameter objects, shipped with version 2.5.5.

Looking at the Parameter class, it seems it should be enough to call the value attribute on it, like:

<s:if test="%{#parameters.error.value == 1}">

I hope is that, but meanwhile: try using more of the framework mechanisms and less the request parameters (eg. use an error variable with getter and setter on a base action, or even better, use actionErrors and fieldErrors to carry the messages, and check for their presence to detect when an error occurred).

Upvotes: 3

Related Questions