为Web应用程序存储临时数据的最佳实践

28

我的最新项目可以从数据库中生成包含信息的文档。

因此,我会按需将文档模板复制到一个临时文件夹,并进行修改。我这样做是因为每个模板在修改期间都必须可用。

之后,用户通过来自我的Web应用程序的下载链接获得他的文档。

我的问题是:存储Web应用程序数据的最佳实践是什么?我认为使用temp文件夹不错。但是,由于我必须自己删除数据,所以我考虑将其放置在tomcat webapp文件夹旁边的WAR文件夹内。

我在Windows 2003上使用Tomcat作为主机系统。 我使用Grails、Java和Maven进行项目开发...不知道这些信息是否有用。

编辑:
我问这个平凡的问题的主要原因是……如果我负责创建/删除我的临时数据……是否仍然使用系统上的temp文件夹是一种良好的实践?我对此不确定......

4个回答

36

在Web应用程序中存储(敏感)用户特定文件时,确保将其存储在/WEB-INF中的某个位置,并使用Servlet访问它们,该Servlet(间接地)检查已登录的用户,否则它对任何用户/黑客都是可访问的。优点是可以通过ServletContext#getResource()#getRealPath()方便地以编程方式访问。缺点是每当重新部署Web应用程序时,这些文件都会丢失。

您还可以将它们存储在默认临时文件夹中。优点是可以通过标准API(如File#createTempFile()System.getProperty("java.io.tmpdir"))访问它。临时文件夹的缺点是,无法从Java控制由操作系统控制的文件夹清理,因此当您关闭资源但仍然需要它时,可能会导致文件丢失。

您还可以将它们存储在Web应用程序之外的固定文件夹中。它的优点是每当您重新部署Web应用程序时,内容不会丢失。缺点是您需要使用足够的OS权限自己创建该文件夹,而这在第三方主机上可能不适用。

清理自己的临时资源当然属于您自己需要执行的任务。我不认为这是一个问题。

权衡一下优缺点即可。


我不知道操作系统可以决定清理临时文件夹。你能详细说明一下吗? - Eli Acherkan
1
大多数服务器系统每天/每周/每月运行一次cron作业,从/tmp中删除所有N天之前的文件。这是为了确保磁盘空间不会因为有人忘记清理而耗尽。 - Aaron Digulla
1
@EliAcherkan:tmp 应该无论如何都应该让你想起些什么。 - Mr_and_Mrs_D
仅将数据写入数据库而不保存临时文件是否有任何好处? - Jeff

13
  • 将信息存储在Web应用程序文件夹中并不总是有效的。某些应用服务器不会展开部署的WAR文件,因此Web应用程序没有“工作目录”。一些系统管理员还会限制Web应用程序对文件系统的访问(这取决于安全管理器策略)。
  • 临时文件应该用于临时数据。可以根据需要重构的数据。不要使用用户应下载的临时文件。例如,当系统认为它应该清理临时文件或重新启动应用程序服务器时,用户仍然希望下载这些文件,尽管这些文件可能已经被删除了。
  • 存储此类数据的正确位置是数据库。您的文档实际上不是临时文件。使用数据库来存储文档,并将数据库用作文档缓存。然后,您可以实现自己的清理策略。它还可作为持久性存储,因此您不必担心服务器重新启动。此外,您还可以在其中添加其他元数据,例如最后访问时间或访问计数器,并轻松地向用户提供他创建的文档列表。如果您的文档处理库需要java.io.File进行操作,则只需将文档从数据库存储到临时文件中,开始处理并将其读回数据库即可。

7
一个Web容器提供了一个上下文属性,指向临时目录:
Servlet规范SRV.3.7.1 临时工作目录
每个servlet上下文都需要一个临时存储目录。Servlet容器必须为每个servlet上下文提供一个私有的临时目录,并通过ServletContext.TEMPDIR (javax.servlet.context.tempdir) 上下文属性使其可用。与该属性相关联的对象必须是java.io.File类型。
示例:
File appTempDir = getServletContext().getAttribute(ServletContext.TEMPDIR);
File tempFile = File.createTempFile("process1", ".txt", appTempDir);
tempFile.deleteOnExit();
try {
    ...
} finally {
    tempFile.delete();
}

3
补充一下:使用 File tmpDir = (File)getServletContext().getAttribute(ServletContext.TEMPDIR); 将会获取到由 Servlet 容器提供的当前 Web 应用程序的临时文件目录。请注意,不要改变原文的含义,尽可能地将翻译变得通俗易懂。 - daiscog
这段代码似乎无效。 - Jeef
@Jeef 你为什么这么想? - dajood
因为它在运行时会抛出错误,所以它无法正常运行。 - Jeef
1
<% java.io.File tmpDir = java.io.File)application.getAttribute(ServletContext.TEMPDIR);
%> <%=tmpDir.toString()%>在jsp中使用Tomcat会得到以下结果:C:\Daten\apache-tomcat-8.0.8\work\Catalina\localhost\ROOT
- weberjn

5
我认为临时文件应该放在临时文件夹中。在您的情况下,您会自己删除文件,但如果文件删除操作存在错误怎么办?或者如果服务器在文件被删除之前关闭怎么办?如果写入临时文件夹,则至少有一些希望稍后(手动或通过某个进程)清理文件。
即使应用程序希望存储持久数据(即非临时数据),我认为它也不应存储在Tomcat目录中,因为每当您部署新版本应用程序(甚至安装新版本Tomcat)时,这些目录往往会被删除或覆盖。
有用的方法:

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接