I am on latest glassfish (3.1.2) - so no need for apache FileItem and no bugs with getPart(). I read that the best practice on uploading images is saving them on the file system (see here for instance). I am editing already existing code - smelly at that - so I had the idea to do :
Part p1 = request.getPart("file");
System.out.println("!!!!!P1 : " + p1);
Prints :
!!!!!P1 : File name=DSC03660.JPG,
StoreLocation=C:\_\glassfish3\glassfish\domains\domain1\generated\jsp\elkethe\upload_7cb06306_138b413999a__7ffa_00000000.tmp,
size=2589152bytes, isFormField=false, FieldName=file
newlines mine. In the code people are doing :
if (request.getParameter("crop") != null) {
// get path on the server
String outputpath = this.getServletContext().getRealPath(
"images/temp/" + session.getId() + ".jpg");
// store photo
InputStream is = p1.getInputStream();
createPhoto(is, outputpath);
session.setAttribute("photo_path", "images/temp/" + session.getId()
+ ".jpg");
response.sendRedirect("cropping");
return;
}
Where
private void createPhoto(InputStream is, String outputpath) {
FileOutputStream os = null;
try {
os = new FileOutputStream(outputpath);
// write bytes taken from uploaded file to target file
int ch = is.read();
while (ch != -1) {
os.write(ch);
ch = is.read();
}
} catch (Exception ex) {
ex.printStackTrace();
} finally {
Helpers.close(os);
}
}
Now what happens is that the file is uploaded in the StoreLocation (???) on submitting the form so apparently all this p1.getInputStream()
is for naught.
My questions are :
- what is StoreLocation ? How tmp are those glassfish uploads ? Where are all those parameters set ? I did read BalusC' tutorial - but there is no mention of StoreLocation (google is not very helpful either).
- What would be a more professional way of handling the situation - including keeping the photos outside the webroot - but using facilities glassfish provides (if it does provide) ?
- Even p1 printing so nice escapes me (it does not seem to Override
toString()
)
Interested in tips even in how should one rename the photos etc (is this sessionID thing Right ? - check also the time trick) :
if (request.getParameter("save") != null) {
long time = System.currentTimeMillis();
String path = "images/upload/" + session.getId() + time + ".jpg";
String outputpath = this.getServletContext().getRealPath(path);
// store photo
InputStream is = p1.getInputStream();
createPhoto(is, outputpath);
// etc
}
Good practice is to pick a path on the filesystem where photos will be uploaded. Often this path is programmed to be configurable via java system property (eg: by passing
-Dcom.mycompany.uploadPath=/path/to/photos/dir
system property on JVM arguments).You can also use java system propeties to find environment specific path:
user.dir
,user.home
etc. See System Properties on Java SE Tutorial. Or to use glassfish-relative path, see glassfish system properties.Once you have reference to Part, it's just about doing file IO to copy the uploaded file into this upload path, eg:
Code above uses apache IOUtils for convenience but feel free to write your own copy method. You should also add exception handling method
StoreLocation is just the the java.io.File object for the
FileItem
's data's temporary location on the disk. Resides injavax.servlet.context.tempdir
which defaults to%GLASSFISH_HOME%\domains\domain1\generated\jsp\webApp
. Those uploads are as tmp as anything (The lifetime of the file is tied to the lifetime of theFileItem
instance; the file will be deleted when the instance is garbage collected - from here). Haven't yet managed to change the value ofjavax.servlet.context.tempdir
programmatically (comment please) - it is thetempdir
property of the sun-web-app element of the sun-web.xml.Well a more professional way is to Use
Part.write()
to move the file to the desired location. Due to glassfish implementation though you can't supply an absolute path to write - a chore. I asked here.As to where to save the file : https://stackoverflow.com/a/18664715/281545
That is for saving the file - to serve it from a location outside the app you need to define "alternatedocroot" properties in the sun-web.xml (or glassfish-web.xml).
Oh yes it does
No it is not - I tend towards
File#createTempFile()
- anyway this is a different question asked here