如何通过 Java EE Web 应用程序将文件存储在服务器(Web 容器)上?
我开发了一个 Java EE Web 应用程序。该应用程序允许用户在浏览器的帮助下上传文件。用户上传文件后,该应用程序首先将上传的文件存储在服务器(它正在运行的服务器上)上,然后对其进行处理。
目前,我将文件存储在服务器上,如下所示:
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());
}
其中 formFile
表示上传的文件。
现在,问题是它在某些服务器上运行良好,但在某些服务器上 getServlet().getServletContext().getRealPath("")
返回 null
因此我得到的最终路径是 null/filename
并且该文件不会存储在服务器上。
当我检查 API 时 ServletContext.getRealPath()
方法,我发现以下内容:
public java.lang.String getRealPath(java.lang.String 路径)
返回包含给定虚拟路径的真实路径的字符串。例如,路径
"/index.html"
返回服务器文件系统上的绝对文件路径,该路径将由对"http://host/contextPath/index.html" 的请求提供服务
,其中 contextPath 是此 ServletContext 的上下文路径。返回的真实路径将采用适合运行 servlet 容器的计算机和操作系统的形式,包括正确的路径分隔符。如果 servlet 容器因任何原因无法将虚拟路径转换为真实路径(例如当内容可从 .war 存档中获取时),则此方法返回 null。
那么,是否有其他方法可以将文件存储在那些为 getServlet().getServletContext().getRealPath("")
返回 null
的服务器上
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.
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.
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.
When I checked the API for ServletContext.getRealPath()
method, I found the following:
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).
So, Is there any other way by which I can store files on those servers also which is returning null
for getServlet().getServletContext().getRealPath("")
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
根据规范,保证从 servlet 容器获得的唯一“真实”路径是临时目录。
您可以通过 ServletContext.gerAttribute("javax.servlet.context.tempdir") 获取该信息。但是,这些文件对于 Web 上下文不可见(即,您无法发布简单的 URL 来传递这些文件),并且无法以任何方式保证这些文件在 Web 应用程序或服务器重新启动后仍然存在。
如果您只是需要一个地方来短期存储工作文件,那么这对您来说很合适。
如果你确实需要一个目录,你可以将它作为一个配置参数(环境变量、Java 属性(即
java -Dyour.file.here=/tmp/files ...
)、 web.xml 中设置的上下文参数、通过 Web 表单存储在数据库中的配置参数等)。然后由部署者为您设置此目录。但是,如果您稍后需要实际提供该文件,您将需要一个特定于容器的机制来将外部目录“挂载”到您的 Web 应用程序中(Glassfish 作为“备用文档根”,其他人也有类似的概念),或者您将需要编写一个 Servlet/过滤器来在 Web 应用程序之外提供文件存储。这个 FileServlet 非常完整,并且您可以你看,创建自己的虽然并不困难,但要做好它也不是一件容易的事。
编辑:
基本要点是相同的,但不使用“getRealPath”,而是简单地使用“getInitParameter”。
所以:
那就上路吧。
再次编辑:
至于路径的内容,我会给它一个绝对路径。否则,您需要知道应用程序服务器在执行期间将其默认路径设置到哪里,并且每个应用程序服务器很可能使用不同的目录。例如,我认为 Glassfish 的工作目录是运行域的配置目录。不是一个特别明显的选择。
因此,绝对使用绝对路径。这样您就知道文件将去往何处,并且可以在操作系统级别控制该目录的访问权限(如果需要)。
By spec, the only "real" path you are guaranteed to get form a servlet container is a temp directory.
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.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.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 FileServlet is quite complete, and as you can see, creating your own, while not difficult, isn't trivial to do it right.
Edit:
The basic gist is the same, but rather than using "getRealPath", simply use "getInitParameter".
So:
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.
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.
不建议从 Java EE 容器写入文件系统,特别是如果您需要处理写入的数据:
如果这是一个选项,我会将文件存储在数据库中或使用 JCR 存储库(例如 Jackrabbit )。
Writing to the file system from a Java EE container is not really recommended, especially if you need to process the written data:
If this is an option, I would store the files in database or use a JCR repository (like Jackrabbit).