如何在 EAR 或 WAR 之外存储 Java EE 配置参数?
我想在 Web 项目之外存储 Web 项目的配置(ear/war 文件)。 应用程序不应该知道它正在哪个容器中运行(WebSphere/JBoss 等)。
处理这个问题的最佳方法是什么?
JNDI 是一种干净的方式吗? 如果JNDI可以解决我的问题,我应该如何配置呢? (自定义对象?)
在我的例子中,SOAP/WS 端点只有简单的 Key=>Value 对(字符串、字符串)。
I want to store configuration for a web project outside of the web project (ear/war file).
The application shouldn't know in which container it's running (WebSphere/JBoss etc.).
What is the best way to handle this?
Is JNDI a clean way? If JNDI can solve my problems, how should I configure it? (Custom Objects?)
In my case are there only simple Key=>Value pairs (String,String) for SOAP/WS endpoints.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(5)
请参阅此问题以了解读取属性WAR 文件之外的文件。
有关从 JNDI 读取变量值的信息,请参阅此问题。 我相信这是最好的解决方案。 您可以使用以下代码读取字符串变量:
上面的代码适用于所有容器。 在 Tomcat 中,您在 conf/server.xml 中声明以下内容:
上面将创建一个全局资源。 还可以在应用程序的上下文中定义资源。 在大多数容器中,JNDI 资源可通过 MBeans 管理控制台使用。 其中一些提供图形界面来编辑它们。 当进行更改时,最多需要重新启动应用程序。
JNDI 资源的定义和编辑方式是特定于容器的。 应用适当的设置是配置者/管理员的工作。
以下是 JNDI 提供的好处:
See this question for reading properties file outside of the WAR file.
See this question for reading variable values from JNDI. I believe that this is the best solution. You can read a String variable with this code:
The above code will work on all containers. In Tomcat you declare the following in conf/server.xml:
The above will create a global resource. It is also possible to define a resource in the context of application. In most containers the JNDI resources are available through a MBeans Management Console. Some of them offer a graphical interface to edit them. At most an application restart is needed, when a change is made.
How JNDI resources are defined and edited is container specific. It is the job of the configurator/administrator to apply the appropriate settings.
These are the benefits offered by JNDI:
在为不同的开发人员部署 Web 应用程序时,以及在 Amazon 的 EC2 上,我们有类似的配置要求:如何将配置与二进制代码分开? 根据我的经验,JNDI 太复杂,并且在使用的容器之间变化太大。 此外,手动编辑 XML 很容易出现语法错误,因此这个想法被放弃了。 我们通过基于以下规则的设计解决了这个问题:
1)仅应使用简单的名称=值条目
2)应仅通过更改一个参数即可加载新配置
3)我们的WAR二进制文件必须可重新配置而无需重新打包
4)敏感参数(密码)永远不会打包在二进制文件中
使用 .properties 文件进行所有配置,并使用 System.getProperty("domain"); 加载适当的属性文件,我们能够满足要求。 但是,系统属性并不指向文件 URL,而是创建了一个称为“域”的概念来指定要使用的配置。 配置的位置始终是:
$HOME/appName/config/$DOMAIN.properties
。因此,如果我想使用自己的配置运行我的应用程序,我可以通过将域设置为我的名称来启动应用程序:
-Ddomain=jason
启动时,应用程序加载文件:
/home/jason/appName/config/jason.properties
这使开发人员可以共享配置,以便我们可以重新创建应用程序的相同状态以进行测试和部署,而无需重新编译或重新打包。 然后使用域值从捆绑 WAR 之外的标准位置加载 .properties。
我可以使用如下生产配置在我的工作站上完全重新创建生产环境:
-Ddomain=ec2
这将加载:
/home/jason/appName/config/ec2.properties
此设置允许我们使用一组已编译的二进制文件进行开发/QA/发布周期,并在每个环境中使用不同的配置。 不存在将密码等捆绑在二进制文件中的风险,并且人们可以共享他们的配置来重现我们所看到的问题。
We had a similar configuration requirement when deploying a webapp for different developers, and on Amazon's EC2: how do we separate configuration from the binary code? In my experience, JNDI is too complex, and varies too much between containers to be used. Also, hand-editing XML is very susceptible to syntax errors, so was the idea was thrown out. We resolved this with a design based on a few rules:
1) only simple name=value entries should be used
2) new configurations should be loadable by changing only one parameter
3) our WAR binary must be reconfigurable w/o repackaging it
4) sensitive parameters (passwords) will never be packaged in the binary
Using .properties files for all configuration, and using
System.getProperty("domain");
to load the appropriate properties files, we were able to meet the requirements. However, the system property does not point to a file URL, instead we created a concept we call "domain" to specify the configuration to use. The location of the configuration is always:$HOME/appName/config/$DOMAIN.properties
.So if I want to run my app using my own configuration, I start the app by setting the domain to my name:
-Ddomain=jason
on startup, and the app loads the file:
/home/jason/appName/config/jason.properties
This lets developers share configurations so we can recreate the same state of the app for testing and deployment without recompiling or repackaging. The domain value is then used to load .properties from a standard location, outside of the bundled WAR.
I can completely recreate the production environment on my workstation by using the production configuration like:
-Ddomain=ec2
which would load:
/home/jason/appName/config/ec2.properties
This setup allows us to do have dev/QA/release cycles with exactly -one- set of compiled binaries, using different configurations in each environment. There's no risk of having passwords/etc bundled in the binaries, and people can share their configurations to recreate issues that we're seeing.
我使用环境变量指向其中包含我的配置的 URL(可能是 file:// URL)。 这设置起来非常简单,并且不需要 JNDI 基础设施。
这是一些示例代码(从内存中输入 - 我还没有编译/测试过这个):
I use an environment variable to point to a URL (which probably is a file:// URL) that has my configuration in it. This is very simple to setup and doesn't require the JNDI infrastructure.
Here's some sample code (typed from memory - I haven't compiled/tested this):
您可以只存储类路径上的普通 java 属性文件并加载属性吗?
它很简单而且非常简单..除非我错过了一些东西
you can just store then is a normal java properties file that is on the class path and just load the properties?
it is straightforward and pretty simple.. unless I am missing something
我最喜欢的地方是:环境变量和属性文件(如上面 Jared 和 kgiannakakis 所建议的那样。)
存储环境属性的数据库表
然而,另一种更简单的解决方案是使用数据库表存储环境属性。
如果您的应用程序使用数据库,
My favorite places are : Environment Variables and Properties files (as suggested by Jared and kgiannakakis above.)
Database Table storing environment properties
However one other simpler solutions is to have Database table storing environment properties.
If your application uses database