users@jersey.java.net

Fixed <was> Re: [Jersey] Doh! Re: [Jersey] Trying to include a resource class from jsp

From: Paul Sandoz <Paul.Sandoz_at_Sun.COM>
Date: Fri, 18 Dec 2009 13:57:58 +0100

Hi,

I have fixed this in the trunk. So you should be able to correctly
include views using c:import and views may include other views and the
appropriate "it" is correctly in scope.

I think allowing one to choose the model name is orthogonal to the
underlying ability to include. But, without your test case i would
never have been able to work out an appropriate solution.

Any solution to choose the model name should i think be accompanied
with solutions to extend the template processing and viewable APIs
such that:

1) resolving returns an object associated with the template processor,
which is then passed to the writeTo method; and

2) by default a request does not have to be in scope for Viewable
instances to be processed (it should depend on the
     TempalteProcessor implementation)

Paul.


On Dec 15, 2009, at 5:13 PM, Paul Sandoz wrote:

> Hi,
>
> I modified Jersey's RequestDispatcherWrapper to "push"/"pop"
> appropriate request attributes and modified ServletContainer along
> similar lines as the ExtendedServletContainer and it appears to all
> work fine with c:import. See attached for a patch.
>
> I have a question. In your ExtendedServletContainer why do you do
> the following:
>
> String requestURI = request.getRequestURI();
> if (includeRequestURI.equalsIgnoreCase(requestURI)) {
> super.doFilter(request, response, chain);
> return;
> }
>
> Why is it necessary to compare the included request URI with the
> request URI?
>
> Ignoring the case when comparing is likely to be an issue as URI
> paths are case sensitive.
>
> Paul.
>
> <jersey-server.patch>
>
> On Dec 15, 2009, at 3:23 PM, Paul Sandoz wrote:
>
>>
>> On Dec 15, 2009, at 2:44 PM, Yoryos wrote:
>>
>>> There is a logical bug:
>>>
>>> Try to add a:
>>> IncludeViewResource model again: ${it} at the end of the
>>> include.jsp. The it is not the expected one. I would expect the
>>> one of IncludeViewResource but as we've included the TwoResource
>>> class, the it has been overwritten by it's model witch is the
>>> string 'TwoResource'
>>>
>>
>> Nice catch, this requires a simple modification to the
>> RequestDispatcherWrapper:
>>
>> public void forward(ServletRequest req, ServletResponse rsp)
>> throws ServletException, IOException {
>> ResolvedViewable rv =
>> (ResolvedViewable
>> )hc
>> .getProperties().get("com.sun.jersey.spi.template.ResolvedViewable");
>>
>> Object oldIt = req.getAttribute("it");
>>
>> req.setAttribute("httpContext", hc);
>> req.setAttribute("resolvingClass", rv.getResolvingClass());
>> req.setAttribute("it", it);
>> req.setAttribute("_basePath", basePath);
>> req.setAttribute("_request", req);
>> req.setAttribute("_response", rsp);
>> d.forward(req,rsp);
>>
>> if (oldIt != null)
>> req.setAttribute("it", oldIt);
>> }
>>
>>
>>> I can't think how could c:import work out of the box without named
>>> model. I'll try to play with a jsp tag that will replace the model
>>> in each include. That should work (I hope :-) ).
>>>
>>
>> Even with a named model the same issue could have occurred if two
>> views independently use the same name.
>>
>> Paul.
>>
>>>
>>> On Tue, Dec 15, 2009 at 15:08, Paul Sandoz <Paul.Sandoz_at_sun.com>
>>> wrote:
>>>
>>> On Dec 15, 2009, at 12:31 PM, Paul Sandoz wrote:
>>>
>>>> On Dec 15, 2009, at 12:06 PM, Paul Sandoz wrote:
>>>>>>
>>>>>> OK. I have just played around with your sample and if i do not
>>>>>> register your ExtendedJSPTemplateProcessor and modify Jersey's
>>>>>> RequestDispatcherWrapper such that the include methods is
>>>>>> implemented as follows:
>>>>>>
>>>>>> public void include(ServletRequest req, ServletResponse
>>>>>> rsp) throws ServletException, IOException {
>>>>>> ResolvedViewable rv =
>>>>>> (ResolvedViewable
>>>>>> )hc
>>>>>> .getProperties
>>>>>> ().get("com.sun.jersey.spi.template.ResolvedViewable");
>>>>>>
>>>>>> req.setAttribute("httpContext", hc);
>>>>>> req.setAttribute("resolvingClass",
>>>>>> rv.getResolvingClass());
>>>>>> req.setAttribute("it", it);
>>>>>> req.setAttribute("_basePath", basePath);
>>>>>> req.setAttribute("_request", req);
>>>>>> req.setAttribute("_response", rsp);
>>>>>> d.include(req,rsp);
>>>>>> }
>>>>>>
>>>>>
>>>>> Clarification: the above does not actually require any
>>>>> modification because Jersey's JSPTemplateProcessor always calls
>>>>> the forward on the dispatcher. Thus some tweaks to the
>>>>> ServletContainer.filter method may be all that is required.
>>>>>
>>>>
>>>> After debugging, i observed that the
>>>> ExtendedServletContainer.doFilter is never called for includes
>>>> from views. Thus there is something more fundamental going on.
>>>> Since the JSPTemplateProcessor calls forward then perhaps after
>>>> that it is not possible to include using the JSP include tag?
>>>>
>>>
>>> Doh! i forgot to include the following statement in the JSP file:
>>>
>>> <%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>
>>>
>>> Now everything works as i would expect.
>>>
>>> Attached is a modification of your example that uses Jersey's
>>> unmodified JSPTemplateProcessor and RequestDispatcherWrapper.
>>>
>>> Paul.
>>>
>>>
>>>
>>>
>>>> In any case from what i can tell one does not have to modify
>>>> Viewable to get equivalent behavior for view inclusion as in the
>>>> example you provide. But, to get re-entrant inclusion will
>>>> require a little more head scratching to work out and still may
>>>> require a custom tag.
>>>>
>>>> Paul.
>>>>
>>>
>>>
>>>
>>
>