use a URL object to read a resource in web content - java

Im working in a web application using JSF2 and in one of my forms I create a PDF file that contains a image and a specific font. The ressorces are located in the WebContent directory.
My problem is when I want to create the pdf File I want to read the ressources and pass it in parameters to the method creating PDF FILE. I dont know how to use the URL object or any other way to do the task.
Thanks.

The ressorces are located in the WebContent directory.
WebContent directory is just for development environment under eclipse. When deployed the files there would go into the root of the web-app. So I take it that you want to access files in the root of your web-app.
You can use ServletContext.getResource(String path) with a path as "/myFileName" where the / signifies the web-app context root.
To get the reference to the ServletContext you may try this

The URL class has an openStream() method which gives you an InputStream of the resource's content:
URL resource = externalContext.getResource("/image.png");
InputStream input = resource.openStream();
// ...
You can also immediately get the resource as stream without getting it as URL first:
InputStream input = externalContext.getResourceAsStream("/image.png");
// ...
Having the InputStream, you can just read it into whatever target object which your PDF creator is expecting as input.

Related

Instancing a java.io.File to read a resource from classpath

Supposing that I've a project structure as follows:
+ src
---+ main
------+ java
------+ resources
How can I define a java.io.File instance that is able to read an xml from resources folder?
It depends on what your program's working directory is.
You can get your working directory at runtime via System.getProperty("user.dir");
Here's a link with more info
Once you've got that, create a relative filepath pointing to your resource folder.
For example, if your working directory is src, create a relative filepath like so:
new File(Paths.get("main","resources").toString());
There are weaknesses with this approach as the actual filepath you use may change when you deploy your application, but it should get you through some simple development.
No, use an InputStream, with the path starting under resources.
InputStream in = getClass().getResourceAsStrem("/.../...");
Or an URL
URL url = getClass().getResource("/.../...");
This way, if the application is packed in a jar (case sensitive names!) it works too. The URL in that case is:
"jar:file://... .jar!/.../..."
If you need the resource as file, for instance to write to, you will need to copy the resource as initial template to some directory outside the application, like System.getProperty("user.home").
Path temp = Files.createTempFile("pref", "suffix.dat");
Files.copy(getClass().getResourceAsStream(...), temp, StandardCopyOption.REPLACE_EXISTING);
File file = temp.toFile();
As #mjaggard commented, createTempFile creates an empty file,
so Files.copy will normally fail unless with option REPLACE_EXISTING.

How can I access a css file located in my "src/main/resources" folder from my JSF controller at runtime

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")

open xsd file in web-inf/xsd

I want to open the xsd file in the web-inf/xsd/output.xsd
This is what I am trying to do
URL url = portletContext.getResource("WEB-INF/xsd/output.xsd");
getResource returns URL but in my case I am getting NullPointerException and I need to supply this to the newFile to open the file.
File newFile = new File("");
I am confused how to get this working.
UPDATE
Please bear with my english. I got this working. I have a question, I have another file *.xsl file which would be used to generate the PDF. I cannot delete this file after opening, what would be the effect on the JVM if a file is left open I mean >100 users trying to create the PDF i.e., *.xsl file will be opened 100 times, in future application is used heavily by the users, does the GC automatically clear all the file descriptors opened?
From the API doc of javax.portlet.PortletContext it describes that:
... The path must begin with a slash (/) and is interpreted as relative to the current context root (which usually is the WebContent or web directory of your web application)
This method allows the portlet container to make a resource available to portlets from any source. Resources can be located on a local or remote file system, in a database, or in a .war file.

How to create a java.io.File Object with URI?

Users can upload images on my website. My servlet needs to write the uploads into directory images of my webapp. For writing it onto the disk I need to create a File() object.
One way is that I can hardcode the complete path to something like
new File("/usr/tomcat/webapps/ROOT/images/file.jpg")
Is there a way so that I can specify something like new File("images/file.jpg").. Can I do it using new File (URI uri ) so that I do not have to hardcode the complete path. My servlet is located inside /usr/tomcat/webapps/ROOT/WEB-INF/classes/
The images folder is not a directory. It is actually a symbolic link which is pointing to another directory on the filesystem outside tomcat
Don't store images under your webapp deployment directory: next time you'll redeploy the app, you will lose all your images. And moreover, there is not always a directory for a webapp, since it's typically deployed as a war file.
Store your images in an external location, at an absolute path, and configure Tomcat or another web server to serve images from this location, or implement a servlet which serves images from this location.
See Image Upload and Display in JSP for additional pointers.
EDIT:
If your problem is the hard-coded absolute path in the Java code, use a System property that you set when starting Tomcat, or a context param in the web.xml, or use a properties file to store the path, or your database.
You can get the web app path from the ServletContext object. You get the ServletContext from the HttpServletRequest object (http://docs.oracle.com/javaee/6/api/javax/servlet/ServletRequest.html#getServletContext%28%29).
See http://docs.oracle.com/javaee/6/api/javax/servlet/ServletContext.html#getRealPath%28java.lang.String%29
Concatenate the "real path" to the desired image file path and provide this as the parameter to the File constructor.
try{
String directory = //Store it in your Property file and pick it
String filename= //Generate Dynamic name or any specific format
// Create file
FileWriter fstream = new FileWriter(directory+filename);
BufferedWriter out = new BufferedWriter(fstream);
out.write("your content"); }
catch (Exception e){
System.err.println("Error: " + e.getMessage()); }
finally {
//Close the output stream
out.close();
}
You Can keep the directory path in you property file if it is not changing frequently.
Directory name can be absolute path which may be a hardrive path or you can save it in your webapp also but it always advisable any input file keep it outside the webapp.
File naming is always up to you if you want to keep the same file name then need to handle duplicate check other wise specify some dynamic format and named it.

how to add a file to Java EE projects?

I want to add a xml file to my Java ee project and use it in my code but when I address the file from src directory it does not understand my address and search for file in bin directory of tomcat.
My project is using wicket framwork and JavaEE.
does any one know how to address the file or where should I place the file to access is from project?
If your xml file is a resource that must be accessed server-side only, then the best choice is to place it in the WEB-INF directory inside your war, or in some subdirectory inside the WEB-INF. This way you ensure the resource will not be accessible by the web.
Then you can retrieve it using ServletContext.getResource, as pointed out by Peter D.
For example, in a servlet you can retrieve it this way (exception handling omitted):
String path = "/WEB-INF/my.xml";
URL url = getServletConfig().getServletContext().getResource(path);
InputStream in = url.openStream();
// read content from input stream...
Inside your servlet you can:
this.getServletContext().getResource( path );
public java.net.URL getResource(java.lang.String path)
throws java.net.MalformedURLException
Returns a URL to the resource that is mapped to a specified path. The path must begin with a "/" and is interpreted as relative to the current context root.
This method allows the servlet container to make a resource available to servlets from any source. Resources can be located on a local or remote file system, in a database, or in a .war file.
The servlet container must implement the URL handlers and URLConnection objects that are necessary to access the resource.
This method returns null if no resource is mapped to the pathname.
Some containers may allow writing to the URL returned by this method using the methods of the URL class.
The resource content is returned directly, so be aware that requesting a .jsp page returns the JSP source code. Use a RequestDispatcher instead to include results of an execution.
This method has a different purpose than java.lang.Class.getResource, which looks up resources based on a class loader. This method does not use class loaders.
Normally src is not used at runtime. I don't use tomcat, but in my environment I have build tasks that copy non-Java files from src to the bin directory.
You may find it necessary to open the file by using the classloader getResourceAsStream() so that you are searching the same directories as your classes come from.
This assumes that you want to deliver the XML in the application. Alternatively you may prefer to have it somewhere else. URI resource references may help
Why don't you place the XML file in your resources directory. You can access it from any class with:
MyClass.class.getClassLoader().getResourceAsStream(filename);

Categories

Resources