What does servletcontext.getRealPath("/") mean and when should I use it
Asked Answered
F

4

70

In the following snippet:

ServletContext context = request.getServletContext();
String path = context.getRealPath("/");

What does / in the method getRealPath() represent? When should I use it?

Francklin answered 28/8, 2012 at 13:46 Comment(2)
that is called as WebApplicationContext. e.g. You have application named as TestWebApp then / would give path till TestWebAppLorrianelorrie
It's the root of your web application.Voroshilovgrad
H
134

Introduction

The ServletContext#getRealPath() is intented to convert a web content path (the path in the expanded WAR folder structure on the server's disk file system) to an absolute disk file system path.

The "/" represents the web content root. I.e. it represents the web folder as in the below project structure:

YourWebProject
 |-- src
 |    :
 |
 |-- web
 |    |-- META-INF
 |    |    `-- MANIFEST.MF
 |    |-- WEB-INF
 |    |    `-- web.xml
 |    |-- index.jsp
 |    `-- login.jsp
 :    

So, passing the "/" to getRealPath() would return you the absolute disk file system path of the /web folder of the expanded WAR file of the project. Something like /path/to/server/work/folder/some.war/ which you should be able to further use in File or FileInputStream.

Note that most starters don't seem to see/realize that you can actually pass the whole web content path to it and that they often use

String absolutePathToIndexJSP = servletContext.getRealPath("/") + "index.jsp"; // Wrong!

or even

String absolutePathToIndexJSP = servletContext.getRealPath("") + "index.jsp"; // Wronger!

instead of

String absolutePathToIndexJSP = servletContext.getRealPath("/index.jsp"); // Right!

Don't ever write files in there

Also note that even though you can write new files into it using FileOutputStream, all changes (e.g. new files or edited files) will get lost whenever the WAR is redeployed; with the simple reason that all those changes are not contained in the original WAR file. So all starters who are attempting to save uploaded files in there are doing it wrong.

Moreover, getRealPath() will always return null or a completely unexpected path when the server isn't configured to expand the WAR file into the disk file system, but instead into e.g. memory as a virtual file system.

getRealPath() is unportable; you'd better never use it

Use getRealPath() carefully. There are actually no sensible real world use cases for it. Based on my 20 years of Java EE experience, there has always been another way which is much better and more portable than getRealPath().

If all you actually need is to get an InputStream of the web resource, better use ServletContext#getResourceAsStream() instead, this will work regardless of the way how the WAR is expanded. So, if you for example want an InputStream of index.jsp, then do not do:

InputStream input = new FileInputStream(servletContext.getRealPath("/index.jsp")); // Wrong!

But instead do:

InputStream input = servletContext.getResourceAsStream("/index.jsp"); // Right!

Or if you intend to obtain a list of all available web resource paths, use ServletContext#getResourcePaths() instead.

Set<String> resourcePaths = servletContext.getResourcePaths("/");

You can obtain an individual resource as URL via ServletContext#getResource(). This will return null when the resource does not exist.

URL resource = servletContext.getResource(path);

Or if you intend to save an uploaded file, or create a temporary file, then see the below "See also" links.

See also:

Haswell answered 28/8, 2012 at 13:56 Comment(10)
I was 100% sure @Haswell would answer this and answer is awesomely. Seriously, you're awesome.Annulate
@Haswell What would this give ServletConfig#getServletContext().getRealPath(".") ?Stepsister
@Haswell If my input and output files are in WEB-INF, how do I reference them using either getResourceAsStream or getResourcePaths?Brobdingnagian
@te7: just use getResourceAsStream("/WEB-INF/filename.ext") or getResourcePaths("/WEB-INF"). Key is to specify a webcontent-relative path starting with /.Haswell
@Haswell Info: getResourcePaths returns all the paths to each file in /WEB-INF in one string variable...not usable as far as I can tell. FYI. I haven't tried using getResourceAsStream yet because that would require a major overhaul of all my methods in my 2 working classes. I tried it on one method and the compiler can't seem to resolve the servletContext for it because the context is out of scope within the method. I think I'll have to pass the servletContext to it from the doPost method it is contained in. I'll post back if I get it working.Brobdingnagian
@Haswell For getResourceAsStream it wasn;t a scope problem, it was syntax. I had to use getServletContext().getResourceAsStream(path) where path = "/WEB-INF/inputfile.txt". But now I get a null pointer exception on that line when the method executes. Any ideas?Brobdingnagian
@Haswell I fixed the nullpointer. Since the servlet class that contains the "readnums" method never gets instanced by the server, it never gets a context. So I passed to that servlet's doPost method the Startup context that gets instanced by the server with "ServletContext context = getServletContext();". I passed "context" to the doPost method in the second class, and then onto the "readnums" method that uses getResourceAsStream, using that passed context: "InputStream input = context.getResourceAsStream(path);"Brobdingnagian
My original post with the pertinent code, where a comment by BalusC lead me here, is located at: stackoverflow.com/questions/31627559/…Brobdingnagian
@Haswell Can you comment on similar question stackoverflow.com/questions/36446968/…Hatley
@Haswell is right to use getServletContext().getRealPath("/") and append the specifc file to it. to avoid vulnerabilities problemUnsling
K
4

A web application's context path is the directory that contains the web application's WEB-INF directory. It can be thought of as the 'home' of the web app. Often, when writing web applications, it can be important to get the actual location of this directory in the file system, since this allows you to do things such as read from files or write to files.

This location can be obtained via the ServletContext object's getRealPath() method. This method can be passed a String parameter set to File.separator to get the path using the operating system's file separator ("/" for UNIX, "\" for Windows).

Kildare answered 28/8, 2012 at 13:51 Comment(0)
A
2

There is also a change between Java 7 and Java 8. Admittedly it involves the a deprecated call, but I had to add a "/" to get our program working! Here is the link discussing it Why does servletContext.getRealPath returns null on tomcat 8?

Apfelstadt answered 16/1, 2017 at 23:58 Comment(0)
M
-1

My Method:

protected void processRequest(HttpServletRequest request, HttpServletResponse response)
        throws ServletException, IOException {

    try {
        String path = request.getRealPath("/WEB-INF/conf.properties");
        Properties p = new Properties();
        p.load(new FileInputStream(path));

        String StringConexion=p.getProperty("StringConexion");
        String User=p.getProperty("User");
        String Password=p.getProperty("Password");
    }
    catch(Exception e){
        String msg = "Excepcion " + e;
    }
}
Moneyer answered 6/11, 2018 at 16:13 Comment(1)
While this code snippet may solve the problem, it doesn't explain why or how it answers the question. Please include an explanation for your code, as that really helps to improve the quality of your post. Remember that you are answering the question for readers in the future, and those people might not know the reasons for your code suggestion.Sundew

© 2022 - 2024 — McMap. All rights reserved.