"Craig R. McClanahan" wrote:
>
> Anders Kristensen wrote:
>
> > Hi,
> >
> > I'm trying to implement the 2.1 version of the servlet API and I have a
> > question about how the RequestDispatcher mechanism is supposed to work
> > plus a report of a couple of bugs in JSDK 2.1.
> >
> > RequestDispatcher.include makes it possible to include the output of
> > another servlet into the output of the invoked servlet and the included
> > servlet sees the same info in response to getServletPath, getPathInfo,
> > getRequestURI as does the original servlet.
> >
> > This appears to me to be a problem when the included resource is a
> > static file being served by a (system) FileServlet. In this case the
> > FileServlet would use the getPathTranslated (or something similar) to
> > figure out which file it should ship back. However, if it was invoked
> > from some other servlet using, say,
> >
> > RequestDispatcher disp = ctxt.getRequestDispatcher ("/somepath.txt");
> > disp.include(request, response);
> >
> > it wouldn't see "/somepath.txt" in response to getPathTranslated. It is
> > possible to achieve the desired behaviour by having FileServlet first
> > check the request attribute javax.servlet.include.path_info and only if
> > this returns null use getPathInfo. Is this how the JSDK/JWS works?
> > This basically means that *all* servlets using the extra path info needs
> > to perform this extra step, as they won't otherwise work with the
> > inclusion mechanism, and that seems a bit clunky to me. Maybe it would
> > be better for included servlets to see altered request info (as does
> > servlets forward()'ed to)?
> >
>
> One way to deal with this is make your file-serving servlet work when it is
> executed directly, or as an included servlet, like this:
>
> String pathInfo =
> request.getAttribute("javax.servlet.include.path_info");
> if (pathInfo == null)
> pathInfo = request.getPathInfo();
> String pathname =
> getServletContext().getRealPath(pathInfo);
>
> Now, "pathname" contains the absolute pathname of the file to be returned, no
> matter how this servlet is called.
Right, so that's the workaround I mentioned. IMHO this is suboptimal
because it means all servlets which use the extra path info and which
potentially can be include()'d has to perform this extra step.
And here's another, but similiar, gotcha: when the request method is a
POST and the first servlet include()'s another one, that other servlet
has to handle POSTs even when it wouldn't ordinarily do this. For
example, it would probably be quite common to include a static file from
a servlet handling form submissions (e.g. indirectly through JSP),
meaning that the FileServlet suddenly has to treat POST requests just
like GET requests (which is kindof a protocol vioaltion).
Otherwise it has to inspect the javax.servlet.include.* attributes to
try and guess that its being invoked as the result of an include()
rather than directly. If this is going to be common it should probably
be directly supported in the servlet API.
>
> >
> > Anther question: Is it OK for a path argument to getRequestDispatcher
> > to include a query string? I guess so since include() arranges for it to
> > appear in the javax.servlet.include.query_string request attribute. But
> > on the other side a forwarded request doesn't report those params. What
> > gives?
> >
>
> The ability to include a query string on an include() call was a recent
> change. I expect that the "forward" case will be clarified in the 2.2
> servlet API spec -- probably by becoming the request parameters that the
> forwarded-to servlet sees.
>
> You might try this under the recently released JSWDK servlet engine, which
> will track the recent changes and clarifications much more closely than the
> original JSDK 2.1 release.
OK so it's going to change. What is the JSWDK servlet engine and where
can I get info on these recent changes in the servlet API that you
mention? Has it been discussed on this list recently. (I apologise for
not having the stamina to trawl through the archives - they're massive.)
>
> >
> > Also, I believe the following are bugs in JSDK 2.1:
> >
> > o RequestDispatcher.include throws an exception if the
> > ServletOutputStream has already been obtained. This is the
> > correct behaviour for forward but not for include.
>
> This is correct behavior on include as well, in some circumstances. If the
> original servlet has done a getWriter(), the included servlet will throw an
> exception if it calls getOutputStream(). LIkewise, if the original servlet
> has done a getOutputStream(), the included servlet cannot call getWriter().
>
> It only works if both the original servlet and the included servlet use the
> same technique (either output stream or writer).
This sounds like a bug to me. This is an unnecessary dependency between
what ought to be independent servlets. It means I can't include the
output of two different servlets if one happen to use
ServletOutputStream and other happen to use PrintWriter for its output.
I see no reason why the implementation can't take care of this. The
problem appears to be that PrintWriter does its own buffering through
BufferedWriter but this can be handled by the RequestDispatcher by
flushing a PrintWriter (if one has been retrieved) before and after
doing the include. This all comes down to implementation issues - I
don't think there are any inherent reason for this to be this way.
(Buffering may still be done at a lower level.)
--
Anders Kristensen <[EMAIL PROTECTED]>,
http://www-uk.hpl.hp.com/people/ak/
Hewlett-Packard Labs, Bristol, UK
___________________________________________________________________________
To unsubscribe, send email to [EMAIL PROTECTED] and include in the body
of the message "signoff SERVLET-INTEREST".
Archives: http://archives.java.sun.com/archives/servlet-interest.html
Resources: http://java.sun.com/products/servlet/external-resources.html
LISTSERV Help: http://www.lsoft.com/manuals/user/user.html