Tomcat 6 file upload strategy - java

I have been using tomcat for sometime and still can't find a good way to do file upload. Just wonder how you guys handle file upload.
You know how you can create a symlink in the application to another fs. but then by default tomcat removes your symlink and everything within the symlink. so this add extra steps to auto deployment. I know there are patch that you can change the behavior. but that will make add extra steps to tomcat upgrade, and patch might not be available always.
I use fckeditor(with it's servlet connectors), spring, struts 1/2 and sometime just plain servlet for the fileupload.
What is the best way to do this?
Another requirement is, uploaded file should be viewable and in a nice location so that backup script can backup easily, ideally not within the apps (or just a symlink within the apps)
Any comment is welcome!
=)

Personally, I place the files in a location relative to $CATALINA_BASE:
File dir = new File(System.getProperty("catalina.base"), "uploads");

Related

Files written in a JSP page are not found by Tomcat

I've developed a JSP that writes a PNG file in a folder of deployment directory. After writing the contents, flushing, closing and syncing the file I try to show it in the same JSP using a tag but most of the times the imatge doesn't appears in the renderized page on the browser (the request of return a 404 Not Found response). The file is created (I can see the file into the folder in the system explorer).
I'm using Tomcat 8 as web container and I'm executing the webapp and Tomcat in the Eclipse Luna IDE.
Can anyone help me?
I believe this has been answered before in a slightly different form:
Tomcat 7 returns "304 Not Modified" on modified/non existent resource
However, since you are probably only generating your PNG files once (or maybe not very often), you have IMO a valid use case.
Since Tomcat does do caching, I think that you might want to consider using cachingAllowed="false" on your <Context>. Note that you will likely observe a slight performance drop since Tomcat will be going to the disk for every static request instead of consulting its cache.
You also have the option of writing your own servlet to serve the auto-generated PNG files directly from the disk. It can be complicated to write your own static-resource servlet with all the bells and whistles that Tomcat's DefaultServlet supports, but you can skip a lot of that and just always serve the whole file regardless of what the clients requests.

Moving web application (Java/JSP) to a web server

I have developed an application with Netbeans (Using Java, JSP and JQuery) in Windows environment. Now I am ready to transfer the application to a web host so that the application can be available on the Web and I am told that the application would have to be moved to a linux environment (hosting service already bought). Here are my concerns:
How to convert my code to Linux? Is there an automatic tool for this?
How to deploy my application to the server online (what do I need to copy and to what directory on the web?)
My application writes to a directory on c:drive on my laptop, what should I do to make the application write to correct directory a designated directory on the web server?
I have read here and there online but just haven't got specific solutions to this.
How to convert my code to Linux? Is there an automatic tool for this?
One of the Java key features is portability, so as far as you haven't used any OS-specific code like running a program using CMD or similar or a library that is OS-dependant (which is rare in these times but there are some yet), then you don't have anything to do.
How to deploy my application to the server online (what do I need to copy and to what directory on the web?)
You need to generate a WAR file. This file will zip all your web pages (JSPs) and web resources (js, css, image files) along with the Java binaries (*.class) and libraries (that must be on WEB-INF/lib folder).
Since you're working with NetBeans, here's a Q/A to generate the war file: How can I create a war file of my project in NetBeans?
This war file must be placed in the deploy folder of your web application server. Usually, the hosting provides you the tools (generally a link on the web with user and password) to administrate the host, based on this you should ask (or find it by yourself) the option to upload the war file.
My application writes to a directory on c:drive on my laptop, what should I do to make the application write to correct directory a designated directory on the web server?
You need to configure this path as a constant in your application, or even better, configure it in a properties file (or somewhere else) in order to be read and use it by your application easily. Remember that the path should be generic to be supported in almost every OS. For example, if you use a path with name
C:\some\path\for\files
Its generic form will be:
/some/path/for/files
Since you're going to work on Linux, make sure the user who executes the Tomcat (or the web application server you will use on production) have enough permissions to write on that folder. This can be easily done (and somebody here can fix this please) using the chown command:
#> chown -R user /some/path/for/files
Here's another Q/A to manage files and path on Java web applications: How to provide relative path in File class to upload any file?
OK, first a few thoughts:
Convert code to Linux. Once you have your ear of war file, you can just deploy them. It's best if you use UTF8 enconding in your files, specially if you use special characters, but that would be an issue you could test out when you deploy, could also be dependant on the Linux configuration. Having that said, Java is portable and you only have to be sure that the archive you create is compatible with the AppServer that's installed on the Linux hosting. You should get all the information you need about the deployment environment from the hosting site / company.
Deployment will depend from site to site, they should give you all instructions.
Here you might have a problem. I would say that the easiest way is to just map the directory in a properties file and customize it on every machine you use it. That's the easy part so far. However, you should check if your site will give you access to a directory, and be aware of space limitations and cleanup of the files. If you get, let's say, 100MB and you use 10MB a day, you might end up with trouble after 10 days...

How to display directory in Spring App?

So I'm writing a Spring web application that runs some scripts on the local server using ProcessBuilder. That part seems to be running fine. The scripts generate output files and then zip them up into a single .zip file. I'd like to provide the user with a way to download these files but I'm not sure of the best way to do this, or even how to implement any way to do it.
I tried putting the path to the directory into the URL, but I believe since Spring intercepts all URLs and it doesn't know how to process the one pointing at either the directory the Zip is in or the Zip itself, I just get an error. What would the proper way to do this be? Either to display a list of files or just link to the files themselves? Any help would be really appreciated, thank you.
The way you do any file download from a web-app is to write a servlet that writes the content of the file to the http response's output stream. There's an example of this here that's downloading an Excel file.
The directory listings that you get in a web-page don't just happen automatically, you'll have to write a JSP that displays the directory listing with hyperlinks on each file that link to file download servlet.
I looked around and could not find a complete directory listing example for spring. Though it is relatively simple to implement I put together a blog post to explain this, so that it could be quickly reused when needed http://krishna-passionatelycurious.blogspot.com/2013/04/file-download-page-using-spring.html.
But, the overall approach is to loop through the contents of a directory and generate appropriate links, such that the links point back to the same spring handler, where we could make a decision based on whether the accessed link actually points to a directory or a file and generate directory listing again or stream the content for download.
The blog has a sample implementation of this.

Java Servlets - Writing to file

I'm using the Netbeans IDE, and I'm currently using a GlassFish server.
What I want to do is write to a file.
I looked at some pages, and the code I have now (that is not working as far as I know) looks like:
File outputFile = new File(getServletContext().getRealPath("/")
+ "TheFile.txt");
FileWriter fout = new FileWriter(outputFile);
fout.write("The Content");
fout.close();
This is my project's structure:
Also where will the file get placed?
Edit:
I forgot to mention there are some other folders below the ones in the picture: Test Packages, Libraries, Test Libraries and Configuration Files. However I don't think the file would get placed there.
Edit (newest):
I found out the file is stored in the /build/web folder, but this is not appearing in Netbeans. Even after I restarted it.
As you've coded, the file will be placed in public web root. That's where getRealPath("/") will point to. To be precise, it's the folder named Web Pages as in your screenshot. As an exercise, do the following to figure the absolute path, so that you can find it by OS disk explorer.
System.out.println(file.getAbsolutePath());
I don't do Netbeans, but likely you need to refresh the folder in your IDE after the write of the file so that it appears in the listing in the IDE. Click the folder and press F5. This is at least true for Eclipse.
That said, this approach is not recommended. This won't work when the servletcontainer isn't configured to expand the WAR on disk. Even when it did, you will lose all new files and changes in existing files when the WAR is been redeployed. It should not be used as a permanent storage. Rather store it on a fixed path outside the webapp or in a database (which is preferred since you seem want to reinvent a CMS).
Note that this is in no way guaranteed to work in all web containers or through restarts and will most likely be overwritten by a redeployment.
If you want to be able to allow your user to update content, you need to store the new content somewhere and have a servlet or a JSP-page or a facelet retrieve the new content from the backing storage and send it to the browser.
See the documentation for getRealPath. It returns you the location on the disk for something specified with a URL.
I'm guessing your file is in the root of your web application on the disk within Glassfish (where the WAR file is extracted). I don't know enough about Glassfish to say where that will be.
Also, note you are using string concatenation to create the file name, so if the getRealPath call doesn't return a String with a "/" on the end, then you might be creating a file in the parent directory of your web app. Perhaps best to use a File object for the parent directory when creating the File object for the actual file. Check out the File API.
I'd recommend creating the file outside of your web app. If you redeploy your WAR file then you might delete your file, which probably isn't what you want.
Being in a servlet makes little difference to the fact that you want to output a file. Just follow the standard file APIs as a starting point. Here's a tutorial.

How to preview a file on the server in JBoss

I need some ideas on how I can best solve this problem.
I have a JBoss Seam application running on JBoss 4.3.3
What a small portion of this application does is generate an html and a pdf document based on an Open Office template.
The files that are generated I put inside /tmp/ on the filesystem.
I have tried with System.getProperties("tmp.dir") and some other options, and they always return $JBOSS_HOME/bin
I would like to choose the path $JBOSS_HOME/$DEPLOY/myEAR.ear/myWAR.war/WhateverLocationHere/
However, I don't know how I can programatically choose path without giving an absolute path, or setting $JBOSS_HOME and $DEPLOY.
Anybody know how I can do this?
The second question;
I want to easily preview these generated files. Either through JavaScript, or whatever is the easiest way. However, JavaScript cannot access the filesystem on the server, so I cannot open the file through JavaScript.
Any easy solutions out there?
Not sure how you are generating your PDFs, but if possible, skip the disk IO all together, stash the PDF content in a byte[] and flush it out to the user in a servlet setting the mime type to application/pdf* that responds to a URL which is specified by a link in your client or dynamically set in a <div> by javascript. You're probably taking the memory hit anyways, and in addition to skipping the IO, you don't have to worry about deleting the tmp files when you're done with the preview.
*****I think this is right. Need to look it up.
Not sure I have a complete grasp of what you are trying to achieve, but I'll give it a try anyway:
My assumption is that your final goal is to make some files (PDF, HTML) available to end users via a web application.
In that case, why not have Apache serve those file to the end users, so you only need your JBOSS application to know the path of a directory that is mapped to an Apache virtual host.
So basically, create a file and save it as /var/www/html/myappfiles/tempfile.pdf (the folder your application knows), and then provide http://mydomain.com/myappfiles (an Apache virtual host) to your users. The rest will be done by the web server.
You will have to set an environment variable or system property to let your application know where your folder resides (/var/www/html/myappfiles/ in this example).
Hopefully I was not way off :)
I agree with Peter (yo Pete!). Put the directory outside of your WAR and setup an environment variable pointing to this. Have a read of this post by Jacob Orshalick about how to configure environment variables in Seam :
As for previewing PDFs, have a look at how Google Docs handles previewing PDFs - it displays them as an image. To do this with Java check out the Sun PDF Renderer.
I'm not sure if this works in JBoss, given that you want a path inside a WAR archive, but you could try using ServletContext.getRealPath(String).
However, I personally would not want generated files to be inside my deployed application; instead I would configure an external data directory somewhere like $JBOSS_HOME/server/default/data/myapp
First, most platforms use java.io.tmpdir to set a temporary directory. Some servlet containers redefine this property to be something underneath their tree. Why do you care where the file gets written?
Second, I agree with Nicholas: After generating the PDF on the server side, you can generate a URL that, when clicked, sends the file to the browser. If you use MIME type application/pdf, the browser should do the right thing with it.

Categories