Struts2 passing variables case
I'm using Datatables server side ajax pagination and need to pass some variables to server. My server is running Struts2 actions to handle this datatables requests.
I'm facing some problems because datatables is passing predefined internal variables (like iDisplayStart, iDisplayLength, iColumns, sSearch), but Struts2 cannot receive this kind of camelcase style (just first one char lower and second upper case).
To ensure this, I created this test action:
@Action (value = "dummy",
results = {
@Result(name="ok", type="httpheader", params={"status", "200"}) }
)
@ParentPackage("default")
public class DummyAction {
private String xTrace;
public String execute () {
System.out.println( xTrace );
return "ok";
}
public String getxTrace() {
return xTrace;
}
public void setxTrace(String xTrace) {
this.xTrace = xTrace;
}
}
I'm calling this URL:
localhost:8580/sagitarii/dummy?xTrace=thisisatest
The output is NULL, but when I change xTrace to xyTrace (and get, set and url too) all goes fine. How can I make this to work?
* EDIT *
I already tried with any word with this format: iPad, iMac, iPhone, eMail, ... I think this could be just my configuration, but please give a try before post answers.
but Struts2 cannot receive this kind of camelcase style (just first one char lower and second upper case)
This is actually not true. Struts2 can receive any variable name that comply JavaBeans spec. But apart from the Java implementation of this spec. (if you want to learn more about JavaBeans, see this post What is a JavaBean exactly?), it's using its own implementation. Because Struts2 uses OGNL to access bean's properties you should know what a "property" is according OGNL language.
What is a property? Roughly, an OGNL property is the same as a bean property, which means that a pair of get/set methods, or alternatively a field, defines a property (the full story is a bit more complicated, since properties differ for different kinds of objects; see below for a full explanation).
And the full explanation you can find here: Referring to Properties.
I will not dig into details how OGNL treats properties of the object but it should follow the contract for PropertyAccessor
. There's a lot of implementations for different kind of "properties". The one that OGNL uses for objects is ObjectPropertyAccessor
. Here's a merely description what it does:
Implementation of
PropertyAccessor
that uses reflection on the target object's class to find a field or a pair of set/get methods with the given property name.
How it's doing it you can find via browsing the source code. I'll just say that it's capitalizing the the first letter of the property name before using it with get/set
method prefix. So, you have asked
How can I make this to work?
Change the method signature of the getter/setter for properties
public String getXTrace() {
return xTrace;
}
public void setXTrace(String xTrace) {
this.xTrace = xTrace;
}
UPDATE:
Since OGNL 3.0.11 the single lowercase letter is not uppercased.
If the variable is
private String xTrace;
getters and setters should be
public String getXTrace() {
return xTrace;
}
public void setXTrace(String xTrace) {
this.xTrace = xTrace;
}
regardless of the double consecutive uppercase characters. The rule is that the first character after the set / get part is uppercased, the rest is unchanged
I figured out by retrieving the variables using HttpServletRequest and bypassing struts way.
HttpServletRequest req = (HttpServletRequest)ActionContext.getContext().get(StrutsStatics.HTTP_REQUEST);
xTrace = req.getParameter("xTrace");
This will get variables correctly.
EDIT
Better and elegant way:
As commented by Aleksandr M, changing the two consecutives setter name to uppercase makes struts sets the data correctly.