Using my company's chosen cloud storage api and just starting out with JSF 2.2. Trying to build a simple image upload web app and it works when I run locally using Eclipse.
Here's the code:
.xhtml page
<h:form id="form" enctype="multipart/form-data" prependId="false">
Select id Photo: <h:inputFile id="file" value="#{customerEntity.uploadedFile}"/>
<h:commandButton value="Query Cloud"
action="#{customerEntity.addActionController}"/>
</h:form>
customerEntity.java code:
private Part uploadedFile;
private String fileURI;
On local machine, code to extract file name from Part object uploadedFile produces correct file locator (eg. c:\pictures\mypix.jpg) for local access on my machine.
However, when I load into tomcat 7 running in a cloud vm, the application fails with a FileNotFound in the 'try' block:
File source = new File(this.fileURI);
try {
cloud.upload(new FileInputStream(source), source.length());
My debug statements show it's using the file locator from my local pc which clearly doesn't exist on the server. I can't figure out how to get the local file data streamed to the code running on the server.
As a slight jsf newbie, I'm sure it's something obvious, but can't figure it out or resolve via some of the other posts I've seen.
Any guidance would be greatly appreciated!
You're making a rather major conceptual mistake. You should not be interested in the client-specified path/name of the uploaded file. Instead, you should be interested in the content of the uploaded file. And well due to 2 main reasons:
The path to the file will be totally absent when you're using a webbrowser which doesn't expose a security bug that the full client side path is included in the name of the uploaded file (i.e. any browser other than Internet Explorer).
Using new File() on the client-specified path/name would only work if both the webbrowser (which is been used to send the file) and the webserver (which is been used to retrieve the file) runs at physically the same machine, because they have then access to exactly the same local disk file system structure. This doesn't occur in real world.
In order to save the content of the uploaded file in the desired location, do so:
uploadedFile.write("/path/to/uploads/somefilename.ext");
Note: you need to make sure that the somefilename.ext part is unique in its folder. You can if necessary make use of File#createTempFile() to autogenerate an unique filename in the given folder based on filename prefix and suffix.
File file = File.createTempFile("somefilename-", ".ext", new File("/path/to/uploads"));
uploadedFile.write(file.getAbsolutePath());
See also:
Recommended way to save uploaded files in a servlet application
Related
I'm using play framework 2.1.0, upload files to play-app/upload folder.
then I run play 'start -Dhttp.port=80' to start server.
but when I upload a file to play-app/upload folder, it can not be access immediately.
if I stop the server and start again, then I can access the file.
How can I solve this problem? Thanks a lot.
ps, I route /upload as below:
GET /upload/*file controllers.Assets.at(path="/upload", file)
Could it be that static files are loaded once? How can I solve it?
Preferably create upload folder outside the application's folder and add it's full path like /home/navins/upload-folder/ in application.conf, then you'll be able to access it whole time, also you will be able to upload files there not only with app (ie, by FTP) without need of restarting.
I think what you need is to define a sort of Remote assets controller. Basically, once a file is uploaded, you put it in a folder that is outside your application's folder. Then, use a controller that will let you access it. Here is an example: http://www.jamesward.com/2012/08/08/edge-caching-with-play2-heroku-cloudfront
Here, James Ward creates a controller to access assets that are stored on cloudfront, what you need to do is to write a similar controller and replace the "content url" with the absolute path to your "Uploaded files directory".
finally what I've solve it by adding access method in controller:
public static Result view(String filename) {
File file = new File(Play.application().path().getAbsolutePath() + "/upload/" + filename);
return ok(file);
}
then, change route conf, you can access the files by the method.
BTW, if you are using play framework below 2.0, you may user:
renderBinary(file, ContentType);
My site transforms an XML to HTML pages. Inside "Web Pages" folder I've create a folder "acces" that will contain the generated HTML pages and the images used inside. The generating process works, it places the files HTML and jpg, in the corect format in the folder acces. I can acces them from my local disk. When I try to acces the jpg at localhost:8080/myapp/acces/img/Image1.jpg, it works, but when I access localhost:8080/myapp/acces/img/someHtml.html it returns error 404.
If I open the file, from that folder, with that specific name: someHtml.html directly with a browser, it works.
What should I do to make the page become visible. I want to use it inside an HTML iframe.
I think what might be happening in your situation is that your Glassfish is likely deploying your application in a WAR archive, and what happens is your application might be writing to where your code is contained (wherever your workspace might be) so it won't be accessible from the application which is currently running off the WAR file you previously generated. Glassfish has likely already loaded up your application from the WAR file into memory and won't see the new files you've created until you rebuild and redeploy
What you might need to do is write it to some folder, and perhaps have a servlet that will retrieve the file and send it to client. That to me isn't the most elegant solution, you could just use a HTTP Server in front of the glassfish (apache or nginx or whatever) read the generated HTML file
Solved!
In my case I joust corrected:
<form action="mServlet" method="post">
<input type="text" name="variable1"/>
<input type="text" name="variable2"/>
<input type="submit" name="btnBoton"/>
</form>
It was misspeled:
miServlet --> mServlet
i want to know how to create a folder in webserver(tomcat 7.0) in java.
iam recently start one project.In that project i need to upload files into server from the client machine.In this each client has his own folder in server and upload the files into them.
And in each user folder we have more than two jsp files.when user request the server to show their content by an url (eg:ipaddress:portnumber/userid/index.jsp) using that files i want to show his uploaded data.
is it possible.?
please,guide me to solve this problem.
thanks.
As to your concrete question, just the same way as in a normal Java application.
File root = new File("/path/to/all/uploads");
File newfolder = new File(root, "/userid");
newfolder.mkdir();
// ...
As to your idea with those copypasted JSP files over all folders, don't do that. Just have a single servlet which is mapped on for example /files/* and reads the folder specific to the currently logged-in user and finally forwards to the JSP to present the results. Or if your intent is really to make the uploads public to everyone so that each user can see each other's uploads, then supply the desired user ID as parameter or pathinfo in the request URL like so http://localhost:8080/context/files/userid.
Please note that you shouldn't store the files in the expanded WAR folder, or they will get lost everytime you redeploy the webapp. Store them on a fixed path outside Tomcat's /webapps folder.
You access files and folders from a web application just like any other Java application: using java.io.File or maybe JDK7's new File I/O mechanism. See also the Java I/O Tutorial and the File-related utilities of Apache Commons IO.
Ok, here we go.
try {
File f = new File("file/path/name/.ext");
if(!f.isDirectory()) {
boolean success = (new File(f)).mkdirs();
}
if(success) {
System.out.println("Success")
}
} catch(Exception e) {}
That's it. I hope that functionally. Ciao
In my web application one of my pages is uploading a photo to the path
/usr/local/rac/picture-name-goes-here
The photo is uploading fine, but I need to access it in another page and when I try to access it from my JSP, it will not show up, I am guessing my path to the photo is incorrect
The code in my JSP to access the photo looks like the following.
<tr>
<td>
<img src="/usr/local/agent/photo-name-here.jpg"/>
</td>
</tr>
Am I incorrect with this path to the photo?
If it helps, I am running my web application from Tomcat which is in the directory
C:\Tomcat6
I will eventually be moving this over to a linux machine and expect to share the same path to the photo.
There is one major misconception here. HTML is executed by the webbrowser, not by the webserver. The webbrowser downloads HTML, scans for any resources which needs to be downloaded as well (CSS, scripts, images, etc) and fires a new HTTP request for each of them. All resources should point to a valid URL, not to some local disk file system path which the client machine has no notion of.
There are basically two ways to solve this "problem":
Add a new Context to Tomcat's /conf/server.xml:
<Context docBase="/usr/local/agent" path="/images" />
This way they'll be accessible through http://example.com/images/... and you'll be able to use the following <img>
<img src="/images/photo-name-here.jpg"/>
Create a Servlet which basically gets an InputStream of the image and writes it to the OutputStream of the response along a correct set of headers. You can find here a basic example of such a servlet and here a more advanced example. When the Servlet is mapped on /images/* in web.xml, the images are accessible by http://example.com/contextname/images/... and you'll be able to use it as follows (assuming that the JSP/HTML file is located in the context root):
<img src="images/photo-name-here.jpg"/>
src="/usr/local/agent/photo-name-here.jpg" <- this URL is a local address in your server, to show up your images you have to set a valid HTTP address like:
http://www.yourdomain.com/images/photo-name-here.jpg
To accomplish that you will need to upload the foto to a localpath that is inside in your www root folder.
If your webapp is installed in
/home/apache/www/website/
you will upload your images to a folder like:
/home/apache/www/website/images/
and then your HTTP address will be
http://www.yourdomain.com/images/photo-name-here.jpg
I got a little confuse with your two paths in /usr/ and C:\Tomcat
I encourage you to put the upload localpath folder parametrized, so you will be only modifying the config file instead of every function or method that access to that local path.
I have developed a Java EE web application. This application allows a user to upload a file with the help of a browser. Once the user has uploaded his file, this application first stores the uploaded file on the server (on which it is running) and then processes it.
At present, I am storing the file on the server as follows:
try {
// formFile represents the uploaded file
FormFile formFile = programForm.getTheFile();
String path = getServlet().getServletContext().getRealPath("") + "/"
+ formFile.getFileName();
System.out.println(path);
file = new File(path);
outputStream = new FileOutputStream(file);
outputStream.write(formFile.getFileData());
}
where, the formFile represents the uploaded file.
Now, the problem is that it is running fine on some servers but on some servers the getServlet().getServletContext().getRealPath("") is returning null so the final path that I am getting is null/filename and the file doesn't store on the server.
When I checked the API for ServletContext.getRealPath() method, I found the following:
public java.lang.String getRealPath(java.lang.String path)
Returns a String containing the real path for a given virtual path. For example, the path "/index.html" returns the absolute file path on the server's filesystem would be served by a request for "http://host/contextPath/index.html", where contextPath is the context path of this ServletContext.
The real path returned will be in a form appropriate to the computer and operating system on which the servlet container is running, including the proper path separators. This method returns null if the servlet container cannot translate the virtual path to a real path for any reason (such as when the content is being made available from a .war archive).
So, Is there any other way by which I can store files on those servers also which is returning null for getServlet().getServletContext().getRealPath("")
By spec, the only "real" path you are guaranteed to get form a servlet container is a temp directory.
You can get that via the ServletContext.gerAttribute("javax.servlet.context.tempdir"). However, these files are not visible to the web context (i.e. you can not publish a simple URL to deliver those files), and the files are not guaranteed in any way to survive a web app or server restart.
If you simply need a place to store a working file for a short time, then this will work fine for you.
If you really need a directory, you can make it a configuration parameter (either an environment variable, a Java property (i.e. java -Dyour.file.here=/tmp/files ...), a context parameter set in the web.xml, a configuration parameter stored in your database via a web form, etc.). Then it's up to the deployer to set up this directory for you.
However, if you need to actually later serve up that file, you will either need a container specific mechanism to "mount" external directories in to your web app (Glassfish as "alternate doc roots", others have similar concepts), or you will need to write a servlet/filter to serve up file store outside of your web app. This FileServlet is quite complete, and as you can see, creating your own, while not difficult, isn't trivial to do it right.
Edit:
The basic gist is the same, but rather than using "getRealPath", simply use "getInitParameter".
So:
String filePath = getServletContext().getInitParameter("storedFilePath") + "/" + fileName;
And be on your way.
Edit again:
As for the contents of the path, I'd give it an absolute path. Otherwise, you would need to KNOW where the app server sets its default path to during exeuction, and each app server may well use different directories. For example, I believe the working directory for Glassfish is the config directory of the running domain. Not a particularly obvious choice.
So, use an absolute path, most definitely. That way you KNOW where the files will go, and you can control the access permissions at the OS level for that directory, if that's necessary.
Writing to the file system from a Java EE container is not really recommended, especially if you need to process the written data:
it is not transactional
it harms the portability (what if you are in a clustered environment)
it requires to setup external parameters for the target location
If this is an option, I would store the files in database or use a JCR repository (like Jackrabbit).