Checking request parameter value in Struts2 tag

eumust picture eumust · Dec 30, 2010 · Viewed 10.4k times · Source

I have the following code in my jsp:

<s:property value="#parameters['test']"/>
<br/><s:property value="'1'.equals(#parameters['test'])"/>

now if I access this action like this: test.action?test=1

I get the following:

1
false

Wondering, why 1 is not equal to 1?

Answer

Quaternion picture Quaternion · Dec 30, 2010

Edit: There is a difference between "" (double quotes) and '' (single quotes) in OGNL.

Double quotes evaluate single characters to strings while single quotes evaluate single characters to Character types. You may put multiple characters in single quotes and it will be evaluated as a string.

Further request scope is not

Map<String, String> 

but

Map<String, String[]> 

as can be seen below in last 5 lines of the jsp.

JSP

<%@taglib prefix="s" uri="/struts-tags"%>
<!-- values from action where letters = "abcd" -->
<s:property value="letters"/><br/> <!-- Displays: abcd -->
<s:property value="letters.equals('abcd')"/><br/> <!-- Displays: true -->
<s:property value="'abcd'.compareTo('abcd')"/><br/> <!-- Displays: 0 -->
<s:property value="'abcd'.compareTo('abcd') == 0"/><br/> <!-- Displays: true -->
<s:property value="'abcd'.equals('abcd')"/><br/> <!-- Displays: true -->
<s:property value="'abcd'.equals(letters)"/><br/> <!-- Displays: true -->
<br/>
<!-- RUN with ?test=a&test2=abc appended to the url -->
<!-- Time for the numbers from action where number = 1-->
<s:property value="number"/><br/><!-- Displays: 1 -->
<s:property value="number.toString()"/><br/><!-- Displays: 1 -->
<!-- OGNL strings in certain cases must be double quoted -->
<s:property value='"1".equals(number.toString())'/><br/><!-- Displays: true -->
<!-- As we can see single quotes does automatic type conversion to Character which is then evaluates false-->
<s:property value="'1'.equals(number.toString())"/><br/><!-- Displays: false -->
<!-- here a string is compared to an integer which is false-->
<s:property value='"1".equals(number)'/><br/><!-- Displays: false -->
<br/><!-- Request Variables -->
<s:property value="#parameters['test']"/><br/><!-- Displays: a -->
<!-- a is single quoted so automatic type conversion probably converted it to a Character, which is not equal to string "a" -->
<s:property value="'a'.equals(#parameters['test'])"/><br/><!-- Displays: false -->
<!-- both are strings so equality works as expected -->
<s:property value='#parameters["test"]'/><br/><!-- Displays: a -->
<s:property value='"a".equals(#parameters["test"])'/><br/><!-- Displays: false because #parameters["test"] is a string[] and calling toString on string[] does not work -->
<!-- #parameters['test2'] now is 'abc' automatic type conversion of OGNL swill convert 'abc' to a string and so both are equal -->
<s:property value='#parameters["test2"]'/><br/>
<!-- Double quotes must be a string -->
<s:property value='"abc".compareTo(#parameters["test2"]) == 0'/><br/><!-- Displays: true -->
<!-- Single quote so automatic type conversion... string of chars is converted to String -->
<s:property value="'abc'.compareTo(#parameters['test2']) == 0"/><br/><!-- Displays: true -->
<!-- Out of curiosity I'd like to know if '1' is an Integer or a Byte -->
<s:property value="'1'.toString()"/><br/><!-- Answer: Neither it prints "class java.lang.Character" -->
<!-- 'a' is a Character however equals calls toString() -->
<!-- But the request object (and session too) is not <string, string> but <string, string[]> -->
1: <s:property value='"1".class'/><br/> <!-- class java.lang.String -->
2: <s:property value='#parameters["test"].class'/><br/> <!-- Array of string: class [Ljava.lang.String; -->
3: <s:property value='#parameters["test"][0].class'/><br/> <!-- This is what we need: class java.lang.String -->
<s:property value='#parameters["test"][0].equals("a")'/><br/> <!-- Now this works -->
<s:property value="#parameters['test'][0].equals('a'.toString())"/><br/> <!-- this is another way, leaving off the .toString results in false -->

Test.jsp (Action)

package struts2; import com.opensymphony.xwork2.ActionSupport;

public class test extends ActionSupport{
    public String letters = "abcd";
    public int number = 1;
}