You are viewing a plain text version of this content. The canonical link for it is here.
Posted to general@jakarta.apache.org by Greg Wilkins <gr...@mortbay.com> on 1999/07/09 03:07:11 UTC
getResource() Was: Is everything a Servlet?
"Craig R. McClanahan" wrote:
[ ... Description of cool implementation of getResource in JSERV ...]
Wow - we have considered 3 actual implementations and come up
with 3 different interpretations of the spec! Any more...
Except that I think Craig's is a meta implementation of
those that James and I have been talking about and would
probably encompass any others. It is simple, it works
within the servlet API and uses other standard APIs
to extend the functionality.
But I would suggest an improvement by defining a null
resource base as a request to the current servletContext,
which may not need a URL connection to be made for
getResourceAsStream, where only a InputStream is returned.
Jetty's implementation of getResourceAsStream makes
a special request and response, where the HttpOutputStream
of the response is piped directly to the InputStream returned.
Thus no network connection is required and the only real
expense is waking up another thread from the thread pool.
When requesting file resources like this, they come straight
out of the memory cache of our file handler.
This is definitly the best of all worlds:
+ Configure it with "file://directory" and you get the behaviour
that James has described.
+ If tomcat is running in a separate process to your server,
a configuration of "http://myserver:myport" gives the
behaviour that makes sense to me.
+ If tomcat is running in the same process as the server, you can
leave it unconfigured and efficient local requests can be made
with the semantics that I like.
+ Configure some other way to access the "other resource" spaces
referred to in the spec.
I say nail this one into Tomcat as soon as the hood is open!
Have you defined an attribute of the ServletContext for this?
Something like "org.apache.jakarta.ServletContext.resourceBase"???
I think I feel a "com.mortbay.Jetty.ServletContext.resourceBase"
in the making soon - full credit of course!
--
Greg Wilkins<gr...@mortbay.com> GB Phone: +44-(0)171-4394045
Mort Bay Consulting Australia and UK. Mbl Phone: +44-(0)7775534369
http://www.mortbay.com AU Phone: +61-(0)299772395
Re: getResource() Was: Is everything a Servlet?
Posted by "Craig R. McClanahan" <cm...@mytownnet.com>.
James Duncan Davidson wrote:
> > If all resources are URLs, not Files, are you still able to efficiently
> > determine when an underlying resource changes? For instance, a change in a .jsp
> > source-file, or a recompiled servlet .class ...
>
> This is the part about "downcasting" (loose use of the term, but it's
> the right idea) to a file when needed. The first past through the code
> (unoptimized) was written with URLs. In the few cases where we needed
> the ability of files, and files are available (noted by the file: url
> type), then the second layer of more optimized code was added to do
> these sorts of things.
>
If you use getResource() instead of getResourceAsStream(), and open a URLConnection
of your own (and your underlying URLStreamHandler is smart if you've got a custom
one), you should be able to use things like URLConnection.getIfModifiedSince() and
URLConnection.getLastModified() to help you make this kind of decision.
If you're accessing resources from an web server that has authentication enabled,
you can even add the appropriate HTTP headers here, although this is obviously going
to be more application dependent.
Craig McClanahan
Re: getResource() Was: Is everything a Servlet?
Posted by James Duncan Davidson <du...@x180.com>.
> If all resources are URLs, not Files, are you still able to efficiently
> determine when an underlying resource changes? For instance, a change in a .jsp
> source-file, or a recompiled servlet .class ...
This is the part about "downcasting" (loose use of the term, but it's
the right idea) to a file when needed. The first past through the code
(unoptimized) was written with URLs. In the few cases where we needed
the ability of files, and files are available (noted by the file: url
type), then the second layer of more optimized code was added to do
these sorts of things.
So a more accurate statement is "Everything is treatead as a URL first
and foremost. In cases where needed, other mechanisms were added for
cases where possible."
It's the classic "write the application the way it should be written,
optimize second" routine.
--
James Davidson
<du...@eng.sun.com> http://java.sun.com/products/servlet
<du...@x180.com> http://www.x180.com
!try; do() PGP:0x7D776205
Re: getResource() Was: Is everything a Servlet?
Posted by Mike Williams <mi...@o3.co.uk>.
James Duncan Davidson wrote:
> Bingo... Cool trick too as I can set up 4 different servers with a URL
> of http://distribution/webserver1 -- the server sucks in (via
> getResource of course) http://distribution/webserver1/WEB-INF/web.xml,
> configures based on that, loads any servlet classes that aren't local
> from http://distribution/webserver/WEB-INF/classes, and is set up.
> Insta-mirroring. Add a generic caching mechanism on top of getResource
> and you've got a pretty effectient little system.
>
> Inside tomcat, *everything* is treated as a URL.
If all resources are URLs, not Files, are you still able to efficiently
determine when an underlying resource changes? For instance, a change in a .jsp
source-file, or a recompiled servlet .class ...
(Sorry for demonstrating my ignorance amongst such illustrious company ...)
cheers, Mike
Re: getResource() Was: Is everything a Servlet?
Posted by James Duncan Davidson <du...@x180.com>.
Jumping in at the tail of this -- I'll clean up a few points in the
other messages in a bit (theory being if I react to the tail of the
thread, it'll be saner than watching me go through the gyrations.. :)
(yes, I nuked out the attributions -- 1st level is Craig, 2nd level is
Greg, etc.)
> The JSWDK servlet engine (i.e. Tomcat) lets you specify the document base
> as either a directory or a URL, so it's pretty much following the same
> pattern.
Bingo... Cool trick too as I can set up 4 different servers with a URL
of http://distribution/webserver1 -- the server sucks in (via
getResource of course) http://distribution/webserver1/WEB-INF/web.xml,
configures based on that, loads any servlet classes that aren't local
from http://distribution/webserver/WEB-INF/classes, and is set up.
Insta-mirroring. Add a generic caching mechanism on top of getResource
and you've got a pretty effectient little system.
Inside tomcat, *everything* is treated as a URL. Only in cases where
it's handy to "cast" out to a file, say to create directory listings in
the defaultServlet, does it do so.
And, as Craig mentions further down, the way you get to content
elsewhere is to create a protocol handler. You can have myoracle://
protocols that use your handler to fish out content that maps to
/path/path/foo.html.
> > But I would suggest an improvement by defining a null
> > resource base as a request to the current servletContext,
> > which may not need a URL connection to be made for
> > getResourceAsStream, where only a InputStream is returned.
> ...
> You are still going to want to create a URL for your "optimized" access
> path, so that servlets who call getResource() instead of
> getResourceAsStream() still have access to the same resources.
To clarify, getResourceAsStream is a convience method. There shouldn't
be a way to get a stream without being able to get the URL as the URL is
the authoritative source for a particular path name.
> If you use a "file:..." or "war:" resource base (where "war:" maps to a
> URLStreamHandler that extracts elements from the web archive file you are
> running in, per my previous mail), there's no problem --
> getResourceAsStream("/menu.jsp") does the trick. The distinction James
> is making between resources (static) and servlets (dynamic) is key to
> this working.
Yes, this is a key distinction. One that I'll be clarifying in the 2.2
spec (I've got hte // XXX fix allready there).
> But if you use a "http:" resource base, there is a problem -- if the web
> server you are pointing at has JSP support installed, it's going to
> execute the JSP page and give you the results, instead of giving you the
> source code to the page. This would not be a Good Thing.
Right. When I played with the insta-mirror setup above, all mappings
were disabled on the distribution -- only defaultServelt was active
serving out content. This is what made it look just like a local .war
file or directory structure.
> There is no need for a servlet context attribute for this -- in fact
> there should not be one. How a servlet engine implements mapping of
> relative paths to absolute URLs is not the business of a servlet. It is
> purely a configuration setting of the engine itself, which is done in an
> engine-dependent fashion just like mapping a servlet name to its init
> parameters is.
Right. Web applications should be infinitly relocatable unless a
specific application domain issue demands otherwise (and that's the
application's business). This is why the abstraction for getResource was
made in the first place.
--
James Davidson
<du...@eng.sun.com> http://java.sun.com/products/servlet
<du...@x180.com> http://www.x180.com
!try; do() PGP:0x7D776205
Re: getResource() Was: Is everything a Servlet?
Posted by "Craig R. McClanahan" <cm...@mytownnet.com>.
Greg Wilkins wrote:
> "Craig R. McClanahan" wrote:
> [ ... Description of cool implementation of getResource in JSERV ...]
>
> Wow - we have considered 3 actual implementations and come up
> with 3 different interpretations of the spec! Any more...
>
Not quite three ...
The JSWDK servlet engine (i.e. Tomcat) lets you specify the document base
as either a directory or a URL, so it's pretty much following the same
pattern.
>
> Except that I think Craig's is a meta implementation of
> those that James and I have been talking about and would
> probably encompass any others. It is simple, it works
> within the servlet API and uses other standard APIs
> to extend the functionality.
>
> But I would suggest an improvement by defining a null
> resource base as a request to the current servletContext,
> which may not need a URL connection to be made for
> getResourceAsStream, where only a InputStream is returned.
>
I'm not quite sure what you mean by this. If there is no resource base
defined, then there is no valid interpretation of the "relative path"
argument to getResource() or getResourceAsStream() -- you have no idea
what the relative path is "relative" to. Perhaps showing you my
implementation of getResourceAsStream will make this clearer:
public InputStream getResourceAsStream(String path) {
URL url = getResource(path);
if (url == null)
return (null);
else
return (url.openStream());
}
(again with some error handling left out).
You are still going to want to create a URL for your "optimized" access
path, so that servlets who call getResource() instead of
getResourceAsStream() still have access to the same resources.
>
> Jetty's implementation of getResourceAsStream makes
> a special request and response, where the HttpOutputStream
> of the response is piped directly to the InputStream returned.
> Thus no network connection is required and the only real
> expense is waking up another thread from the thread pool.
> When requesting file resources like this, they come straight
> out of the memory cache of our file handler.
>
> This is definitly the best of all worlds:
>
> + Configure it with "file://directory" and you get the behaviour
> that James has described.
>
> + If tomcat is running in a separate process to your server,
> a configuration of "http://myserver:myport" gives the
> behaviour that makes sense to me.
>
> + If tomcat is running in the same process as the server, you can
> leave it unconfigured and efficient local requests can be made
> with the semantics that I like.
>
> + Configure some other way to access the "other resource" spaces
> referred to in the spec.
>
> I say nail this one into Tomcat as soon as the hood is open!
>
There is one key distinction that wasn't obvious to me until James did
his example scenario on reading the text of a JSP page versus the
interpreted result of executing the JSP page.
Let's say you are actually writing the JSP servlet. Identifying the
relative path of the JSP page being requested is no big deal -- you just
map the JSP servlet to the ".jsp" extension, and calling
request.getServletPath() gives you the exact relative path that you
need. For concreteness, let's assume that you asked for /menu.jsp.
Now, how does the JSP servlet itself go about reading the source code so
it can compile the page?
If you use a "file:..." or "war:" resource base (where "war:" maps to a
URLStreamHandler that extracts elements from the web archive file you are
running in, per my previous mail), there's no problem --
getResourceAsStream("/menu.jsp") does the trick. The distinction James
is making between resources (static) and servlets (dynamic) is key to
this working.
But if you use a "http:" resource base, there is a problem -- if the web
server you are pointing at has JSP support installed, it's going to
execute the JSP page and give you the results, instead of giving you the
source code to the page. This would not be a Good Thing.
I guess we're still OK as long as you make the restriction that the web
server you are pointing at has to treat resources as static, rather than
executable content. Otherwise, this particular scenario isn't going to
work -- but every other scenario still does fine.
>
> Have you defined an attribute of the ServletContext for this?
> Something like "org.apache.jakarta.ServletContext.resourceBase"???
>
There is no need for a servlet context attribute for this -- in fact
there should not be one. How a servlet engine implements mapping of
relative paths to absolute URLs is not the business of a servlet. It is
purely a configuration setting of the engine itself, which is done in an
engine-dependent fashion just like mapping a servlet name to its init
parameters is.
>
> I think I feel a "com.mortbay.Jetty.ServletContext.resourceBase"
> in the making soon - full credit of course!
>
> --
> Greg Wilkins<gr...@mortbay.com> GB Phone: +44-(0)171-4394045
> Mort Bay Consulting Australia and UK. Mbl Phone: +44-(0)7775534369
> http://www.mortbay.com AU Phone: +61-(0)299772395
>
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: general-unsubscribe@jakarta.apache.org
> For additional commands, e-mail: general-help@jakarta.apache.org