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.
Related
If I have a resource file (mydata.txt) in resources folder (set up as another source folder) of my application. This mydata.txt eventually would be packaged inside root of a jar file (.war) to be deployed to some application server (Tomcat, Jetty, WildFly).
File mydata.txt has some crucial data needed to the application, and this file shall be appended by the application.
To get a file from jar I can use getClass().getResourceAsStream("/mydata.txt") - thus I get this file as InputStream. But there is no way I can get this file as OutputStream and write to it.
All solutions with getClass().getResource() - returning URL are discouraged, getResourceAsStream is always recommended, but it allows only reading, not writing/updating/appending the file.
getClass().getProtectionDomain().getCodeSource() solution is also discouraged to get (write) access to the file.
I could create some file in a temporary directory on Tomcat Server (System.getProperty("java.io.tmpdir") and write to it, but it is nonsense because this file contents is crucial for the application (to write it to tmp dir), besides I need to append file, not create a new one and write to it.
Also, I am not sure that writing to any other directory (other than tmp) of application server is a good idea (please correct me if I am wrong here).
So I come to the conclusion that it is not recommended to save any data to a file in enterprise application, so I shall always use a database instead?
In short: Yes. Beside all you mentioned (which is all correct) the biggest problems are
concurrent access
transaction handling
which both a database serves perfect and with a file approach is just a pain in the ****
In addition to that especially an application server provides you with configuration of connection (and pools) to data sources of any kind, which is really handy in a production environment.
As i know it returns the application path? But what exactly the use of it.
In many environments the application user is not allowed to read any files outside of the deployment directory. This is mostly done for security purposes - for example if someone hacks your application they won't be able to read a passwords file.
And in professionally managed environments developers often don't have a say in which directory the application will be placed.
So if you need to read a file like properties, images, certificates, etc. you can place it in the application directory (or .war file) and use getRealPath("") to get the path you need to load.
As an alternative you can place the external files on the classpath but there are sometimes issues with this. For large files most app servers will try to load the entire file into memory and cache it if it is on the classpath.
The getRealPath() gives the absolute path (on the file system) leading to a file specified in the parameters of the call. It returns the path in the format specific to the OS.
The getContextPath() on the other hand returns the URI or the relative path to the resource.
As far as I remember, I've used it to save images or other data files, since it allows you to see where your application is deployed at the moment. For example, Eclipse and Tomcat will create a temporary folder that's buried deep somewhere within your Eclipse profile and deploy the app there.
This is a real path in file system.
From javadoc:
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).
I think it is very clear. Why do we need this? Sometimes web applications perform some manipulation in file system. For example read stuff from files, write files etc. This API allows you to access the place where your JSPs and other stuff is really stored.
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");
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.
I have this code on an applet. The applet works ok, but I get a lot of unnecessary duplicate download. In particular, I have noticed that each "getResource" triggers a download of the .JAR file.
static {
ac = new ImageIcon(MyClass.class.getResource("images/ac.png")).getImage();
dc = new ImageIcon(MyClass.class.getResource("images/dc.png")).getImage();
//...other images
}
How can this be avoided?
Simply removing all instances of URLConnection.setDefaultUseCaches(false) will solve the problem.
Please refer for more details.
http://java-junction.blogspot.com/2009/11/applet-jar-caching-not-working.html
Do you include the applet to a HTML page? If so, try to enable the JAR caching, as is described here: http://java.sun.com/j2se/1.4.2/docs/guide/plugin/developer_guide/applet_caching.html
If that does not help for some reason :) perhaps expose your resources / images along your applet JAR on a web server and reach them using separate HTTP requests (yes, its ugly and yes, it does not reduce number of needed downloads, but it at least reduces the amount of data that need to be transferred).
Only a workaround:
You could put your images in a zip file inside the jar, get that using a ZipInputStream and extract the images from there.
Which Java VM do you use? And which Server do you use?
There is a bug in the browser plugin on Linux.
If the server does not send the modified date then Java can not cache the jar file.
If your applet always downloads the jar even though jar is cached, make sure you have not disabled the URLConnection's caching via the API: URLConnection.setUseCaches and URLConnection.SetDefaultUseCaches.
ImageIcon's underlying mechanism for fetching the resource is a URLConnection. Calling URLConnection.setDefaultUseCaches(false), sets a "part of the static state of all URLConnections" which cause the JRE to ignore the cache and redownload the entire jar every time it accessed.
Simply removing all instances of setDefaultUseCaches will solve the problem.
this is a repost from: http://java-junction.blogspot.com/2009/11/applet-jar-caching-not-working.html