在 Java Web 应用程序 (WAR) 中存储配置文件的最佳位置是啥?

Posted

技术标签:

【中文标题】在 Java Web 应用程序 (WAR) 中存储配置文件的最佳位置是啥?【英文标题】:What is the best place to store a configuration file in a Java web application (WAR)?在 Java Web 应用程序 (WAR) 中存储配置文件的最佳位置是什么? 【发布时间】:2010-09-10 21:47:48 【问题描述】:

我创建了一个 Web 应用程序 (WAR) 并将其部署在 Tomcat 上。在 webapp 中有一个页面,其中包含管理员可以输入一些配置数据的表单。我不想将这些数据存储在 DBMS 中,而只是存储在文件系统上的 XML 文件中。放在哪里?

我想将文件放在部署应用程序本身的目录树中的某个位置。我的配置文件应该在 WEB-INF 目录中吗?还是放在别的地方?

在 servlet 中用于查找目录绝对路径的 Java 代码是什么?还是可以通过相对路径访问?

【问题讨论】:

请注意,servlet 引擎没有默认机制 - 您需要做出特定于供应商的假设。 【参考方案1】:

我们所做的是将它放在服务器上的单独目录中(您可以使用 /config、/opt/config、/root/config、/home/username/config 或任何您想要的东西)。当我们的 servlet 启动时,它们会读取 XML 文件,从中获取一些信息(最重要的是 DB 连接信息),仅此而已。

我问过我们为什么要这样做一次。

将所有内容存储在数据库中会很好,但显然您不能将数据库连接信息存储在数据库中。

您可以在代码中硬编码一些东西,但这很丑陋,原因有很多。如果信息必须更改,您必须重新构建代码并重新部署。如果有人获得了您的代码或 WAR 文件的副本,他们就会获得该信息。

把东西放在 WAR 文件中看起来不错,但如果你想改变很多东西,那可能是个坏主意。问题是,如果您必须更改信息,那么下次重新部署时,它将覆盖该文件,因此您在 WAR 内置版本中未记得更改的任何内容都会被遗忘。

文件系统中特殊位置的文件对我们来说非常有效。它没有任何大的缺点。你知道它在哪里,它是单独存储的,如果它们都需要不同的配置值(因为它不是 WAR 的一部分),那么可以很容易地部署到多台机器上。

我能想到的唯一其他可行的解决方案是将数据库中的所有内容都保留在数据库中,但数据库登录信息除外。这将来自通过 JVM 检索的 Java 系统属性。这是上面 Hans Doggen 提到的 Preferences API 的事情。我不认为它在我们的应用程序最初开发时就已经存在,如果它没有被使用的话。

至于访问配置文件的路径,只是文件系统上的一个文件。您无需担心网络路径。因此,当您的 servlet 启动时,它只需在“/config/myapp/config.xml”(或其他)打开文件,它就会找到正确的东西。只是硬编码这个路径对我来说似乎没什么害处。

【讨论】:

您可以将“config”目录放在服务器的类路径上,而不是引用文件的完整路径,然后使用 ClassLoader.getResource()。 我们在tomcat启动时指定一个系统属性。我们的应用程序从这个系统属性中获取我们的配置目录,因此我们可以在服务器之间使用不同的配置目录。 在我目前正在处理的应用程序中,我们将配置文件存储在应用程序之外的位于 USER_HOME 目录中的文件夹中。在启动时,应用程序从位置 String absoluteConfigPath = System.getProperty("user.home") + File.separator + ".myapp" + File.separator + "config.xml"; 获取文件 只是一个小注释:根据文件系统层次结构指南tldp.org/LDP/Linux-Filesystem-Hierarchy/html/opt.html,所有文件都应该放在 /opt/'package'/config 下,其中 'package' 是程序的名称。 如果您有多个环境(例如测试和登台)在同一个 tomcat 中运行,这将如何工作?因为当你只有一个 tomcat 时,你不能为每个环境指定一个系统属性。【参考方案2】:

WEB-INF 是放置配置文件的好地方。下面是一些从 servlet 中获取目录绝对路径的代码。

public void init(ServletConfig servletConfig) throws ServletException
    super.init(servletConfig);
    String path = servletConfig.getServletContext().getRealPath("/WEB-INF")

【讨论】:

这不是一种兼容的方法 - servlet 规范不保证 getRealPath() 将返回一个有效的(非空)路径,甚至完全解包战争(恕我直言,Weblogic 将不将文件从 .war 提取到磁盘)。 如果您有开发、测试、预生产和生产环境,这将不起作用,因为每个环境都需要一个单独的 .war。您应该能够部署一次配置,然后通过环境传播相同的战争......【参考方案3】:

将其放入WEB-INF 将对尝试通过 URL 直接访问它的用户隐藏 XML 文件,所以是的,我会说将其放入 WEB-INF

【讨论】:

【参考方案4】:

我不会将它存储在应用程序文件夹中,因为那样会用新的应用程序部署覆盖配置。

我建议你看看 Preferences API,或者在 users 文件夹中写一些东西(运行 Tomcat 的用户)。

【讨论】:

【参考方案5】:

这个问题的答案取决于您打算如何读取和写入该配置文件。

例如,Spring 框架让您能够use XML configuration files(或Java 属性文件);这些可以存储在您的类路径中(例如,在 WEB-INF 目录中)、文件系统上的任何其他位置,甚至是内存中。如果您为此使用 Spring,那么存储配置文件最简单的位置是在您的 WEB-INF 目录中,然后使用 Spring 的 ClassPathXmlApplicationContext 类来访问您的配置文件。

但同样,这完全取决于您计划如何访问该文件。

【讨论】:

【参考方案6】:

如果是您的自定义配置,WEB-INF 是一个好地方。但有些库可能需要配置驻留在 WEB-INF/classes 中。

【讨论】:

以上是关于在 Java Web 应用程序 (WAR) 中存储配置文件的最佳位置是啥?的主要内容,如果未能解决你的问题,请参考以下文章

AWS Java - 未找到包含在我的 .War 包中的参考文件

Java Web 应用程序应该在哪里存储它的数据?

如何在 tomcat 上部署 Java Web 应用程序(.war)?

将java web项目打包war文件然后发布到Tomcat,

使用 Google AppEngine 创建 Java Web 服务

Web 服务作为 JAR 文件,还是另一个 WAR 中的 WAR?