2

Does anyone know how to easily access the Action class in a JSP when using Struts2? While I know it is often possible to use Struts tags and OGNL, I actually find them both to be confusing (clearly due to ignorance) and quite frankly find it easier to maintain Java in the JSP (not to mention it's easier to explain to new programmers as everyone knows Java).

I have searched for a solutions for years, and the best solution I have found is to call a static method from a class, that looks like:

public static BaseAction getCurrentAction(HttpServletRequest request) {
    OgnlValueStack ognlStack = (OgnlValueStack)request.getAttribute(org.apache.struts2.ServletActionContext.STRUTS_VALUESTACK_KEY);
    return (BaseAction)ognlStack.getRoot().get(0);
}

...which would be in a BaseAction class extended by you own Action class, so that in your JSP you can say:

<%
  MyAction action = (MyAction)BaseAction.getCurrentAction(request);
  String myValue = action.getMyValue();
%>

However this all seems overly complicated and it assumes a precise order in the OgnlValueStack - there must be a better way, non?

Many thanks for any advice!

Alex
  • 21
  • 1
  • 1
  • 2
  • 2
    Or `${myValue}`. I find it nearly inconceivable that a tag, and even OGNL, is so difficult to understand that you'd resort to scriptlets. Are there specific things that cause you issues? If so, maybe it would make more sense to address that, than to try to figure out ways to write *very* suspicious code to do things trivially provided out-of-the-box. – Dave Newton Sep 21 '11 at 21:53
  • Thanks everyone! Clearly this is argumentative stuff, but it just feels easier and more natural to use scriptlets. ...and I'll admit ignorance - eg. I still don't understand when to use #, $ and % and the differences. Thing is, I get java as it's used everywhere else and I tend to be a fan of minimizing the number of technologies used in any given project in order to keep thing more simple. – Alex Sep 21 '11 at 23:09
  • A rough starter. Use # if the data you need is not in the action (IE the session), OGNL expressions aught to be wrapped with %{} but where an expression makes sense it isn't needed. ${} is an EL expression. Documentation is your friend: http://struts.apache.org/2.2.1.1/docs/tag-reference.html (There are plenty of examples you can even cut and paste your way though the simple stuff) – Quaternion Sep 22 '11 at 05:37
  • Many thanks Quanternion! I'm very familiar with that documentation and have gleaned knowledge for many of the examples - unless I'm figuratively blind (which may be possible) what is missing in that documentation is the rough starter knowledge you outline above. Thanks again! – Alex Sep 22 '11 at 17:01

3 Answers3

3

If you don't want to use struts2 tags an equally valid approach is to use JSTL tags. These tags are supported by struts2 and I'm guessing most major java web frameworks.

It is strongly recommended that you avoid servlets/scriplets in typical business programming using any Java Web Framework.

You probably already know this but to get a property from the action just say:

<s:property value="myProperty"/>

Or equally valid using the JSTL (some here would even say more valid as the view no longer depends on struts2)

<c:out value="${myProperty}" />

There are few programmers (and I would stand to say no seasoned struts2 programmers) who would find this harder to understand than

<%
  MyAction action = (MyAction)BaseAction.getCurrentAction(request);
  String myValue = action.getMyValue();
%>

There are only a handful of tags required to generate a page, you need to get properties, iterate to produce tables/lists and that's about it. The time learning those few tags will save a great deal of time.

Quaternion
  • 10,380
  • 6
  • 51
  • 102
  • Thanks Quanternion! My frustration with the Struts tags usually start happening when I am using logic expressions and then they don't work as expected. From my experience this stuff is actually hard to debug, as opposed to scriptlets - which are doing exactly the same thing. Out of curiosity, why is it recommended that you avoid scriptlets in your JSP? Seems reasonable presuming it's only for presentation purposes. Thanks again. – Alex Sep 21 '11 at 23:14
  • 1
    As an exercise try this. Construct your next few pages only using html, the struts2 property tag and the struts2 iterator tag (or equivalent JSTL). What I'm saying (and most others) is keep your Java in the action. Try to keep with these rules: Only output with your jsp, Prepare everything you need to display in your action so there is nothing to do in the jsp and Don't do any business logic in your action, delegate that to other objects. The humble action validates input to pass on to business objects then marshals data for display. Then it's off to the view layer. – Quaternion Sep 22 '11 at 05:32
  • I meant to say "Only output with tags in your jsp". – Quaternion Sep 22 '11 at 05:46
2

To follow up on Quaternion's answer, you can access any public method in your action class from OGNL tags or JSTL as he suggested.

You can also pass parameters to the action class through the tags:

public String getHello(String value){
    return "Hello " + value + "!";
}

Which is called on the JSP:

<s:property value="getHello('Russell')"/>

Which outputs:

Hello Russell!
Russell Shingleton
  • 3,176
  • 1
  • 21
  • 29
  • Interesting - I didn't know you could directly call methods directly from a tag like this - I thought you had to specify them as a property - so in the above example you would say: ``, which will cat the getter for the property `hello`. – Alex Sep 21 '11 at 23:18
  • 1
    You have to consider the how OGNL and JSTL are rendered. They are server side scripting, just like JSP code. When the server fetches the page it essentially "compiles it on the fly" and outputs the results. As the tags are parsed it will invoke the underlying Java code and output the results. Since it is server side scripting, you can do just about anything you need to with the underlying classes as long as the methods are publicly accessible. – Russell Shingleton Sep 22 '11 at 00:51
  • What Russell said is really worth noting, perhaps looking up how to construct a tag of your own would remove all the magic. – Quaternion Sep 22 '11 at 05:44
0

Besides Quaternion's answer , I want to add another way to call action object in here.The action object is on the top of the valueStack.In your jsp, you can access struts action like this,

<% MyAction myAction = (MyAction) ActionContext.getContext().getValueStack().peek(); %>

References: https://struts.apache.org/tag-developers/access-to-valuestack-from-jsps.html

If you want to know more how to access via ognl expression, the following discussion may be helpful for you What are different ways to access variables with OGNL in Struts 2