Java - load file from web context - java

I can't figure out why fi.exists() returns false here. I can browse to the file via the browser at contextPath+"/images/default.png
String contextPath = req.getContextPath();
File fi = new File(contextPath+"/images/default.png");
exists = fi.exists();

I think you missunderstood what the context path is.
If you application is deployed on yourdomain.com/app, the context path will be /app.
It is used to tell the client where to look for resources.
When you do contextPath+"/images/default.png", you the path would be dependent of the deployment path (in this case it would be the file /app/images/default.png).
If you want the file next to the installation of your application server, you can use "images/default.png".
If you want to access resource files, you may want to try Thread.currentThread().getContextClassLoader().getResource("images/default.png") instead of files.
If you want to check if a context related resource exist, you can do it as stated here:
boolean exists=req.getServletContext().getResource("images/default.png")!=null;`
or
String path=req.getServletContext().getRealPath("images/default.png");`

Rather than getContextPath(), I needed to use getRealPath():
String path = req.getServletContext().getRealPath("/images/default.png");
File fi = new File(path);

Related

Path for creating a file in Tomcat

I created a website setting file in the xml format, and the content of this file specifies things like website title, url, meta description, admin email, etc.
In my Java code, I simply defined the file as following:
private static final String webSettingFileName = "WebSettings.xml";
public void saveSetting()
{
File settingFile = new File(webSettingFileName);
// try-catch block to write the XML file omitted
}
After I deploy the war file, I found out that the web Setting xml file was written to the Tomcat bin folder, however, I would like to write the file inside the ROOT folder of webapps in Tomcat. So I am wondering how to specify the file path in my code. Thanks
Edit:
As Jarrod Roberson gave me a red -1 for duplicate question. I disagree with him, because I had checked the post before making this post. I tried the method suggested in that post here, but it does not work for me, because I need to save the web settings file persistently in the same location no matter how many times Tomcat has restarted (so tomcat/webapps serves my purpose!). The file is for saving website settings. In addition, the ServletContext don't seem working in Java 1.8 that I am using for my webapp.
Edit 2:
This is how I finally made it work:
private final static File catalinaBase = new File(System.getProperty("catalina.base")).getAbsoluteFile();
private static final String webSettingFileName = "WebSetting.xml";
private final static File file = new File(catalinaBase, "webapps/" + webSettingFileName);
You can use the method ServletContext.getRealPath("/") to retrieve the absolute filesystem path of the current webapp, e.g.:
File settingFile = new File(getServletContext().getRealPath("/"), webSettingFileName);
Note that this will only work with an exploded (unzipped) war file.

how to reach a file in www directory from a servlet?

Using tomcat 6, i created a template inside www/templates/templatefile.html
how do I access it from a servlet ? i want to read the html file and parse it.
I tried getting the real path using request.getRealPath(request.getServletPath())
and from there to go to the templates directory but for some reason it still can't find the file.
Assuming that www is a folder in the public web content root, then you can use ServletContext#getRealPath() to convert a relative web path to an absolute disk file system path as follows:
String relativeWebPath = "/www/templates/templatefile.html";
String absoluteDiskPath = getServletContext().getRealPath(relativeWebPath);
File file = new File(absoluteDiskPath);
InputStream input = new FileInputStream(file);
// ...
Note that this won't work when the WAR is not expanded (Tomcat in default trim does it, but it can be configured not to do that). If all you want to end up is having an InputStream of it, then you'd rather like to use ServletContext#getResourceAsStream() instead.
String relativeWebPath = "/www/templates/templatefile.html";
InputStream input = getServletContext().getResourceAsStream(relativeWebPath);
// ...

Programmatically reading static resources from my java webapp [duplicate]

This question already has answers here:
How to find the working folder of a servlet based application in order to load resources
(3 answers)
Closed 6 years ago.
I currently have a bunch of images in my .war file like this.
WAR-ROOT
-WEB-INF
-IMAGES
-image1.jpg
-image2.jpg
-index.html
When I generate html via my servlets/jsp/etc I can simple link to
http://host/contextroot/IMAGES/image1.jpg
and
http://host/contextroot/IMAGES/image1.jpg
Not I am writing a servlet that needs to get a filesystem reference to these images (to render out a composite .pdf file in this case). Does anybody have a suggestion for how to get a filesystem reference to files placed in the war similar to how this is?
Is it perhaps a url I grab on servlet initialization? I could obviously have a properties file that explicitly points to the installed directory but I would like to avoid additional configs.
If you can guarantee that the WAR is expanded, then you can use ServletContext#getRealPath() to convert a relative web path to an absolute disk file system which you can further use in the usual Java IO stuff.
String relativeWebPath = "/IMAGES/image1.jpg";
String absoluteDiskPath = getServletContext().getRealPath(relativeWebPath);
File file = new File(absoluteDiskPath);
InputStream input = new FileInputStream(file);
// ...
However, if you can't guarantee that the WAR is expanded (i.e. all resources are still packaged inside WAR) and you're actually not interested on the absolute disk file system path and all you actually need is just an InputStream out of it, then use getServletContext().getResourceAsStream() instead.
String relativeWebPath = "/IMAGES/image1.jpg";
InputStream input = getServletContext().getResourceAsStream(relativeWebPath);
// ...
See also:
getResourceAsStream() vs FileInputStream
Use the getRealPath method of ServletContext.
Ex:
String path = getServletContext().getRealPath("WEB-INF/static/img/myfile.jpeg");
This is relatively straight forward you simply use the class loader to fetch the files from the class plath. :
InputStream is = YourServlet.class.getClassLoader().getResourceAsStream("IMAGES/img1.jpg");
There are a few other getResoruce classes that are worth looking at. Also you don't have to fetch the class loader through the class variable on your servlet. Any class that you happen to know has been loaded by the container should work .
If you know the relative location of the files you could ask the runtime about the exact location using
Thread.currentThread().getContextClassLoader().getResource(<relative-path>/<filename>)
This would give you an URL to the location where the specified image can be found. This URL can be used to read the specified file or you can split it to use the different parts of the URL for further processing.

How can I get real path for file in my WebContent folder?

I need to get real path for file in my WebContent directory, so that framework that I use can access that file. It only takes String file as attribute, so I need to get the real path to this file in WebContent directory.
I use Spring Framework, so solution should be possible to make in Spring.
If you need this in a servlet then use getServletContext().getRealPath("/filepathInContext")!
getServletContext().getRealPath("") - This way will not work if content is being made available from a .war archive. getServletContext() will be null.
In this case we can use another way to get real path. This is example of getting a path to a properties file C:/Program Files/Tomcat 6/webapps/myapp/WEB-INF/classes/somefile.properties:
// URL returned "/C:/Program%20Files/Tomcat%206.0/webapps/myapp/WEB-INF/classes/"
URL r = this.getClass().getResource("/");
// path decoded "/C:/Program Files/Tomcat 6.0/webapps/myapp/WEB-INF/classes/"
String decoded = URLDecoder.decode(r.getFile(), "UTF-8");
if (decoded.startsWith("/")) {
// path "C:/Program Files/Tomcat 6.0/webapps/myapp/WEB-INF/classes/"
decoded = decoded.replaceFirst("/", "");
}
File f = new File(decoded, "somefile.properties");
you must tell java to change the path from your pc into your java project so
if you use spring use :
#Autowired
ServletContext c;
String UPLOAD_FOLDEdR=c.getRealPath("/images");
but if you use servlets just use
String UPLOAD_FOLDEdR = ServletContext.getRealPath("/images");
so the path will be /webapp/images/ :)
In situations like these I tend to extract the content I need as a resource (MyClass.getClass().getResourceAsStream()), write it as a file to a temporary location and use this file for the other call.
This way I don't have to bother with content that is only contained in jars or is located somewhere depending on the web container I'm currently using.
Include the request as a parameter. Spring will then pass the request object when it calls the mapped method
#RequestMapping .....
public String myMethod(HttpServletRequest request) {
String realPath = request.getRealPath("/somefile.txt");
...
You could use the Spring Resource interface (and especially the ServletContextResource): http://static.springsource.org/spring/docs/current/javadoc-api/org/springframework/core/io/Resource.html
This approach uses the resource loader to get the absolute path to a file in your app, and then goes up a few folders to the app's root folder. No servlet context required! This should work if you have a "web.xml" in your WEB-INF folder. Note that you may want to consider using this solely for development, as this type of configuration is usually best stored externally from the app.
public String getAppPath()
{
java.net.URL r = this.getClass().getClassLoader().getResource("web.xml");
String filePath = r.getFile();
String result = new File(new File(new File(filePath).getParent()).getParent()).getParent();
if (! filePath.contains("WEB-INF"))
{
// Assume we need to add the "WebContent" folder if using Jetty.
result = FilenameUtils.concat(result, "WebContent");
}
return result;
}
my solve for: ..../webapps/mydir/ (..../webapps/ROOT/../mydir/)
String dir = request.getSession().getServletContext().getRealPath("/")+"/../mydir";
Files.createDirectories(Paths.get(dir));
try to use this when you want to use arff.txt in your development and production level too
String path=getServletContext().getRealPath("/WEB-INF/files/arff.txt");

How to load properties file in Google App Engine?

So I'm trying to add some ability to my project to allow user-defined properties in my deployment artifact - a simple key:value .properties file. I place the service.properties file in
war/WEB-INF/my-service.properties
And in my ServiceImpl.java constructor I have the following:
String propertiesFileName = "my-service.properties";
URL propertyURL = ClassLoader.getSystemResource(propertiesFileName);
URL propertyURL2 = this.getClass().getClassLoader().getResource(propertiesFileName);
URL propertyURL3 = this.getClass().getClassLoader().getResource( "WEB-INF/" + propertiesFileName);
URL propertyURL6 = this.getClass().getClassLoader().getResource(
"E:/Projects/eclipse-workspace/projectName/war/WEB-INF/" + propertiesFileName);
All instances of Property URL are null. I know I'm missing something absolutely obvious, but I need a second pair of eyes. Regards.
EDIT:
Ah, it seems I was confused as the default GAE project creates a logging.properties file in /war. From the Google App Engine documentation:
The App Engine Java SDK includes a template logging.properties file, in the appengine-java-sdk/config/user/ directory. To use it, copy the file to your WEB-INF/classes directory (or elsewhere in the WAR), then the system property java.util.logging.config.file to "WEB-INF/classes/logging.properties" (or whichever path you choose, relative to the application root). You can set system properties in the appengine-web.xml file, as follows:
Try putting the service.properties in WEB-INF/classes. Then it should be accessible just with :
this.getClass().getClassLoader().getResourceAsStream("/filename.properties");
As Mike mentioned in his comment to jsights answer, it worked for me if I used
this.getClass().getClassLoader().getResourceAsStream("filename.properties");
(removed the first slash) after placing the file in WEB-INF/classes.
I think what you will need is something like this:
String filePath = servletContext.getRealPath("/WEB-INF/views/") + "/" + mav.getViewName() + ".vm";
FileInputStream in = new FileInputStream(filePath);
I get the servletContext from spring: #Autowire ServletContext.

Categories

Resources