4

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.

Roman C
  • 49,761
  • 33
  • 66
  • 176
Magno C
  • 1,922
  • 4
  • 28
  • 53
  • @AndreaLigios is right. Change your getters/setters to `getXTrace`/`setXTrace` and it will work. – Aleksandr M Jan 13 '15 at 18:14
  • My getters and setters was generated by eclipse. Give my code above a try. – Magno C Jan 13 '15 at 18:49
  • Of course this will work. Algorithm to construct setter is very simple: put prefix `set`, turn first letter of parameter to upper case and voila. So for `xTrace` parameter S2 will search `setXTrace` method. – Aleksandr M Jan 13 '15 at 18:51
  • I know man. Just give a try. Make a setter using Eclipse's GGAS for "iPad" and other for "imPad". – Magno C Jan 13 '15 at 18:53
  • This is the eclipses algorithm for "sEcho": `getsEcho()` and for "stEcho": `setStEcho(String stEcho)`. By follow this, "stEcho" work and "sEcho" do not work. – Magno C Jan 13 '15 at 18:56
  • Ok, yes it is more complicated than that. But what do you want? Like I already said @AndreaLigios answer is right. – Aleksandr M Jan 13 '15 at 18:57
  • I want to create a variable with just first char lower and second upper and make it to work with predefined getters and setters. – Magno C Jan 13 '15 at 18:59
  • 1
    See http://stackoverflow.com/q/7264253/1700321. – Aleksandr M Jan 13 '15 at 19:00
  • Predefined by eclipse? And what happens when you move to some other ide say... notepad. What will happen then? – Aleksandr M Jan 13 '15 at 19:00
  • Yes. After variable declaration, I just press CTRL+3 and type GGAS (Generate Getters And Setters) and Eclipse do the rest. All getters and setters generated by eclipse follow the specification so I don't know what will happen in Struts if I change the setter "by hand". See my own answer. I'm already solved this by using a fast and safe method. Cold Case. – Magno C Jan 14 '15 at 10:10
  • *by hand*? Setters/getters are no magic stuff there are just methods. *what will happen* - it will work as expected. *fast and safe method* - it isn't fast, and save compared to what? Writing code by hand? – Aleksandr M Jan 14 '15 at 10:59
  • You're right. It works. I was without time to come back to this code and change it. If @AndreaLigios undelete his post I'll aprove it. – Magno C Jan 14 '15 at 11:42

3 Answers3

3

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

Andrea Ligios
  • 49,480
  • 26
  • 114
  • 243
  • 1
    I think you not understood my problem. Setters and getters are correct (I always use eclipse shortcuts). This will return null. Try yourself. Any variable with this format will return null (iPad, iMac, eMail,...). – Magno C Jan 13 '15 at 17:49
  • 2
    As promissed. This is the correct solution. I always use the Eclipse `GGAS` shortcut and wait it to be always correct. By generating getters and setters using this shortcut and then changing it "by hand" (or to be less lazy, bypassing Eclipse shortcuts and write all methods) Struts will work as spected. – Magno C Jan 26 '15 at 10:54
3

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.

Community
  • 1
  • 1
Roman C
  • 49,761
  • 33
  • 66
  • 176
  • Sorry Roman. You're correct too, but @Andrea Ligios wrote first (his answer was deleted and then restored). Thanks for detailed explanation (as usual) although I did not understand much. The real problem was in Eclipse method generator I trust too much. – Magno C Jan 26 '15 at 11:04
  • @MagnoC This is not a question who answered the question first, or second, or later. Before making decision you should look at the quality of the post and if the answer helped you to solve your problem. I've found your question an interesting discussion about JavaBeans convention and it's my problem that I couldn't explain it better. – Roman C Jan 26 '15 at 11:19
  • Agree. @Andrea Ligios solved my problem. I think your answer leads to root of question `why should I follow the naming specs?` or `how this work in deep?`but the real problem was my mistake in trust Eclipse method name generation since if I code using a text editor I would have written correctly. Andrea Ligios simply said: `you dumb! pay attention what you're doing`. – Magno C Jan 26 '15 at 12:23
  • 1
    The problem was that Eclipse's generation is *correct* and it's *not your mistake*, but it's not working with Struts. Andrea's answer was correct, but he didn't explain anything about it. And I thought that questions you have implied discussing his answer. – Roman C Jan 26 '15 at 12:47
1

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.

Magno C
  • 1,922
  • 4
  • 28
  • 53
  • Upvoted for using constant. :) Just a note: you can also use `ServletRequestAware` to get `HttpServletRequest`. – Aleksandr M Jan 14 '15 at 11:44