You are viewing a plain text version of this content. The canonical link for it is here.
Posted to user@struts.apache.org by Adam Hardy <ah...@cyberspaceroad.com> on 2008/04/19 19:29:18 UTC

from Action to PageContext: how's it done?

 From looking at the struts2 architecture, one of the big questions that I can't 
find the answer to is how struts/xwork moves objects such as the properties on 
an action into the PageContext.

When an interceptor is executing for example, calling 
ServletActionContext.getPageContext() will return null until the action has been 
  invoked.

Invoking the action also executes the Result, so the JSP is called and the 
PageContext is created.

But how does struts do that? I've got a feeling my knowledge of the Servlet 
Container could be better :(

Thanks for any info,
regards
Adam

---------------------------------------------------------------------
To unsubscribe, e-mail: user-unsubscribe@struts.apache.org
For additional commands, e-mail: user-help@struts.apache.org


Re: from Action to PageContext: how's it done?

Posted by Martin Gainty <mg...@hotmail.com>.
 ServletContext attributes 'foo'
 #application['foo'] or #application.foo

 Access to PageContext for attribute foo
 #attr['foo'] or #attr.foo

in WebWork 1.x one could access special named objects (the request scope
attributes to be exact) by using "@foo",
but now special variables are accessed using "#foo" is merely a request to
another object in the OgnlContext <other than the root>

http://struts.apache.org/2.0.11.1/docs/ognl-basics.html
Good Stuff
Martin
----- Original Message -----
From: "Adam Hardy" <ah...@cyberspaceroad.com>
To: "Struts Users Mailing List" <us...@struts.apache.org>
Sent: Saturday, April 19, 2008 9:11 PM
Subject: Re: from Action to PageContext: how's it done?


> Dave Newton on 20/04/08 00:23, wrote:
> > --- Adam Hardy <ah...@cyberspaceroad.com> wrote:
> >> So you say the StrutsRequestWrapper holds the struts context [...]
> >
> > No, I'm saying it has access to it via ActionContext.getContext().
> >
> >> and is accessed  somewhere in the Result to pull everything down
> >> into the PageContext?
> >
> > I'm not sure what that means.
> >
> > All the request wrapper does (slightly simplified) is call
super.getAttribute
> > (where super is an HttpServletRequestWrapper). If nothing is returned
from
> > that, as would be the case with a typical action and action property,
then
> > the wrapper will query the stack for the value.
> >
> > You should probably just look at the source code, no?
>
> Yes, I guess I should if I had a team of sherpas for the expedition. I
once
> scaled the face of the Hibernate Source Massif and only 3 of the team came
back
> alive.
>
> But seriously, I appreciate your comments a lot since they buy me out of
lot of
> hard source code reading, which is not something too pleasant when you
don't
> know where you're aiming for, as you probably know.
>
> What you're saying is clear except one thing - in JSTL I can access the
action.
> And in JSTL, I'm not calling request.getAttribute() - I'm _not_ doing
this:
>
> ${requestScope['myObject']}
>
> I'm just doing this:
>
> ${myObject}
>
> and struts somehow gives me the right info, which to my mind means that
Struts
> has put that object into the PageContext already.
>
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: user-unsubscribe@struts.apache.org
> For additional commands, e-mail: user-help@struts.apache.org
>
>


---------------------------------------------------------------------
To unsubscribe, e-mail: user-unsubscribe@struts.apache.org
For additional commands, e-mail: user-help@struts.apache.org


Re: from Action to PageContext: how's it done?

Posted by Adam Hardy <ah...@cyberspaceroad.com>.
Dave Newton on 20/04/08 02:24, wrote:
> --- Adam Hardy <ah...@cyberspaceroad.com> wrote:
>> What you're saying is clear except one thing - in JSTL I can access the
>> action. And in JSTL, I'm not calling request.getAttribute() - I'm _not_
> doing this:
>> ${requestScope['myObject']}
>>
>> I'm just doing this:
>>
>> ${myObject}
>>
>> and struts somehow gives me the right info, which to my mind means that
>> Struts has put that object into the PageContext already.
> 
> I told you precisely what it did: if the request wrapper can't find the
> attribute in normal scope, it goes to the stack.
> 
> Here is the entire relevant source; it's 36 lines. With comments.
> 
>     public Object getAttribute(String s) {  [snip]

OK mystery over - I just didn't see how the JSP gets to the request wrapper to 
make that call to request.getAttribute().

I just realised though - the PageContext will search through all scopes, 
starting with the Request until it finds what you asked for. Unless you specify 
PageContext.SESSION_SCOPE or other.

Sorry for the misunderstanding.


Adam

---------------------------------------------------------------------
To unsubscribe, e-mail: user-unsubscribe@struts.apache.org
For additional commands, e-mail: user-help@struts.apache.org


Re: from Action to PageContext: how's it done?

Posted by Dave Newton <ne...@yahoo.com>.
--- Adam Hardy <ah...@cyberspaceroad.com> wrote:
> What you're saying is clear except one thing - in JSTL I can access the
> action. And in JSTL, I'm not calling request.getAttribute() - I'm _not_
doing this:
> 
> ${requestScope['myObject']}
> 
> I'm just doing this:
> 
> ${myObject}
> 
> and struts somehow gives me the right info, which to my mind means that
> Struts has put that object into the PageContext already.

I told you precisely what it did: if the request wrapper can't find the
attribute in normal scope, it goes to the stack.

Here is the entire relevant source; it's 36 lines. With comments.

    public Object getAttribute(String s) {
        if (s != null && s.startsWith("javax.servlet")) {
            // don't bother with the standard javax.servlet attributes, we
can short-circuit this
            // see WW-953 and the forums post linked in that issue for more
info
            return super.getAttribute(s);
        }

        ActionContext ctx = ActionContext.getContext();
        Object attribute = super.getAttribute(s);
        if (ctx != null) {
            if (attribute == null) {
                boolean alreadyIn = false;
                Boolean b = (Boolean)
ctx.get("__requestWrapper.getAttribute");
                if (b != null) {
                    alreadyIn = b.booleanValue();
                }
    
                // note: we don't let # come through or else a request for
                // #attr.foo or #request.foo could cause an endless loop
                if (!alreadyIn && s.indexOf("#") == -1) {
                    try {
                        // If not found, then try the ValueStack
                        ctx.put("__requestWrapper.getAttribute",
Boolean.TRUE);
                        ValueStack stack = ctx.getValueStack();
                        if (stack != null) {
                            attribute = stack.findValue(s);
                        }
                    } finally {
                        ctx.put("__requestWrapper.getAttribute",
Boolean.FALSE);
                    }
                }
            }
        }
        return attribute;
    }

Dave


---------------------------------------------------------------------
To unsubscribe, e-mail: user-unsubscribe@struts.apache.org
For additional commands, e-mail: user-help@struts.apache.org


Re: from Action to PageContext: how's it done?

Posted by Adam Hardy <ah...@cyberspaceroad.com>.
Dave Newton on 20/04/08 00:23, wrote:
> --- Adam Hardy <ah...@cyberspaceroad.com> wrote:
>> So you say the StrutsRequestWrapper holds the struts context [...]
> 
> No, I'm saying it has access to it via ActionContext.getContext().
> 
>> and is accessed  somewhere in the Result to pull everything down 
>> into the PageContext?
> 
> I'm not sure what that means.
> 
> All the request wrapper does (slightly simplified) is call super.getAttribute
> (where super is an HttpServletRequestWrapper). If nothing is returned from
> that, as would be the case with a typical action and action property, then
> the wrapper will query the stack for the value.
> 
> You should probably just look at the source code, no?

Yes, I guess I should if I had a team of sherpas for the expedition. I once 
scaled the face of the Hibernate Source Massif and only 3 of the team came back 
alive.

But seriously, I appreciate your comments a lot since they buy me out of lot of 
hard source code reading, which is not something too pleasant when you don't 
know where you're aiming for, as you probably know.

What you're saying is clear except one thing - in JSTL I can access the action. 
And in JSTL, I'm not calling request.getAttribute() - I'm _not_ doing this:

${requestScope['myObject']}

I'm just doing this:

${myObject}

and struts somehow gives me the right info, which to my mind means that Struts 
has put that object into the PageContext already.

---------------------------------------------------------------------
To unsubscribe, e-mail: user-unsubscribe@struts.apache.org
For additional commands, e-mail: user-help@struts.apache.org


Re: from Action to PageContext: how's it done?

Posted by Dave Newton <ne...@yahoo.com>.
--- Adam Hardy <ah...@cyberspaceroad.com> wrote:
> So you say the StrutsRequestWrapper holds the struts context [...]

No, I'm saying it has access to it via ActionContext.getContext().

> and is accessed  somewhere in the Result to pull everything down 
> into the PageContext?

I'm not sure what that means.

All the request wrapper does (slightly simplified) is call super.getAttribute
(where super is an HttpServletRequestWrapper). If nothing is returned from
that, as would be the case with a typical action and action property, then
the wrapper will query the stack for the value.

You should probably just look at the source code, no?

Dave



---------------------------------------------------------------------
To unsubscribe, e-mail: user-unsubscribe@struts.apache.org
For additional commands, e-mail: user-help@struts.apache.org


Re: from Action to PageContext: how's it done?

Posted by Adam Hardy <ah...@cyberspaceroad.com>.
Dave Newton on 19/04/08 23:54, wrote:
> --- Adam Hardy <ah...@cyberspaceroad.com> wrote:
>> The struts interceptors encompass both the actions and the results, but how
>> does struts put the action properties into the pageContext?
> 
> It doesn't; it puts the action on the stack. The tags use OGNL to get values
> from the stack context, or when using JSP 2.0 EL the S2 request wrapper will
> go to the stack if the value isn't found in the normal contexts.
> 
> I guess I'm not really sure what you're asking.

I think you've understood what I'm asking.

So how does the stack context get put into the pageContext? The pageContext only 
comes into existence when the JSP is called via (presumably) a 
RequestDispatcher.forward() - what I can't figure out is how struts gets 
involved in the JSP when I'm not using struts tags there or anything except some 
JSTL to ask for an action property such as "${myPropertyOnAction}"

So you say the StrutsRequestWrapper holds the struts context and is accessed 
somewhere in the Result to pull everything down into the PageContext?

I don't understand the javadoc for StrutsRequestWrapper which says

"All Struts requests are wrapped with this class, which provides simple JSTL 
accessibility. This is because JSTL works with request attributes, so this class 
delegates to the value stack ...."

JSTL only works with request attributes when you explicitly say 
"${requestScope[thing]}"

No?
Adam



---------------------------------------------------------------------
To unsubscribe, e-mail: user-unsubscribe@struts.apache.org
For additional commands, e-mail: user-help@struts.apache.org


Re: from Action to PageContext: how's it done?

Posted by Dave Newton <ne...@yahoo.com>.
--- Adam Hardy <ah...@cyberspaceroad.com> wrote:
> The struts interceptors encompass both the actions and the results, but how
> does struts put the action properties into the pageContext?

It doesn't; it puts the action on the stack. The tags use OGNL to get values
from the stack context, or when using JSP 2.0 EL the S2 request wrapper will
go to the stack if the value isn't found in the normal contexts.

I guess I'm not really sure what you're asking.

Dave


---------------------------------------------------------------------
To unsubscribe, e-mail: user-unsubscribe@struts.apache.org
For additional commands, e-mail: user-help@struts.apache.org


Re: from Action to PageContext: how's it done?

Posted by Adam Hardy <ah...@cyberspaceroad.com>.
Ralf Fischer on 19/04/08 18:43, wrote:
> On Sat, Apr 19, 2008 at 7:29 PM, Adam Hardy
> <ah...@yberspaceroad.com> wrote:
>> From looking at the struts2 architecture, one of the big questions that I
>> can't find the answer to is how struts/xwork moves objects such as the
>> properties on an action into the PageContext.
> 
> Actually it's not done at all. I guess your real question is "I create
> some objects in my action and want to render them somehow in the view.
> How do I do that?"

Sorry, your guess was wide of the mark. My mistake for not being more explicit. 
I am familiar enough with the struts framework to know how I can put getters and 
setters on my action and use  properties accordingly in my JSP with JSTL or OGNL 
or whatever, but my question is one meta-level up from your answer, i.e. how is 
that done by struts?

The struts interceptors encompass both the actions and the results, but how does 
struts put the action properties into the pageContext?


Adam

---------------------------------------------------------------------
To unsubscribe, e-mail: user-unsubscribe@struts.apache.org
For additional commands, e-mail: user-help@struts.apache.org


Re: from Action to PageContext: how's it done?

Posted by Ralf Fischer <th...@googlemail.com>.
Hello Adam

On Sat, Apr 19, 2008 at 7:29 PM, Adam Hardy
<ah...@cyberspaceroad.com> wrote:
> From looking at the struts2 architecture, one of the big questions that I
> can't find the answer to is how struts/xwork moves objects such as the
> properties on an action into the PageContext.

Actually it's not done at all. I guess your real question is "I create
some objects in my action and want to render them somehow in the view.
How do I do that?"

Upon request to your struts web application the filter creates a value
stack which holds all the information needed. The action responsible
for the "page" of I may say so is put onto the stack and the single
interceptors on the stack set the parameters from the configuration or
the requested URI into the stack. Usually this leads to the population
of action properties if you did everything right, meaning the URI
parameter  ?foo=1 will lead to a call of setFoo("1").

The same stack is still available when the result associated with the
action is rendered, which may be a JSP page, and you can access
information easily by using OGNL expressions to extract the
information you need.

>  When an interceptor is executing for example, calling
> ServletActionContext.getPageContext() will return null until the action has
> been  invoked.

Is there a page context yet when you are some method calls away from a
servlet filter?

>  Invoking the action also executes the Result, so the JSP is called and the
> PageContext is created.
>
>  But how does struts do that? I've got a feeling my knowledge of the Servlet
> Container could be better :(

I suggest some basic reading on struts, here[1] for example.

Cheers,
-Ralf

[1] http://struts.apache.org/2.0.11.1/docs/home.html

---------------------------------------------------------------------
To unsubscribe, e-mail: user-unsubscribe@struts.apache.org
For additional commands, e-mail: user-help@struts.apache.org