Setting response headers from inside layout code

classic Classic list List threaded Threaded
4 messages Options
Reply | Threaded
Open this post in threaded view
|

Setting response headers from inside layout code

Mike McNally-3
I'm noticing that I can't set HTTP response headers from code that's in a <layout-defiinition> when it's invoked. Debugging a little (I wrote a little tag class to experiment) I note that I can successfully call "setHeader" or "setContentType", but they have no apparent effect; immediately calling "getContentType" on the Response object returns a different string than passed to "setContentType".

When that code runs, it's using a wrapped version of the ServletResponse. From outside the context of a Stripes layout, that test tag works just fine.

Is this a situation that I should expect? Is there any way around that? I need to set the content type inside a layout because that's where the need for it is determined (it's deciding between JSON and HTML).

--
Turtle, turtle, on the ground,
Pink and shiny, turn around.

------------------------------------------------------------------------------

_______________________________________________
Stripes-users mailing list
[hidden email]
https://lists.sourceforge.net/lists/listinfo/stripes-users
Reply | Threaded
Open this post in threaded view
|

Re: Setting response headers from inside layout code

Matthijs Laan
On 2014-07-11 22:28, Mike McNally wrote:

> I'm noticing that I can't set HTTP response headers from code that's
> in a <layout-defiinition> when it's invoked. Debugging a little (I
> wrote a little tag class to experiment) I note that I can successfully
> call "setHeader" or "setContentType", but they have no apparent
> effect; immediately calling "getContentType" on the Response object
> returns a different string than passed to "setContentType".
>
> When that code runs, it's using a wrapped version of the
> ServletResponse. From outside the context of a Stripes layout, that
> test tag works just fine.
>
> Is this a situation that I should expect? Is there any way around
> that? I need to set the content type inside a layout because that's
> where the need for it is determined (it's deciding between JSON and HTML).
>

Rewrite your code so you decide the content type in your ActionBean. In
the MVC model the view (resolution) should only display your model, the
controller (actionbean) should decide which view to use.

For JSON I usually return a Resolution like:

   new StreamingResolution("application/json", new
StringReader(json.toString(4)));

Matthijs


------------------------------------------------------------------------------
Want fast and easy access to all the code in your enterprise? Index and
search up to 200,000 lines of code with a free copy of Black Duck&#174;
Code Sight&#153; - the same software that powers the world's largest code
search on Ohloh, the Black Duck Open Hub! Try it now.
http://p.sf.net/sfu/bds
_______________________________________________
Stripes-users mailing list
[hidden email]
https://lists.sourceforge.net/lists/listinfo/stripes-users
Reply | Threaded
Open this post in threaded view
|

Re: Setting response headers from inside layout code

Stone, Timothy
Mike,

Matt highlights something that is cleverly enforced in the Stripes
platform, the Front Controller pattern and what Freddy Daoud terms the
³pre-action² pattern. These patterns discourage ³direct-to-JSP² access.
When using the Stripes tag library with the layouts, as in your examples,
you are seeing this enforcement.

The ideas are more clearly expressed in Freddy¹s book, /Stripes...and Java
web development is fun again./ (PragProg,
http://pragprog.com/book/fdstr/stripes).


> The ³pre-action² pattern
> A good practice in a Stripes application is to use what is known as the
>³pre-action² pattern. This consists of always having requests go to  >
>Action Beans rather than directly to JSPs. We did this in the example‹
>both links target HelloActionBean using the beanclass= attribute of
> the <s:link> tag. There are no direct links to hello.jsp. In fact, we
>made sure of that by placing the JSP file in the /WEB-INF/jsp
> directory. In Java web applications, files anywhere under /WEB-INF
>cannot be accessed by the browser.

> Using the pre-action pattern has the following advantages:
> * ensures that the current Action Bean will be available in the JSP
>using ${actionBean}
> * routes requests through Action Beans, involving the full Stripes
>request-response lifecycle and
>   giving us more control over what happens between the stages of this
>lifecycle
> * restricts the URLs used to access the application, making it easier to
>control security
> * targets Action Beans instead of JSPs, making our code refer to class
>names instead of URLs













On 7/14/14, 4:19 AM, "Matthijs Laan" <[hidden email]> wrote:

>On 2014-07-11 22:28, Mike McNally wrote:
>> I'm noticing that I can't set HTTP response headers from code that's
>> in a <layout-defiinition> when it's invoked. Debugging a little (I
>> wrote a little tag class to experiment) I note that I can successfully
>> call "setHeader" or "setContentType", but they have no apparent
>> effect; immediately calling "getContentType" on the Response object
>> returns a different string than passed to "setContentType".
>>
>> When that code runs, it's using a wrapped version of the
>> ServletResponse. From outside the context of a Stripes layout, that
>> test tag works just fine.
>>
>> Is this a situation that I should expect? Is there any way around
>> that? I need to set the content type inside a layout because that's
>> where the need for it is determined (it's deciding between JSON and
>>HTML).
>>
>
>Rewrite your code so you decide the content type in your ActionBean. In
>the MVC model the view (resolution) should only display your model, the
>controller (actionbean) should decide which view to use.
>
>For JSON I usually return a Resolution like:
>
>   new StreamingResolution("application/json", new
>StringReader(json.toString(4)));
>
>Matthijs
>
>
>--------------------------------------------------------------------------
>----
>Want fast and easy access to all the code in your enterprise? Index and
>search up to 200,000 lines of code with a free copy of Black Duck&#174;
>Code Sight&#153; - the same software that powers the world's largest code
>search on Ohloh, the Black Duck Open Hub! Try it now.
>http://p.sf.net/sfu/bds
>_______________________________________________
>Stripes-users mailing list
>[hidden email]
>https://lists.sourceforge.net/lists/listinfo/stripes-users


Barclaycard

www.barclaycardus.com<http://www.barclaycardus.com>

This email and any files transmitted with it may contain confidential and/or proprietary information. It is intended solely for the use of the individual or entity who is the intended recipient. Unauthorized use of this information is prohibited. If you have received this in error, please contact the sender by replying to this message and delete this material from any system it may be on.

------------------------------------------------------------------------------
Want fast and easy access to all the code in your enterprise? Index and
search up to 200,000 lines of code with a free copy of Black Duck&#174;
Code Sight&#153; - the same software that powers the world's largest code
search on Ohloh, the Black Duck Open Hub! Try it now.
http://p.sf.net/sfu/bds
_______________________________________________
Stripes-users mailing list
[hidden email]
https://lists.sourceforge.net/lists/listinfo/stripes-users
Reply | Threaded
Open this post in threaded view
|

Re: Setting response headers from inside layout code

Mike McNally-3
My requests all *do* go to ActionBean code.  The issue is that I don't want every single action bean to have to include code to figure out the appropriate content type. Really I could do the work in an Intercept, but because the response JSP has to include different stuff when it's initializing the single-page app than when it isn't, putting the content type test there makes sense (to me at least). I strongly prefer my Java code to "know" as little as possible about what's going on after an action returns a response (other than the page name for the Forward of course).

The real issue here doesn't have much to do with Stripes architecture. It turns out it's just a JSP thing: from inside a JSP include (which is what a Stripes layout really is), response headers can't be tampered with.

The solution to my problem was to just use a pair of simple JSP tag files instead of a Stripes layout, because it *is* possible to mess with the response headers from that context.


On Mon, Jul 14, 2014 at 8:36 AM, Stone, Timothy <[hidden email]> wrote:
Mike,

Matt highlights something that is cleverly enforced in the Stripes
platform, the Front Controller pattern and what Freddy Daoud terms the
³pre-action² pattern. These patterns discourage ³direct-to-JSP² access.
When using the Stripes tag library with the layouts, as in your examples,
you are seeing this enforcement.

The ideas are more clearly expressed in Freddy¹s book, /Stripes...and Java
web development is fun again./ (PragProg,
http://pragprog.com/book/fdstr/stripes).


> The ³pre-action² pattern
> A good practice in a Stripes application is to use what is known as the
>³pre-action² pattern. This consists of always having requests go to  >
>Action Beans rather than directly to JSPs. We did this in the example‹
>both links target HelloActionBean using the beanclass= attribute of
> the <s:link> tag. There are no direct links to hello.jsp. In fact, we
>made sure of that by placing the JSP file in the /WEB-INF/jsp
> directory. In Java web applications, files anywhere under /WEB-INF
>cannot be accessed by the browser.

> Using the pre-action pattern has the following advantages:
> * ensures that the current Action Bean will be available in the JSP
>using ${actionBean}
> * routes requests through Action Beans, involving the full Stripes
>request-response lifecycle and
>   giving us more control over what happens between the stages of this
>lifecycle
> * restricts the URLs used to access the application, making it easier to
>control security
> * targets Action Beans instead of JSPs, making our code refer to class
>names instead of URLs













On 7/14/14, 4:19 AM, "Matthijs Laan" <[hidden email]> wrote:

>On 2014-07-11 22:28, Mike McNally wrote:
>> I'm noticing that I can't set HTTP response headers from code that's
>> in a <layout-defiinition> when it's invoked. Debugging a little (I
>> wrote a little tag class to experiment) I note that I can successfully
>> call "setHeader" or "setContentType", but they have no apparent
>> effect; immediately calling "getContentType" on the Response object
>> returns a different string than passed to "setContentType".
>>
>> When that code runs, it's using a wrapped version of the
>> ServletResponse. From outside the context of a Stripes layout, that
>> test tag works just fine.
>>
>> Is this a situation that I should expect? Is there any way around
>> that? I need to set the content type inside a layout because that's
>> where the need for it is determined (it's deciding between JSON and
>>HTML).
>>
>
>Rewrite your code so you decide the content type in your ActionBean. In
>the MVC model the view (resolution) should only display your model, the
>controller (actionbean) should decide which view to use.
>
>For JSON I usually return a Resolution like:
>
>   new StreamingResolution("application/json", new
>StringReader(json.toString(4)));
>
>Matthijs
>
>
>--------------------------------------------------------------------------
>----
>Want fast and easy access to all the code in your enterprise? Index and
>search up to 200,000 lines of code with a free copy of Black Duck&#174;
>Code Sight&#153; - the same software that powers the world's largest code
>search on Ohloh, the Black Duck Open Hub! Try it now.
>http://p.sf.net/sfu/bds
>_______________________________________________
>Stripes-users mailing list
>[hidden email]
>https://lists.sourceforge.net/lists/listinfo/stripes-users


Barclaycard

www.barclaycardus.com<http://www.barclaycardus.com>

This email and any files transmitted with it may contain confidential and/or proprietary information. It is intended solely for the use of the individual or entity who is the intended recipient. Unauthorized use of this information is prohibited. If you have received this in error, please contact the sender by replying to this message and delete this material from any system it may be on.

------------------------------------------------------------------------------
Want fast and easy access to all the code in your enterprise? Index and
search up to 200,000 lines of code with a free copy of Black Duck&#174;
Code Sight&#153; - the same software that powers the world's largest code
search on Ohloh, the Black Duck Open Hub! Try it now.
http://p.sf.net/sfu/bds
_______________________________________________
Stripes-users mailing list
[hidden email]
https://lists.sourceforge.net/lists/listinfo/stripes-users



--
Turtle, turtle, on the ground,
Pink and shiny, turn around.

------------------------------------------------------------------------------
Want fast and easy access to all the code in your enterprise? Index and
search up to 200,000 lines of code with a free copy of Black Duck&#174;
Code Sight&#153; - the same software that powers the world's largest code
search on Ohloh, the Black Duck Open Hub! Try it now.
http://p.sf.net/sfu/bds
_______________________________________________
Stripes-users mailing list
[hidden email]
https://lists.sourceforge.net/lists/listinfo/stripes-users