Where to put file resources in Dynamic Web Project Tomcat? [duplicate] - java

I've got a file in my war/WEB-INF folder of my app engine project. I read in the FAQs that you can read a file from there in a servlet context. I don't know how to form the path to the resource though:
/war/WEB-INF/test/foo.txt
How would I construct my path to that resource to use with File(), just as it looks above?
Thanks

There's a couple ways of doing this. As long as the WAR file is expanded (a set of files instead of one .war file), you can use this API:
ServletContext context = getContext();
String fullPath = context.getRealPath("/WEB-INF/test/foo.txt");
http://tomcat.apache.org/tomcat-5.5-doc/servletapi/javax/servlet/ServletContext.html#getRealPath(java.lang.String)
That will get you the full system path to the resource you are looking for. However, that won't work if the Servlet Container never expands the WAR file (like Tomcat). What will work is using the ServletContext's getResource methods.
ServletContext context = getContext();
URL resourceUrl = context.getResource("/WEB-INF/test/foo.txt");
or alternatively if you just want the input stream:
InputStream resourceContent = context.getResourceAsStream("/WEB-INF/test/foo.txt");
http://tomcat.apache.org/tomcat-5.5-doc/servletapi/javax/servlet/ServletContext.html#getResource(java.lang.String)
The latter approach will work no matter what Servlet Container you use and where the application is installed. The former approach will only work if the WAR file is unzipped before deployment.
EDIT:
The getContext() method is obviously something you would have to implement. JSP pages make it available as the context field. In a servlet you get it from your ServletConfig which is passed into the servlet's init() method. If you store it at that time, you can get your ServletContext any time you want after that.

Now with Java EE 7 you can find the resource more easily with
InputStream resource = getServletContext().getResourceAsStream("/WEB-INF/my.json");
https://docs.oracle.com/javaee/7/api/javax/servlet/GenericServlet.html#getServletContext--

I know this is late, but this is how I normally do it,
ClassLoader classLoader = Thread.currentThread().getContextClassLoader();
InputStream stream = classLoader.getResourceAsStream("../test/foo.txt");

Related

Java EE web-application file creation

I'm developing a web application in java to control my stock and do some other things. I upload files through a JSF component. This files are images. Anyway, my question is, I want these images to be stored in the web application's resource folder. More specifically in a subfolder named "userUploads". I create a File object but how do I a get a String representing that path?
If you want your files to be stored in your "web application's resource folder" I'm guessing you mean a folder called 'resources' inside the 'webroot'. While this is not really the best approach, you can achieve this by using the ServletContext:
ServletContext sc = httpRequest.getSession().getServletContext();
String path = sc.getPath("resources");
or
File file = new File(sc.getPath("resources"))
Personally, I'd recommend creating your 'uploads' folder outside of your web app's directory, so that it is not replaced during deployment etc.
"I create a File object but how do I a get a String representing that path?"
If you have a File object, you can call myFile.getAbsolutePath() to get a string representation of the path.
Do the following:
Get the HttpSession from the HttpServletRequest.
Get the ServletContext from the HttpSession.
Get the absolute path to your installation using the ServletContext.getRealPath() method. The parameter to this method is a path that is relative to your context root.
Here is a link: ServletContext

File path to resource in our war/WEB-INF folder?

I've got a file in my war/WEB-INF folder of my app engine project. I read in the FAQs that you can read a file from there in a servlet context. I don't know how to form the path to the resource though:
/war/WEB-INF/test/foo.txt
How would I construct my path to that resource to use with File(), just as it looks above?
Thanks
There's a couple ways of doing this. As long as the WAR file is expanded (a set of files instead of one .war file), you can use this API:
ServletContext context = getContext();
String fullPath = context.getRealPath("/WEB-INF/test/foo.txt");
http://tomcat.apache.org/tomcat-5.5-doc/servletapi/javax/servlet/ServletContext.html#getRealPath(java.lang.String)
That will get you the full system path to the resource you are looking for. However, that won't work if the Servlet Container never expands the WAR file (like Tomcat). What will work is using the ServletContext's getResource methods.
ServletContext context = getContext();
URL resourceUrl = context.getResource("/WEB-INF/test/foo.txt");
or alternatively if you just want the input stream:
InputStream resourceContent = context.getResourceAsStream("/WEB-INF/test/foo.txt");
http://tomcat.apache.org/tomcat-5.5-doc/servletapi/javax/servlet/ServletContext.html#getResource(java.lang.String)
The latter approach will work no matter what Servlet Container you use and where the application is installed. The former approach will only work if the WAR file is unzipped before deployment.
EDIT:
The getContext() method is obviously something you would have to implement. JSP pages make it available as the context field. In a servlet you get it from your ServletConfig which is passed into the servlet's init() method. If you store it at that time, you can get your ServletContext any time you want after that.
Now with Java EE 7 you can find the resource more easily with
InputStream resource = getServletContext().getResourceAsStream("/WEB-INF/my.json");
https://docs.oracle.com/javaee/7/api/javax/servlet/GenericServlet.html#getServletContext--
I know this is late, but this is how I normally do it,
ClassLoader classLoader = Thread.currentThread().getContextClassLoader();
InputStream stream = classLoader.getResourceAsStream("../test/foo.txt");

Create a file and store in Java web application folder

I would like to create an xml file and store in a folder within my spring Mvc web application.
I can get the root of my application with request.getContextPath()
but
how do i get the application's relative path so it will work on any machine indipendently by the location of the application's folder?
Like C:/folder/folder/MYAPPLICATIONROOTFOLDER
You want to do this.
First, you need to get the ServletContext. I don't know how this is done in Spring MVC, but it's there somewhere.
Then you can do:
ServletContext ctx = getServletContextFromSpringSomehow();
String path = ctx.getRealPath("/folder/filename.txt");
FileWriter fw = new FileWriter(path);
The key here is ServletContext.getRealPath. It gives you the local file system path of a resource from within your webapp. Observer that you use "/" here, as it's a URL, not a file name. The container will give you a valid file name in return. Note, this only works if your container explodes your WAR, or you deploy an exploded WAR. If the WAR is NOT exploded, you will get a null back from the container.
Also note, this WILL work for non-existent files. The container does not check for the actual existence of the file. But it will be up to you to actually create any missing intermediate directories, etc.
Finally, of course, that even if you get a file path back, doesn't mean you can actually write to that path. That's a OS permission issue outside of the scope of the container.
One solution is to bundle the XML with the clases in the JAR/WAR and then use the getResourceAsStream() to leverage the ClassLoader to locate the file.
If I put the file foo.xml with the classes in com/stackoverflow/example, I could then locate the resources from objects in that bundle with
InputStream is = MyClass.getResourceAsStream( "com/stackoverflow/example" );
and from here process the file with a XML parser or whatever else you wanted to do to read the file.

getResourceAsStream() is always returning null [duplicate]

This question already has answers here:
Where to place and how to read configuration resource files in servlet based application?
(6 answers)
Closed 6 years ago.
I have the following structure in a Java Web Application:
TheProject
-- [Web Pages]
-- -- [WEB-INF]
-- -- -- abc.txt
-- -- index.jsp
-- [Source Packages]
-- -- [wservices]
-- -- -- WS.java
In WS.java, I am using the following code in a Web Method:
InputStream fstream = this.getClass().getResourceAsStream("abc.txt");
But it is always returning a null. I need to read from that file, and I read that if you put the files in WEB-INF, you can access them with getResourceAsStream, yet the method is always returning a null.
Any ideas of what I may be doing wrong?
Btw, the strange thing is that this was working, but after I performed a Clean and Build on the Project, it suddenly stopped working :/
To my knowledge the file has to be right in the folder where the 'this' class resides, i.e. not in WEB-INF/classes but nested even deeper (unless you write in a default package):
net/domain/pkg1/MyClass.java
net/domain/pkg1/abc.txt
Putting the file in to your java sources should work, compiler copies that file together with class files.
A call to Class#getResourceAsStream(String) delegates to the class loader and the resource is searched in the class path. In other words, you current code won't work and you should put abc.txt in WEB-INF/classes, or in WEB-INF/lib if packaged in a jar file.
Or use ServletContext.getResourceAsStream(String) which allows servlet containers to make a resource available to a servlet from any location, without using a class loader. So use this from a Servlet:
this.getServletContext().getResourceAsStream("/WEB-INF/abc.txt") ;
But is there a way I can call getServletContext from my Web Service?
If you are using JAX-WS, then you can get a WebServiceContext injected:
#Resource
private WebServiceContext wsContext;
And then get the ServletContext from it:
ServletContext sContext= wsContext.getMessageContext()
.get(MessageContext.SERVLET_CONTEXT));
Instead of
InputStream fstream = this.getClass().getResourceAsStream("abc.txt");
use
InputStream fstream = this.getClass().getClassLoader().getResourceAsStream("abc.txt");
In this way it will look from the root, not from the path of the current invoking class
I think this way you can get the file from "anywhere" (including server locations) and you do not need to care about where to put it.
It's usually a bad practice having to care about such things.
Thread.currentThread().getContextClassLoader().getResourceAsStream("abc.properties");
I don't know if this applies to JAX-WS, but for JAX-RS I was able to access a file by injecting a ServletContext and then calling getResourceAsStream() on it:
#Context ServletContext servletContext;
...
InputStream is = servletContext.getResourceAsStream("/WEB-INF/test_model.js");
Note that, at least in GlassFish 3.1, the path had to be absolute, i.e., start with slash. More here: How do I use a properties file with jax-rs?
I had the same problem when I changed from Websphere 8.5 to WebSphere Liberty.
I utilized FileInputStream instead of getResourceAsStream(), because for some reason WebSphere Liberty can't locate the file in the WEB-INF folder.
The script was :
FileInputStream fis = new FileInputStream(getServletContext().getRealPath("/")
+ "\WEBINF\properties\myProperties.properties")
Note:
I used this script only for development.
I had a similar problem and I searched for the solution for quite a while:
It appears that the string parameter is case sensitive. So if your filename is abc.TXT but you search for abc.txt, eclipse will find it - the executable JAR file won't.

How can I get the filename of a servlet resource?

I'm writing a java servlet that calls a function in a jar. I have no control over the code in this jar. The function being called wants the filename of a configuration file as an argument.
I'd like to bundle this file with my war file. If I put it in the war somewhere, what filename can I pass the function in the jar?
Note that only a filename can be used with the jar's API. So ServletContext.getResourceAsStream() is not helpful.
Use ServletContext.getRealPath(). This returns the filesystem path for a given servlet context resource. You pass it the same argument as you would pass to ServletContext.getResourceAsStream()
Better yet, use Spring's Resource abstraction:
Resource resource = new ServletContextResource(servletContext, "/path/to/file");
File resourceFile = resource.getFile();
If it's in your .war file, you won't be able to access it as a file. Some servlet containers will explode a .war file into components, but I don't think you can rely on it.
Have you thought about extracting it (via getResourceAsStream()), writing it to a temp file/directory, and then referencing that ?

Categories