Disk storage in a Java EE application
I have Java EE app in which I want to small little amount of data to disk, eg just user/passwords.
I dont want to go through the hassle of integrating w开发者_运维知识库ith a full db for this little amount of data.
Is there a standard way to access the file system and a standard folder where web applications can store their data on disk, other than using a database?
Note:
I am not using EJBs. It's a web application using Servlets.
You could consider using the preferences API to store this data - it's available on Java EE as well.
Use a simple Java based database, like HSqlDB or h2. The setup won't be that complicated compared to a heavyweight DB. The key advantage this will give you is managing concurrent updates, which you would have to code yourself if you use direct file access.
File access has always been a controversial activity within EJB-based applications because of the restrictions placed upon bean providers by the EJB specification. The part of the specification relevant here is under the section entitled Programming Restrictions, and it states the following about accessing the filing system.
An enterprise bean must not use the java.io package to attempt to access files and directories in the file system.
This is a fairly specific statement, and is followed up by a short explanation of why this is the case.
The file system APIs are not well-suited for business components to access data. Business components should use a resource manager API, such as JDBC, to store data.
While this explanation highlights a key reason for not using file I/O, I think that there is much more to this. However, although this is a well known restriction, actually finding more information on this is a time consuming task. So, in the quest for knowledge, I did some digging and came up with the following reasons why file I/O is "a bad thing"TM.
The WORA mantra of Java and J2EE means that there might not actually be a filing system to access. I've seen various comments saying that the J2EE server might be running on some device that doesn't have a filing system, or the application server doesn't have access to the filing because it's deployed in, for example, a database server. Although this is a valid reason, I don't think that this applies to most projects. Access to files isn't transactional. Yes, typically, files aren't transational resources and when building enterprise systems, you usually want to be sure that some information has been correctly and accurately stored, hence the use of relational databases and the like. Accessing file systems is a potential security hole. If we look at how other resources (e.g. JDBC DataSources, JMS Topics, etc) are accessed, it's usually through JNDI. To ensure that only authorised parties can access these, we typically have such resources protected by some sort of authentication mechanism, be it a username/password combination, or an SSL certificate. The problem with filing systems is that they are much more open and it's harder to control access. One solution is to lock file access via the operating system, and another is to use the Java security model to restrict access to only a specific part of the disk. If you are going to access the filing system from your business components, then locking down access will help to make the system more secure and resilient to attacks. So then, how are we supposed to access files from EJB? Many people advocate the use of an intermediary Java class to wrap up the file access, believing that the EJB specification only disallows access from the bean class itself. Is this true? I'm not convined because all the same reasons apply. The specification itself presents an answer, and that answer is to use a resource manager so that we can treat file access as a secure, transactional, pooled resource. One such implementation is a J2EE Connector Architecture (JCA) adapter that you write, deploy and configure to access your filing system. In fact, some vendors have already built JCA adapters that access flat files and these are particularly useful if you have to access the outputs of legacy, mainframe systems.
Of course, many types of file access can be worked around. For example, configuration information can be placed in LDAP, JNDI, a database, or even properties files delivered inside your JAR files that get loaded as a resource through the classloader. In those circumstances where accessing files is a requirement, then other solutions include loading the file through the servlet container, having it sent to the EJB tier via messaging, downloading the file from a webserver through a socket connection and so on.
These are all workarounds for the programming restriction but at the end of the day I think you have to be pragmatic. Many projects do utilise file access from within the EJB tier and their solutions work. Although the EJB specification imposes a restriction, in reality many vendors choose not to enforce this, meaning that using the java.io package for accessing files is possible. Whatever solution you come up with, you should ideally keep the specification in mind. It's there to help you build portable and upgradable applications, but pragmatism should be employed. Hopefully a future version of the EJB specification will address this issue in more detail and this controversy will become a thing of the past.
Credit for above goes to: Simon Brown
In addition it is never a good idea to keep passwords on your site. Most security references tell you it is OK to keep a hash of a password that you can check against. If somebody breaks into your site, then he could retrieve all the passwords for all users.
Is there a standard way to access the file system and a standard folder where web applications can store their data on disk, other than using a database?
There's the java.io.File
API, but the Servlet or the Java EE specifications do not provide a standard directory where you may persist files for a lengthy duration. At the very best, the javax.servlet.context.tempdir
attribute may be used to locate the location of the temporary files directory, from the ServletContext
.
The rationale for not supporting standard file directories is due to the inability to predict whether the container would be able to access a file system in the first place. Your container might be running off an embedded device in the first place to begin with, that might rely on a SAN or another remote file system for persisting files.
In addition, using the File API in EJBs is frowned upon, due to the non-transactional nature of file systems, so there is no similar concept of working directories and files.
精彩评论