Hi,

On 11.01.2010 21:36, Ian Boston wrote:
> 
> On 11 Jan 2010, at 19:43, Felix Meschberger wrote:
> 
>>
>>
>> On 08.01.2010 16:31, Ian Boston wrote:
>>> We have been trying to implement a Batch method processor (ie a servlet 
>>> that performs multiple requests batching the responses up into a single 
>>> request/response) in Sling.
>>>
>>> Normally with servlets this would require 
>>> requestDispacher.forward(wrappedRequest, wrappedResponse) but this doent 
>>> work since Sling unwrapps all request back to a internal 
>>> SlingHttpServletRequestImpl object so although you can get hold of the 
>>> requestDispatcher, and call the forward method, its almost pointless.
>>
>> I fear, I do not completely understand the problem.
>>
>> You can provide any SlingHttpServletRequest|Response to the forward
>> method and this instance will be presented to the included servlet.
>>
>> If not the provided instances are given to the included servlet, I would
>> consider this a major issue....
>>
>>>
>>> Whats the right way of doing this sort of thing in Sling ?
>>
>> I would say that it should be possible to forward multiple times
>> collecting the output -- you would just have to make sure, no output and
>> headers are really written back by the servlets/scripts forwarded to.
>> Thus the wrappedResponse would have to make sure not to set responses
>> headers (by default in Sling included servlets *can* set response
>> headers unlike in the Servlet API, where this is not possible).
> 
> Wrapping the response works perfectly,
> 
> Wrapping the request does not.
> 
> The SlingRequestDispatcher uses the RequestData.unwrap(...) to unwrap any 
> request back to the first SlingHttpServletRequestImpl (private to the engine 
> bundle) effectively negating any attempt to wrap the request object.

I am not sure, whether we are referring to the same code ...

The SlingRequestDispatcher.dispatch method does:

   SlingHttpServletRequest cRequest = RequestData.unwrap(request);

which returns a SlingHttpServletRequest from the request, which is a
ServletRequest.

Now the RequestData.unwrap(ServletRequest method) does :

        // this should be triggered and immediately return if the
        // request is a SlingHttpServletRequestWrapper or
        // a SlingHttpServletRequestImpl object
        if (request instanceof SlingHttpServletRequest) {
            return (SlingHttpServletRequest) request;
        }

        // unwrap wrappers
        while (request instanceof ServletRequestWrapper) {
            request = ((ServletRequestWrapper) request).getRequest();

            // immediate termination if we found one
            if (request instanceof SlingHttpServletRequest) {
                return (SlingHttpServletRequest) request;
            }
        }

according to my reading, this should returns topmost
SlingHttpServletRequest object, in general is the request object itself.

If there is a misconception on my part, I would be happy to be standing
corrected !

The intent is to *not* unwrap down to the innermost
SlingHttpServletRequestImpl and use that.

Regards
Felix

> 
> Perhaps there should be a marker interface to identify when its safe to use a 
> request object and when it needs to be unwrapped further.
> 
> Ian
> 
> 
>>
>> Regards
>> Felix
>>
>>>
>>> Ian
>>>
>>> BTW, we have also tried Filters registered against the SlingMainSevlet (via 
>>> OSGI), adding another top level servlet directly to the httpservice and 
>>> adding filters at the http service level before the SlingMainServlet. None 
>>> appear to work for all sorts of reason, sadly perfectly valid and to spec.
> 
> 

Reply via email to