How to save a uploaded file on server? My plan is to create a FileOutputStream on the receiver class. Simple enough. But what is the way to create directory and files on server? I tried a File object calling mkdir(). It failed and when I check “getabsoluepath()”, it wasn’t based on the application directory.
What should I use to create new directory and new file on a certain directory on Server?
Create files just like you create files in a Java. new File(“/some/path/dir/name”).mkdir() or .mkdirs(); What exactly was a parent folder in your File object when you were trying to create the folder ? Unless your app server is not running in a security mode you should be able to create files.
Try this, for instance:
This sample will create a folder “myfolder” in your home directory:
And this line will create an output stream and file to write data to:
File file = new File ( folder, "myfile.txt" );
FileOutputStream stream = new FileOutputStream ( file ); // when opening a stream, file will be created automatically
// ... write data to the stream ...
stream.flush();
stream.close();
Well, I can always create directory based on absolute path…
But, I like to create a directory right under the “web content” or “VAADIN” directory. The other users might wants to download the uploaded data. How do I specify the new directory through relative path to the application?
Well, in this case nothing differs from any other JEE web app - just get the root web application root (or other) directory path via HttpServletRequest’s :
getBaseDirectory should also work. What do you mean under “temp directory where application running” ?
When you deploy a .WAR file, it is unpacked by the app server to some temporary directory. For instance, Jetty will unpack to /tmp/jettyXXXXX folder, Glassfish will unpack into it;s domain directory.
If you plan to use it for temporary file storage - this is ok. Just use the directory. But if you plan to use it for permanent storage of uploaded files - do not do this. This directory managed by the app server for runtime purposes and could be removed or changed on any application redeploy or app server restart. For such cases, consider creating a service directory for your application in some safe place, like in user.home or in other preconfigured location.
In order to get a servlet request you should register a transaction listener with your vaadin application, for instance, in the application init method:
getContext().addTransactionListener( this );
Your app class shoud implement ApplicationContext.TransactionListener interface. In transsactionStart method (which is called on every communication request from a client) you’ll find the HttpServletRequest object - it is the second parameter (cast it to HttpServletRequest).
Note, that transactionStart/End methods will be called for every application instance, so you have to separate your own one.
See the
ThreadLocal pattern article for more samples - it also uses transaction listener in a manner I described above.
/**
* Return the servlet container context.
*/
public ServletContext getServletContext() {
ApplicationContext ctx = getContext();
if (ctx == null) return null;
final ServletContext sCtx = ((WebApplicationContext)ctx).getHttpSession().getServletContext();
return sCtx;
}
Once you have the servlet context, you can use the standard J2EE methods – the paths are relative to where your application is deployed; and will vanish if the application is undeployed.
ServletContext sCtx = app.getServletContext();
String dirName = sCtx.getRealPath("registration"); //$NON-NLS-1$
File dir = new File(dirName);
if (!dir.exists()) dir.mkdirs();
File longPath = new File(filename);
filename = longPath.getName();
file = new File(dir, filename);
// Open the file for writing.
fos = new FileOutputStream(file);
Yes. I should store them in a separate pre-config place. The reason I want to put them in the VAADIN directory is my perception that for the App to recognize a picture, it has to be under VAADIN. I was wrong.
Here is my challenge: I want user to upload a picture and then user needs to reference the picture in the user’s own posting. I just found out that if an image existed before the app started, I can reference the image in the “richTextEditor” gadget. But If an image is created AFTER the app started, even the image is in the same directory, user can’t reference the image in the “richTextEditor”. (It just displayed a default image icon.)
I just did the experiment. After the image is uploaded, I stop the app, do a refresh on the WebContent directory. Re-start the app, it then works. I can now reference the newly uploaded image in my app… But I can’t re-start the app every time I upload a picture. What can I do?
Bottom line, I need to see the uploaded image in the “richTextEditor” after an image is uploaded. What is my options?
How do you reference your image in rich text editor (what is the image url) (by the way, do you use built-in to Vaadin, TinyMCE widget or whatever else) ?
To reference images, stored in some non web-app related places, you can use, for instance, Vaadin’s StreamResource. It finally generates an url to access your image and your StreamResource implementation will get a call to request a stream for an image. However, Im not sure if the url will be unique between application restarts.
You can also implement your own image storage and create an image servlet which will serve images - thus you’ll guarantee that image URL will be always the same.
I am just use the Vaadin standard Rich Text Editor. And I am talking about just add a image reference by giving the “http://xxxxxxx” address. When I provides an address of a preloaded image, it shows up in the rich text editor. But If I provides an address of a just uploaded image, it just renders a default icon…
Looks like StreamResource is the one to go. I just see that it calls “application.addResource(this);” in its constructor. My guess is adding the resource to the application is all I need.
TinyMCE looks fantastic… I will try it out immediately. Searching the forum looks like there is a build with it already… Hopefully we will see this in the coming formal releases.
Ok. I got it to work. It is quite simple after I figure out the “got-you” element.
the app.getContext().getBaseDirectory() works. That is what I need.
The “got-you” element: if the image is not under “VAADIN” directory, you can’t render the image in Label or RichTextArea with just the URL. When I put the uploaded images in other directories, the app just can’t render the picture even though the correct path was given. Once I move the upload directories under the “VAADIN” directory, it works.
There are many ways in which you can sort the randomized files in the hard disk,
That is to remove all the unwanted, duplicated files from your machine.