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.
>
>