I am trying to generate a XML file and save it in /WEB-INF/pages/.
Below is my code which uses a relative path:
File folder = new File("src/main/webapp/WEB-INF/pages/");
StreamResult result = new StreamResult(new File(folder, fileName));
It's working fine when running as an application on my local machine (C:\Users\userName\Desktop\Source\MyProject\src\main\webapp\WEB-INF\pages\myFile.xml).
But when deploying and running on server machine, it throws the below exception:
javax.xml.transform.TransformerException:
java.io.FileNotFoundException
C:\project\eclipse-jee-luna-R-win32-x86_64\eclipse\src\main\webapp\WEB INF\pages\myFile.xml
I tried getServletContext().getRealPath() as well, but it's returning null on my server. Can someone help?
Never use relative local disk file system paths in a Java EE web application such as new File("filename.xml"). For an in depth explanation, see also getResourceAsStream() vs FileInputStream.
Never use getRealPath() with the purpose to obtain a location to write files. For an in depth explanation, see also What does servletcontext.getRealPath("/") mean and when should I use it.
Never write files to deploy folder anyway. For an in depth explanation, see also Recommended way to save uploaded files in a servlet application.
Always write them to an external folder on a predefined absolute path.
Either hardcoded:
File folder = new File("/absolute/path/to/web/files");
File result = new File(folder, "filename.xml");
// ...
Or configured in one of many ways:
File folder = new File(System.getProperty("xml.location"));
File result = new File(folder, "filename.xml");
// ...
Or making use of container-managed temp folder:
File folder = (File) getServletContext().getAttribute(ServletContext.TEMPDIR);
File result = new File(folder, "filename.xml");
// ...
Or making use of OS-managed temp folder:
File result = File.createTempFile("filename-", ".xml");
// ...
The alternative is to use a (embedded) database or a CDN host (e.g. S3).
See also:
Recommended way to save uploaded files in a servlet application
Where to place and how to read configuration resource files in servlet based application?
Simple ways to keep data on redeployment of Java EE 7 web application
Store PDF for a limited time on app server and make it available for download
What does servletcontext.getRealPath("/") mean and when should I use it
getResourceAsStream() vs FileInputStream
just use
File relpath = new File(".\pages\");
as application cursor in default stay into web-inf folder.
Related
Ok, Here is my Web project. I built it in eClipse with the following structure:
workspace3\MyProject\war\images\uploaded
workspace3\MyProject\war\WEB-INF\classes
Ok, I want to store the uploaded images into workspace3\MyProject\war\images\unloaded, so here is the code at service side & it works fine in Eclipse
String absolutePath = getClass().getProtectionDomain().getCodeSource().getLocation().getPath();
absolutePath=absolutePath.replace("WEB-INF/classes/", "images/uploaded");
File file = File.createTempFile("upload-", "."+extName, new File(absolutePath));
Ok, now I compiled my project & put it into VPS with Tomcat server and it has the following structure
tomcat7\webapps\ROOT\images\uploaded
tomcat7\webapps\ROOT\WEB-INF\classes
However, somehow when run the website via internet, it couldn't find the images\uploaded location.
Did i do anything wrong here?
Why getClass().getProtectionDomain().getCodeSource().getLocation().getPath() doesn't work in final product after compiled?
You should rather use ServletContext#getRealPath(...) to determine the file system path of your web application:
String absolutePath = request.getServletContext().getRealPath("/images/uploaded");
// File uploaded to this directory will be accessible via
// `http://<yourserver>/<web-app>/images/uploaded/`
But be careful! The servlet specification does not guarantee, that getRealPath will return a path to a writable directory. And it may return null in case the virtual path cannot be translated to a real path!
If you want to be sure, that the destination is a writable directory, and you just want to upload files into a temporary directory for processing, consider using the web application's private temp directory:
File tempDir = (File)request.getServletContext().getAttribute(ServletContext.TEMPDIR);
// Files uploaded to that directory will NOT be automatically published to WWW.
Note that this directory is temporary only and may not survive a server restart! So it is not thought for durable persistance.
The most sensible and durable solution is to write the file into a database, or any other repository (e.g. JCR like Jackrabbit), or into a file directory that is NOT controlled by your web server (and is specified from outside, e.g. via system property or in web.xml).
I need to be able to access my web application's css files, that are stored under src/main/resources/styles, from the backend java controller. I want to use them for creating PDF output with iText.
In other words, I want to do something like this:
CssFile cssFile1 = XMLWorkerHelper.getCSS(new FileInputStream("src/main/resources/styles/my.css"));
However, I'm clearly not going about this correctly, as I am receiving Exceptions like this:
java.io.FileNotFoundException: styles\standard.css (The system cannot find the path specified)
How can a retrieve these files in the controller?
I tried this, but it did not work, same error:
String rcp = econtext.getRequestContextPath();
CssFile cssFile1 = XMLWorkerHelper.getCSS(new FileInputStream(rcp + "src/main/resources/styles/my.css"));
The FileInputStream operates on the local disk file system and all relative paths are relative to the current working directory, which is the local disk file system folder which is been opened at exactly the moment the JVM is started. This is definitely not the root of src/main/resources folder.
Given that the /src/main/resources is recognizable as a Maven folder structure for root of classpath resources, then you just need to obtain it as classpath resource by ClassLoader#getResourceAsStream() instead.
InputStream input = getClass().getResourceAsStream("/styles/standard.css");
// ...
Or if the class is possibly packaged in a JAR loaded by a different classloader.
InputStream input = Thread.currentThread().getContextClassLoader().getResourceAsStream("styles/standard.css");
// ...
See also:
getResourceAsStream() vs FileInputStream
Thats because the JSF is a web app.
Now move the styles/my.css to WEB-INF/styles/my.css this ensures the files your accessing within the controller are part of the WebApp
and now you can access the resource using
XMLWorkerHelper.class.getResourceAsStream("styles/my.css")
I am doing the following,
String str = "this is the new string";
URL resourceUrl = getClass().getResource("path_to_resource");
File file = new File(resourceUrl.toURI());
BufferedWriter writer = new BufferedWriter(new FileWriter(file));
writer.write(xml);
writer.close();
In the above code I am trying to write to a resource file contained in one of my java packages. After executing the code, my program executes fine but the file just updates the properties file in web-INF and not into the package where it is stored. Can anyone please help me figure how can I achieve that or what am I doing wrong here? Thanks a lot.
You should not be trying to write to a file stored with your application classes. Depending on the application server, the location you are trying to write to may not be writable or the application may be running from an application archive (a .war file).
You should use an external folder to store configuration and other application data. Typically, you specify this folder via an environment variable or a property specified during deployment.
I am uploading an excel file to the tomcat server. Which is saving inside my eclipse directory D:\workspace_Eclipse\.metadata\.plugins\org.eclipse.wst.server.core\tmp1\wtpwebapps\StatusPortal\Job_doc\abc.xls
When ever i am accessing this file its giving me file not found Exception \Job_doc\abc.xls.
Its could not able to find the path which is i am giving while accessing the file like
\Job_doc\abc.xls
I am giving the path \Job_doc\abc.xls while accessing.
This is because you are using a relative path. Eclipse will use the current working directory to be a temp location for deploying the webapp. So the file is uploaded to the folder relative to this path (This happens when you start the app from eclipse Run On Server. Define your paths as static constants(May be you can use absolute paths for testing). After testing you can use the relative paths on production deployment.
Still, you can do alternate way. Dont use the integrated tomcat server of Eclipse. Use a standalone server, use the descriptor file to link the webapp in workspace to tomcat. After the save, just reload the app in tomcat manager and try.
Try reading your file using ClassLoader as below:
InputStream inputStream =
getClass().getClassLoader().getResourceAsStream("/Job_doc/abc.xls");
BufferedReader reader = new BufferedReader(new InputStreamReader(inputStream ));
If you want to get the File object, then try as below:
URI uri = getClass().getClassLoader().getResource("/Job_doc/abc.xls").toURI();
File file = new File(uri);
I have a J2EE app deployed as an EAR file, which in turn contains a JAR file for the business layer code (including some EJBs) and a WAR file for the web layer code. The EAR file is deployed to JBoss 3.2.5, which unpacks the EAR and WAR files, but not the JAR file (this is not the problem, it's just FYI).
One of the files within the JAR file is an MS Word template whose absolute path needs to be passed to some native MS Word code (using Jacob, FWIW).
The problem is that if I try to obtain the File like this (from within some code in the JAR file):
URL url = getClass().getResource("myTemplate.dot");
File file = new File(url.toURI()); // <= fails!
String absolutePath = file.getAbsolutePath();
// Pass the absolutePath to MS Word to be opened as a document
... then the java.io.File constructor throws the IllegalArgumentException "URI is not hierarchical". The URL and URI both have the same toString() output, namely:
jar:file:/G:/jboss/myapp/jboss/server/default/tmp/deploy/tmp29269myapp.ear-contents/myapp.jar!/my/package/myTemplate.dot
This much of the path is valid on the file system, but the rest is not (being internal to the JAR file):
G:/jboss/myapp/jboss/server/default/tmp/deploy/tmp29269myapp.ear-contents
What's the easiest way of getting the absolute path to this file?
My current solution is to copy the file to the server's temporary directory, then use the absolute path of the copy:
File tempDir = new File(System.getProperty("java.io.tmpdir"));
File temporaryFile = new File(tempDir, "templateCopy.dot");
InputStream templateStream = getClass().getResourceAsStream("myTemplate.dot");
IOUtils.copy(templateStream, new FileOutputStream(temporaryFile));
String absolutePath = temporaryFile.getAbsolutePath();
I'd prefer a solution that doesn't involve copying the file.
Unless the code or application you are passing the URI String to accepts a format that specifies a location within a jar/zip file, your solution of copying the file to a temporary location is probably the best one.
If these files are referenced often, you may want to cache the locations of the extract files and just verify their existance each time they are needed.
You should copy the contents to a temporary file (potentially with a cache), because trying to get to internal files of the application container is a dependency you want to avoid. There may not even be an extracted file at all (it can load from the JAR directly).