如何通过 Java EE Web 应用程序将文件存储在服务器(Web 容器)上?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/2663204/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How to store a file on a server(web container) through a Java EE web application?
提问by Yatendra Goel
I have developed a Java EE web application. This application allows a user to upload a file with the help of a browser. Once the user has uploaded his file, this application first stores the uploaded file on the server (on which it is running) and then processes it.
我开发了一个 Java EE Web 应用程序。此应用程序允许用户在浏览器的帮助下上传文件。一旦用户上传了他的文件,这个应用程序首先将上传的文件存储在服务器上(它正在运行),然后处理它。
At present, I am storing the file on the server as follows:
目前,我在服务器上存储文件如下:
try {
// formFile represents the uploaded file
FormFile formFile = programForm.getTheFile();
String path = getServlet().getServletContext().getRealPath("") + "/"
+ formFile.getFileName();
System.out.println(path);
file = new File(path);
outputStream = new FileOutputStream(file);
outputStream.write(formFile.getFileData());
}
where, the formFile
represents the uploaded file.
其中,formFile
代表上传的文件。
Now, the problem is that it is running fine on some servers but on some servers the getServlet().getServletContext().getRealPath("")
is returning null
so the final path that I am getting is null/filename
and the file doesn't store on the server.
现在,问题是它在某些服务器上运行良好,但在某些服务器上getServlet().getServletContext().getRealPath("")
正在返回,null
因此我得到的最终路径是null/filename
并且文件没有存储在服务器上。
When I checked the API for ServletContext.getRealPath()
method, I found the following:
当我检查ServletContext.getRealPath()
方法的 API 时,我发现以下内容:
public java.lang.String getRealPath(java.lang.String path)
Returns a String containing the real path for a given virtual path. For example, the path
"/index.html"
returns the absolute file path on the server's filesystem would be served by a request for"http://host/contextPath/index.html"
, where contextPath is the context path of this ServletContext.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).
public java.lang.String getRealPath(java.lang.String path)
返回一个包含给定虚拟路径的真实路径的字符串。例如,该路径
"/index.html"
返回服务器文件系统上的绝对文件路径,该路径将由对 的请求提供服务"http://host/contextPath/index.html"
,其中 contextPath 是此 ServletContext 的上下文路径。返回的真实路径将采用适合运行 servlet 容器的计算机和操作系统的形式,包括正确的路径分隔符。如果 servlet 容器出于任何原因(例如当内容从 .war 存档中可用时)无法将虚拟路径转换为真实路径,则此方法将返回 null。
So, Is there any other way by which I can store files on those servers also which is returning null
for getServlet().getServletContext().getRealPath("")
那么,有没有用,我可以存储这些服务器也被返回的文件任何其他方式null
进行getServlet().getServletContext().getRealPath("")
采纳答案by Pascal Thivent
Writing to the file system from a Java EE container is not really recommended, especially if you need to process the written data:
不建议从 Java EE 容器写入文件系统,特别是如果您需要处理写入的数据:
- it is not transactional
- it harms the portability (what if you are in a clustered environment)
- it requires to setup external parameters for the target location
- 它不是交易性的
- 它会损害可移植性(如果您在集群环境中会怎样)
- 它需要为目标位置设置外部参数
If this is an option, I would store the files in database or use a JCR repository (like Hymanrabbit).
如果这是一个选项,我会将文件存储在数据库中或使用 JCR 存储库(如Hymanrabbit)。
回答by Will Hartung
By spec, the only "real" path you are guaranteed to get form a servlet container is a temp directory.
根据规范,您可以保证从 servlet 容器中获得的唯一“真实”路径是临时目录。
You can get that via the ServletContext.gerAttribute("javax.servlet.context.tempdir")
. However, these files are not visible to the web context (i.e. you can not publish a simple URL to deliver those files), and the files are not guaranteed in any way to survive a web app or server restart.
你可以通过ServletContext.gerAttribute("javax.servlet.context.tempdir")
. 但是,这些文件对 Web 上下文不可见(即您不能发布一个简单的 URL 来传送这些文件),并且不能以任何方式保证这些文件在 Web 应用程序或服务器重新启动后仍然存在。
If you simply need a place to store a working file for a short time, then this will work fine for you.
如果您只需要一个地方来短时间存储工作文件,那么这对您来说很合适。
If you really need a directory, you can make it a configuration parameter (either an environment variable, a Java property (i.e. java -Dyour.file.here=/tmp/files ...
), a context parameter set in the web.xml, a configuration parameter stored in your database via a web form, etc.). Then it's up to the deployer to set up this directory for you.
如果您确实需要一个目录,您可以将其设置为配置参数(环境变量、Java 属性(即java -Dyour.file.here=/tmp/files ...
)、web.xml 中设置的上下文参数、通过 Web 表单存储在数据库中的配置参数等.) 然后由部署者为您设置此目录。
However, if you need to actually later serve up that file, you will either need a container specific mechanism to "mount" external directories in to your web app (Glassfish as "alternate doc roots", others have similar concepts), or you will need to write a servlet/filter to serve up file store outside of your web app. This FileServletis quite complete, and as you can see, creating your own, while not difficult, isn't trivial to do it right.
但是,如果您需要稍后实际提供该文件,您将需要一个特定于容器的机制来将外部目录“挂载”到您的 Web 应用程序中(Glassfish 作为“备用文档根”,其他人有类似的概念),或者您将需要编写一个 servlet/过滤器来在您的 Web 应用程序之外提供文件存储。这个FileServlet非常完整,正如您所见,创建您自己的FileServlet虽然并不困难,但要做好它并非易事。
Edit:
编辑:
The basic gist is the same, but rather than using "getRealPath", simply use "getInitParameter".
基本要点是相同的,但不使用“getRealPath”,只需使用“getInitParameter”。
So:
所以:
String filePath = getServletContext().getInitParameter("storedFilePath") + "/" + fileName;
And be on your way.
并在路上。
Edit again:
再次编辑:
As for the contents of the path, I'd give it an absolute path. Otherwise, you would need to KNOW where the app server sets its default path to during exeuction, and each app server may well use different directories. For example, I believe the working directory for Glassfish is the config directory of the running domain. Not a particularly obvious choice.
至于路径的内容,我会给它一个绝对路径。否则,您需要知道应用服务器在执行期间将其默认路径设置为何处,并且每个应用服务器很可能使用不同的目录。例如,我认为 Glassfish 的工作目录是运行域的 config 目录。不是特别明显的选择。
So, use an absolute path, most definitely. That way you KNOW where the files will go, and you can control the access permissions at the OS level for that directory, if that's necessary.
因此,绝对使用绝对路径。这样您就知道文件的去向,并且如果有必要,您可以在操作系统级别控制该目录的访问权限。