I'm creating a dynamic web project in eclipse using jsps and java servlets, however I want to add some external files to be edited using the app. Where do I put them such that I can open them from my app and save an edited version - and finally provide a link for a download of the edited file?
Thanks
Where do I put them
Nobody cares. Really. As long as it's not in the deploy folder, of course.
If your concrete problem is avoiding to hardcode the exact external location in Java source code, just provide it as VM argument, environment variable, properties file setting, or whatever externally configurable. For detail, see also Recommended way to save uploaded files in a servlet application.
And/or if your concrete problem is serving those files back to the web, just either tell the server to publish the external location into the web as well, or create a servlet which reads from the external location and writes to the response. For detail, see also Load images from outside of webapps / webcontext / deploy folder using <h:graphicImage> or <img> tag.
Related
I uploaded files to the server using BLOB db type on play framework. In the application.conf file I have
attachments.path=home/dotcloud/uploads
But I couldn't find the files on the server.
The issue is that if I restart my www service, then I lose all my files, I only have the db records.
I believe that there are two issues in here. First your path lack a initial '/' to be a full path (I'm assuming that was your intention):
attachments.path=/home/dotcloud/uploads
Second, I'm not sure that your Play server will have rights to write to that folder, as it's outside the application context path. Default folder is local to the application and Play can write it, not so sure about other folders though. You should double check that.
I am writing a java web-application program to create a file(a simple xml file) in hard disk. The program can update the file dynamically. After its creation/update, I want to see the contents of that file from another application(e.g. browser). The problem is that the browser is not aware of the new modifications made in the file. This is resolved if I refresh the eclipse project manually(However, I want the browser to see updated file contents each time I refresh the browser after the file is modified within the web application). So, I think there's some issue with Tomcat/java not releasing the handle of the file or maintaining cache.
Please suggest.
No, the issue is not with Tomcat. It's with Eclipse. You must refresh your eclipse project vs the project directory on disk.
The alternative is to use external Tomcat (or Jetty) for testing your webapp.
Set Response no-cache headers.
We have to make a Java application demo available on Internet using JWS. It goes pretty well; all that's missing is making working directory files available for the application.
We know about the getResource() way... The problem is that we have different plugins for the same application and each one require different files (and often different versions of the same files) in their working directory to work properly. So we just change the working directory when we want the application to have a different behavior.
Currently, the demo is packaged in a signed jar file and it loads correctly until it requires a file from the working directory. Obviously, the Internet users of this demo don't have the files ready. We need a way to make these files available to the WebStart application (read/write access) in its working directory.
We've thought of some things, like having the application download the files itself when it starts, or package them in the jar and extract them on startup.
Looking for advices and/or new ideas. I'll continue working on this... I'll update if I ever find something reliable.
Thank you very much!
I said I would share what I found in my research for something that would fit my needs. Here's what I have so far.
I have found that the concept of current working directory (CWD) does not really make sense in the context of a Java Web Start (JWS) application. This had for effect that I stopped trying to find the CWD of a JWS and started looking for other options.
I have found that (no, I didn't know that) you can refer (using getResource()) to a file in the root directory of a JAR file by simply adding a '/' in front of its name. ("/log4j.properties", for example.) The impact of this is that I can now take any file which is only referred to in a read-only manner in the root of that JAR file (which is really only a ZIP file). You can refer to any file in the root of the JAR file using AnyClass.class.getResourceAsStream. That rules out the problem with read-only files required to run the application, at the cost of a switch in the code telling whether the application is run from a valid CWD or from a JWS context. (You can very simply set a property in the JNLP file of the JWS application and check if that property is set or not to know where to look for the file.)
For write-only files (log files in my case), I used the property , adding a directory with the name of the application: <user.home>/.appname and added log files to it.
Read/write files (which I don't have in my case) would probably simply go at the same place than write-only files. The software could deal with uploading them somewhere if needed, once modified, I guess.
That's the way I deal with the problem for now.
Note there is a service you can explicitly ask for, to get file access to the computer (unless you go all the way and ask for full access (which requires signed jar files)).
Then you need to determine where these files need to go - basically you have no idea what is where and whether you may actually write anywhere. You can create tmp-files but those go away.
Would a file system abstraction talking to the JNLP-server do so you store the users data on the server?
Consider the following example structure
- Project
- www
- files
+ documents
+ html
+ images
+ scripts
- WEB-INF
* web.xml
The documents folder needs to be a symlink or in some other way external from the war file because users will add and remove documents (through a mapped network drive).
I'd like to deploy the webapp as a war-file but I don't know how to do that and take the above into account. Could you give some pointers?
/Adam
If it's static content, maybe you'd be better off fronting your app server with a web server and putting the static content there. You relieve the app server of having to serve up static data and save a network roundtrip to boot.
I agree with #duffymo.myopenid.com that fronting your app server with a web server that serves static content for certain URL prefixes is a good, clean solution.
If this isn't feasible in your environment or if you decide that you'd rather handle it in the web application itself, you could write a servlet that effectively does the same thing. For example, create a servlet that is mapped to the URL pattern /documents/*. This servlet could parse the URL (/documents/some/file.png) to determine a relative filename (some/file.png). It could then read and return the corresponding contents found in an external directory (/staticDocs/some/file.png).
Why not store the documents etc. in a database, then have the web-app access the database and allow users to pull files that way? Does it have to be a mapped network drive?
Otherwise if it's a matter of knowing what is there, you could always construct the jnlp file dynamically and pass file lists, etc. in as arguments (if they are server side).
Guess we need to know a little more about what you are trying to accomplish.
Basically, it's a webapp that aggregates information from various sources and generates documents. It's a requirement that users have the ability to create and upload documents manually from the network without being logged in to the webapp.
Putting the document location path as a context variable is definately doable. I guess it's the easiest way. /Adam
Unfortunately, for you .war files are .zip files at heart and .zip files do not support symbolic links. If you are ONLY deploying to a windows machine you may have luck using a shortcut file. However, I'm not sure if the app-server will like that (... probably not.)
I would recommend adding a configuration parameter to the application that allows the document folder's full path to be specified there. The default path should be relative ("./www/files/documents") so that the app works out of the box without additional configuration.
Many java web servers support "exploded war files" where you just unzip your .war file into the deployment directory. With tomcat you copy this to $CATALINA_HOME/webapps and you're done.
This should work for you.
What about creating an environment variable on your server that points to the directory the files are stored in? The environment variable may work better than a setting inside your WAR file because you could deploy your application in a new environment (maybe moving from DEV to PROD) without changing your WAR file.
From your java code, you can reference this environment setting with:
String docPath= System.getProperty("DOC_PATH");
In Apache Tomcat it may sometimes be appropriate to achieve reuse via the tomcat RewriteValve like this:
META-INF/context.xml:
<Context>
<Valve className="org.apache.catalina.valves.rewrite.RewriteValve" />
</Context>
WEB-INF/rewrite.config:
RewriteRule (.*)/login(/.*\.)(png|jpg|js|css) $1$2$3
Now the /appContext/login/ path will use the same images/js/css as /appContext/
Of course as with all regular expression based solutions to ANY problem, keeping the complexity of the expression low is important for performance.
Sounds like you need a web Content Management System (CMS).
I create a web application (WAR) and deploy it on Tomcat. In the webapp there is a page with a form where an administrator can enter some configuration data. I don't want to store this data in an DBMS, but just in an XML file on the file system. Where to put it?
I would like to put the file somewhere in the directory tree where the application itself is deployed. Should my configuration file be in the WEB-INF directory? Or put it somewhere else?
And what is the Java code to use in a servlet to find the absolute path of the directory? Or can it be accessed with a relative path?
What we do is to put it in a separate directory on the server (you could use something like /config, /opt/config, /root/config, /home/username/config, or anything you want). When our servlets start up, they read the XML file, get a few things out of it (most importantly DB connection information), and that's it.
I asked about why we did this once.
It would be nice to store everything in the DB, but obviously you can't store DB connection information in the DB.
You could hardcode things in the code, but that's ugly for many reasons. If the info ever has to change you have to rebuild the code and redeploy. If someone gets a copy of your code or your WAR file they would then get that information.
Putting things in the WAR file seems nice, but if you want to change things much it could be a bad idea. The problem is that if you have to change the information, then next time you redeploy it will overwrite the file so anything you didn't remember to change in the version getting built into the WAR gets forgotten.
The file in a special place on the file system thing works quite well for us. It doesn't have any big downsides. You know where it is, it's stored seperatly, makes deploying to multiple machines easy if they all need different config values (since it's not part of the WAR).
The only other solution I can think of that would work well would be keeping everything in the DB except the DB login info. That would come from Java system properties that are retrieved through the JVM. This the Preferences API thing mentioned by Hans Doggen above. I don't think it was around when our application was first developed, if it was it wasn't used.
As for the path for accessing the configuration file, it's just a file on the filesystem. You don't need to worry about the web path. So when your servlet starts up it just opens the file at "/config/myapp/config.xml" (or whatever) and it will find the right thing. Just hardcodeing the path in for this one seems pretty harmless to me.
WEB-INF is a good place to put your config file. Here's some code to get the absolute path of the directory from a servlet.
public void init(ServletConfig servletConfig) throws ServletException{
super.init(servletConfig);
String path = servletConfig.getServletContext().getRealPath("/WEB-INF")
Putting it in WEB-INF will hide the XML file from users who try to access it directly through a URL, so yes, I'd say put it in WEB-INF.
I would not store it in the application folder, because that would override the configuration with a new deployment of the application.
I suggest you have a look at the Preferences API, or write something in the users folder (the user that is running Tomcat).
The answer to this depends on how you intend to read and write that config file.
For example, the Spring framework gives you the ability to use XML configuration files (or Java property files); these can be stored in your classpath (e.g., in the WEB-INF directory), anywhere else on the filesystem, or even in memory. If you were to use Spring for this, then the easiest place to store the config file is in your WEB-INF directory, and then use Spring's ClassPathXmlApplicationContext class to access your configuration file.
But again, it all depends on how you plan to access that file.
If it is your custom config WEB-INF is a good place for it. But some libraries may require configs to reside in WEB-INF/classes.