You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@tomcat.apache.org by "Preston L. Bannister" <pr...@home.com> on 2000/03/17 17:23:54 UTC

ServletRequest.getRealPath() deprecated? (Was: Is request.getRealPath() broken?)

OK - maybe I'm confused, but I think I see a problem :).

HttpServletRequest.getRealPath() is described in the Servlet 2.2 spec.

ServletRequest.getRealPath() is the actual method in all versions that I can lay my hands on.  There is no getRealPath() in
HttpServletRequest (aside from through inheritance).

The Servlet 2.1 and 2.2 APIs (not the specs) tag ServletRequest.getRealPath() as deprecated.

In fact if I am writing a servlet that aims to run under an existing servlet engine, as well as under Tomcat, then there is no
equivalent to request.getRealPath() in the case described (below).  The context required to map a relative path to a real path is
the context of the request, not the context of the servlet.

This is in fact what is implemented by the other servlet engines with which I have tested.

What I propose is the following:

1.  Remove the deprecated tag from the ServletRequest.getRealPath().

2.  Update the servlet spec to associate getRealPath() with ServletRequest not HttpServletRequest.  (Of course *I* can't do this...
:).

3.  Fix the bug in Tomcat that causes ServletRequest.getRealPath() to return the incorrect result (below).

Opinions??

--
Preston L. Bannister
preston@home.com
http://members.home.com/preston
pbannister via Yahoo! Messenger


> -----Original Message-----
> From: Preston L. Bannister [mailto:preston@home.com]
> Sent: Wednesday, March 08, 2000 1:50 PM
> To: Tomcat Developers
> Subject: I request.getRealPath() broken?
>
>
> It looks to me like request.getRealPath() is broken.
>
> Added to conf/server,xml:
> ----
> <Context
> 	path="/Report.Web"
> 	docBase="e:/nsa/RWService/webroot/Report.Web"
> 	debug="0"
> 	reloadable="true"
> >
> </Context>
> ----
>
> In e:/nsa/RWService/webroot/Report.Web/WEB-INF/web.xml:
> ---
> <?xml version="1.0" encoding="ISO-8859-1"?>
>
> <!DOCTYPE web-app
>     PUBLIC "-//Sun Microsystems, Inc.//DTD Web Application 2.2//EN"
>     "http://java.sun.com/j2ee/dtds/web-app_2.2.dtd">
>
> <web-app>
>     <servlet>
>         <servlet-name>	ReportWebScreens		</servlet-name>
>         <servlet-class>	com.nsainc.ReportWeb.Screens	</servlet-class>
>     </servlet>
>     <servlet-mapping>
>         <servlet-name>	ReportWebScreens		</servlet-name>
>         <url-pattern>	*.rwsp				</url-pattern>
>     </servlet-mapping>
> </web-app>
> ---
>
> This works but the value returned from request.getRealPath()
> is not what I expected.
>
> I'm trying to use the scheme where the location of a "global"
> file is used to determine the base URI used by the customer
> for this particular instance of the application.
>
> Also I only want to use that part of the Servlet API that is
> backwards compatible to version 2.0.
>
> So given a request to:
>
> 	http://hostname/Report.Web/screens/home.rwsp
>
> The "global" file is called "site.properties" so the servlet checks:
>
> 	http://hostname/Report.Web/screens/site.properties
> 	http://hostname/Report.Web/site.properties
> 	http://hostname/site.properties
>
> At each step the servlet uses request.getRealPath() and I expect:
>
> 	E:\nsa\RWService\webroot\Report.Web\screens\site.properties
> 	E:\nsa\RWService\webroot\Report.Web\site.properties
>     D:\Jakarta\bin\jakarta-tomcat\webapps\ROOT\site.properties
>
> What I get is something different.
>
> ---
> request.getRequestURI() returns
> 	/Report.Web/screens/home.rwsp
>
> request.getRealPath("/Report.Web/screens/site.properties") returns
> 	"E:\nsa\RWService\webroot\Report.Web\Report.Web\screens\site.properties"
>
> request.getRealPath("/Report.Web/site.properties") returns
> 	"E:\nsa\RWService\webroot\Report.Web\Report.Web\site.properties"
>
> request.getRealPath("/site.properties") returns
> 	"E:\nsa\RWService\webroot\Report.Web\site.properties"
>
> FOUND site.properties!
> URLNAME : /
> SITEFILE: E:\nsa\RWService\webroot\Report.Web\site.properties
> ---
>
> I did not expect the doubling of Report.Web in the real path.
>
> Is there some reason we should *not* consider this a bug??


Re: PrintWriter.flush() a no-op?

Posted by Costin Manolache <Co...@eng.sun.com>.
Jason Hunter wrote:

> No response yet.  Going once, going twice...
>
> -jh-

It's a bug probably.  ( it got cut&pasted from
org.apache.tomcat.server.ServletOutputStream )

I think it's ok to fix it, I assumed it was just a fix for some writer
buffering problems & servlet buffering, but never had time to find
what was the original problem.

Costin

>
> Jason Hunter wrote:
> >
> > The code in BufferedServletOutputStream says this:
> >
> >     // If a servlet is using PrintWriter then this method is NO-OP.
> >     public void flush() throws IOException {
> >     if (this.usingWriter == false)
> >         reallyFlush();
> >     }
> >
> > Why would out.flush() be a no-op when using a PrintWriter?
> > I'd like to
> > make it a real flush so out.checkError() works again.
> >
> > -jh-
>
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: tomcat-dev-unsubscribe@jakarta.apache.org
> For additional commands, e-mail: tomcat-dev-help@jakarta.apache.org


Re: PrintWriter.flush() a no-op?

Posted by Jason Hunter <jh...@acm.org>.
No response yet.  Going once, going twice...

-jh-

Jason Hunter wrote:
> 
> The code in BufferedServletOutputStream says this:
> 
>     // If a servlet is using PrintWriter then this method is NO-OP.
>     public void flush() throws IOException {
>     if (this.usingWriter == false)
>         reallyFlush();
>     }
> 
> Why would out.flush() be a no-op when using a PrintWriter?  
> I'd like to
> make it a real flush so out.checkError() works again.
> 
> -jh-

PrintWriter.flush() a no-op?

Posted by Jason Hunter <jh...@acm.org>.
The code in BufferedServletOutputStream says this:

    // If a servlet is using PrintWriter then this method is NO-OP.
    public void flush() throws IOException {
    if (this.usingWriter == false)
        reallyFlush();
    }

Why would out.flush() be a no-op when using a PrintWriter?  I'd like to
make it a real flush so out.checkError() works again.

-jh-

RE: ServletRequest.getRealPath() deprecated? (Was: Is request.getRealPath() broken?)

Posted by co...@eng.sun.com.
> > OK, I must be missing this completely.  I don't see how getResource() or getResourceAsStream() gets me the same information.  Even
> > if it did, this would break backwards compatibility rather badly.
> > 
> > The resource that I am trying to locate is relative to the URI, not relative to the class.

If you just want to read the full content of a file - getResource() should
be good enough. In your case probably that's what you need.

You can't do random access ( for example if your resource is a zip file -
you'll not be able to extract a file and send it ). You can't change a
file - just read or write the full stream.

You can't access file attributes except ( probably ) size and last
modified ( which are available in the URL - most of the time not
implemented, even where the protocol allows that !! ). ( for example
lastModified for file URL doesn't work in many JDKs so getRealPath has to
be used to implement jsp reloading )

I don't like what happens, but it's a specification issue, and we can't
do anything but send feedback ( or find workarounds ). 


Costin



RE: ServletRequest.getRealPath() deprecated? (Was: Is request.getRealPath() broken?)

Posted by cm...@mytownnet.com.
See a couple of quick comments below.

On Fri, 17 Mar 2000, Preston L. Bannister wrote:

> > "Preston L. Bannister" wrote:
> > > The Servlet 2.1 and 2.2 APIs (not the specs) tag ServletRequest.getRealPath() as deprecated.
> 
> From: Craig R. McClanahan
> > And they also document the suggested replacement -- ServletContext.getRealPath().
> 
> In existing implementations getRealPath() in ServletRequest and ServletContext are *not* equivalent, nor should they be.  There is
> context associated with the request (as in the setup described in my original message) and not the servlet that is necessary to
> perform the getRealPath() mapping.
> 
> Now we could change the meaning of the ServletContext to somehow include the context of the request, but this breaks backwards
> compatibility without adding any value that I can see.
> 
> 
> > > In fact if I am writing a servlet that aims to run under an existing servlet engine, as well as under Tomcat, then there is no
> > > equivalent to request.getRealPath() in the case described (below).  The context required to map a relative path to a real path
> is
> > > the context of the request, not the context of the servlet.
> > >
> > > This is in fact what is implemented by the other servlet engines with which I have tested.
> > >
> > > What I propose is the following:
> > >
> > > 1.  Remove the deprecated tag from the ServletRequest.getRealPath().
> 
> > This would require a change to the servlet spec itself, not just to Tomcat ... it's not something that can be accomplished in this
> > forum.  It's also not the direction that things are moving (see below).
> 
> Understood (the part about the forum) though a pointer would be appreciated.  I don't spend *all* my time with servlets/Jakarta :).
> 
> Maybe I'm missing something, but I suspect the "direction" may need a little adjustment :).
> 
> 
> > > 3.  Fix the bug in Tomcat that causes ServletRequest.getRealPath() to return the incorrect result (below).
> 
> > The bug needs to be looked at anyway.
> 
> Agreed :)  This morning...
> 

I can't this morning, but next week certainly.

> 
> > > Opinions??
> 
> > The preferred approach in 2.1/2.2 based servlet engines is to use getResource() or getResourceAsStream() instead of
> > getRealPath() to
> > access local resources.  Now you are using context-relative URIs and you don't care whether or not your resources are
> > actually in an
> > operating system file that you can read -- the servlet container resolves all this stuff for you.
> 
> OK, I must be missing this completely.  I don't see how getResource() or getResourceAsStream() gets me the same information.  Even
> if it did, this would break backwards compatibility rather badly.
> 
> The resource that I am trying to locate is relative to the URI, not relative to the class.

But you have control over the path you pass to
ServletContext.getRealPath() or ServletContext.getResource() -- the same
solution applies to either.  Simply calculate your current path (based on
the value returned by getServletPath(), and then
append the stuff needed to get your resource file.

	String resourcePath =
	  request.getServletPath() + "/../myresources.properties";
	String pathname = getServletContext().getrealPath(resourcePath);
		... or ...
	InputStream is =
	  getServletContext().getResourceAsStream(resourcePath);

No need to un-deprecate something that was actually deprecated in 2.1.

Craig


RE: ServletRequest.getRealPath() deprecated? (Was: Is request.getRealPath() broken?)

Posted by "Preston L. Bannister" <pr...@home.com>.
> "Preston L. Bannister" wrote:
> > The Servlet 2.1 and 2.2 APIs (not the specs) tag ServletRequest.getRealPath() as deprecated.

From: Craig R. McClanahan
> And they also document the suggested replacement -- ServletContext.getRealPath().

In existing implementations getRealPath() in ServletRequest and ServletContext are *not* equivalent, nor should they be.  There is
context associated with the request (as in the setup described in my original message) and not the servlet that is necessary to
perform the getRealPath() mapping.

Now we could change the meaning of the ServletContext to somehow include the context of the request, but this breaks backwards
compatibility without adding any value that I can see.


> > In fact if I am writing a servlet that aims to run under an existing servlet engine, as well as under Tomcat, then there is no
> > equivalent to request.getRealPath() in the case described (below).  The context required to map a relative path to a real path
is
> > the context of the request, not the context of the servlet.
> >
> > This is in fact what is implemented by the other servlet engines with which I have tested.
> >
> > What I propose is the following:
> >
> > 1.  Remove the deprecated tag from the ServletRequest.getRealPath().

> This would require a change to the servlet spec itself, not just to Tomcat ... it's not something that can be accomplished in this
> forum.  It's also not the direction that things are moving (see below).

Understood (the part about the forum) though a pointer would be appreciated.  I don't spend *all* my time with servlets/Jakarta :).

Maybe I'm missing something, but I suspect the "direction" may need a little adjustment :).


> > 3.  Fix the bug in Tomcat that causes ServletRequest.getRealPath() to return the incorrect result (below).

> The bug needs to be looked at anyway.

Agreed :)  This morning...


> > Opinions??

> The preferred approach in 2.1/2.2 based servlet engines is to use getResource() or getResourceAsStream() instead of
> getRealPath() to
> access local resources.  Now you are using context-relative URIs and you don't care whether or not your resources are
> actually in an
> operating system file that you can read -- the servlet container resolves all this stuff for you.

OK, I must be missing this completely.  I don't see how getResource() or getResourceAsStream() gets me the same information.  Even
if it did, this would break backwards compatibility rather badly.

The resource that I am trying to locate is relative to the URI, not relative to the class.


Re: ServletRequest.getRealPath() deprecated? (Was: Is request.getRealPath() broken?)

Posted by "Craig R. McClanahan" <cm...@mytownnet.com>.
"Preston L. Bannister" wrote:

> OK - maybe I'm confused, but I think I see a problem :).
>
> HttpServletRequest.getRealPath() is described in the Servlet 2.2 spec.
>
> ServletRequest.getRealPath() is the actual method in all versions that I can lay my hands on.  There is no getRealPath() in
> HttpServletRequest (aside from through inheritance).
>

Which, of course, means that it is available through HttpServletRequest as well :-).

>
> The Servlet 2.1 and 2.2 APIs (not the specs) tag ServletRequest.getRealPath() as deprecated.
>

And they also document the suggested replacement -- ServletContext.getRealPath().

>
> In fact if I am writing a servlet that aims to run under an existing servlet engine, as well as under Tomcat, then there is no
> equivalent to request.getRealPath() in the case described (below).  The context required to map a relative path to a real path is
> the context of the request, not the context of the servlet.
>
> This is in fact what is implemented by the other servlet engines with which I have tested.
>
> What I propose is the following:
>
> 1.  Remove the deprecated tag from the ServletRequest.getRealPath().
>

This would require a change to the servlet spec itself, not just to Tomcat ... it's not something that can be accomplished in this
forum.  It's also not the direction that things are moving (see below).

>
> 2.  Update the servlet spec to associate getRealPath() with ServletRequest not HttpServletRequest.  (Of course *I* can't do this...
> :).
>
> 3.  Fix the bug in Tomcat that causes ServletRequest.getRealPath() to return the incorrect result (below).
>

The bug needs to be looked at anyway.

>
> Opinions??
>

The preferred approach in 2.1/2.2 based servlet engines is to use getResource() or getResourceAsStream() instead of getRealPath() to
access local resources.  Now you are using context-relative URIs and you don't care whether or not your resources are actually in an
operating system file that you can read -- the servlet container resolves all this stuff for you.

>
> --
> Preston L. Bannister

Craig McClanahan