Properly load file packaged inside .war file
You should be using ServletContext#getResourceAsStream
which would load your files with designed path based on root level of war package:
InputStream inputStream = ctx.getResourceAsStream("/WEB-INF/rules/rules.fcl");
Then, it is up to you to use that stream and chain it to load your file content. It should be something like the follwoing if there a FIS#load
method that accept InputStream
as paramter:
boolean verbose = true; //Just choose your suitable value (verbose mode or not)
FIS fis = FIS.load(inputStream, verbose);
Just caught the method signature from this svn repo.
What does servletcontext.getRealPath(/) mean and when should I use it
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:
- getResourceAsStream() vs FileInputStream
- Recommended way to save uploaded files in a servlet application
- Simple ways to keep data on redeployment of Java EE 7 web application
ServletContext().getRealPath() returns path not ending with /
I Fixed the issue.
The issue was, I didn't put '/' before "resources".
ServletContext.getRealPath("")+"/resources"
getServletContext().getRealPath() doesn't work in controller (NPE), but works in jsp
I was missing this:
ServletContext servletContext = request.getSession().getServletContext();
now it works from controller.
ServletContext servletContext = request.getSession().getServletContext();
String relativeWebPath = "img/image.png";
String absoluteDiskPath = servletContext.getRealPath(relativeWebPath);
Loading a file image in a war project
Use
File file = getRequest().getServletContext().getRealPath("/img/logoCorporativo.jpg");
getRealPath convert a URL root relative path (using slashes "/") to a File.
If the war does not unpack itself on deployment, getRealPath returns null.
System.getProperty(mode) returns null
You have to load mode.properties first, like this way
private Properties mode=null;
mode = new Properties();
mode.load(new FileInputStream(pathtoMODE));
String mode = mode.getProperty("mode");
Related Topics
Why Do Constructors in Java Not Have a Return Type
What Is an Instance Variable in Java
Spring Choose Bean Implementation at Runtime
Java Array with More Than 4Gb Elements
Why String.Replaceall() in Java Requires 4 Slashes "\\\\" in Regex to Actually Replace "\"
Reading a Specific Line from a Text File in Java
Why Are Wait() and Notify() Declared in Java's Object Class
Accessing a File Inside a .Jar File
How to Modify the Raw Xml Message of an Outbound Cxf Request
How to Disable 'X-Frame-Options' Response Header in Spring Security
How to Represent a Range in Java