如何在EAR或WAR之外存储JavaEE配置参数?

如何在EAR或WAR之外存储JavaEE配置参数?,java,parameters,jakarta-ee,war,ear,Java,Parameters,Jakarta Ee,War,Ear,我想在web项目之外存储web项目的配置(ear/war文件)。 应用程序不应该知道它在哪个容器中运行(WebSphere/JBoss等) 处理这个问题的最佳方法是什么 JNDI是一种干净的方式吗?如果JNDI可以解决我的问题,我应该如何配置它?(自定义对象?) 在我的例子中,SOAP/WS端点只有简单的键=>值对(字符串,字符串) 我使用环境变量指向包含我的配置的URL(可能是一个文件://URL)。这是非常简单的设置,不需要JNDI基础设施 下面是一些示例代码(从内存键入-我还没有编译/测试

我想在web项目之外存储web项目的配置(ear/war文件)。 应用程序不应该知道它在哪个容器中运行(WebSphere/JBoss等)

处理这个问题的最佳方法是什么

JNDI是一种干净的方式吗?如果JNDI可以解决我的问题,我应该如何配置它?(自定义对象?)


在我的例子中,SOAP/WS端点只有简单的键=>值对(字符串,字符串)

我使用环境变量指向包含我的配置的URL(可能是一个文件://URL)。这是非常简单的设置,不需要JNDI基础设施

下面是一些示例代码(从内存键入-我还没有编译/测试):

有关在WAR文件之外读取属性文件的信息,请参见此

有关从JNDI读取变量值的信息,请参见此。我相信这是最好的解决办法。您可以使用以下代码读取字符串变量:

Context initialContext = new InitialContext();
String myvar = (String) initialContext.lookup("java:comp/env/myvar");
上述代码适用于所有容器。在Tomcat中,在conf/server.xml中声明以下内容:


以上内容将创建一个全局资源。也可以在应用程序上下文中定义资源。在大多数容器中,JNDI资源可以通过MBeans管理控制台获得。其中一些提供了一个图形界面来编辑它们。在进行更改时,最多需要重新启动应用程序

如何定义和编辑JNDI资源是特定于容器的。配置程序/管理员的工作是应用适当的设置

以下是JNDI提供的好处:

  • 您可以在WAR/EAR文件中定义参数的默认值
  • 参数可以在容器中轻松配置
  • 修改参数值时,无需重新启动容器

我最喜欢的地方是:环境变量和属性文件(正如上面Jared和kgiannakakis所建议的)

存储环境属性的数据库表

然而,另一个更简单的解决方案是让数据库表存储环境属性

如果应用程序使用数据库

  • 这相对容易设置
  • 提供了控制/更改值的非常简单的方法
  • 通过将其作为DB脚本的一部分,可以很好地将其集成到流程中

您可以只存储类路径上的普通java属性文件,然后只加载属性


这很直接,也很简单。。除非我遗漏了什么

在为不同的开发人员部署webapp时,我们有一个类似的配置要求,在Amazon的EC2上:如何将配置与二进制代码分离?根据我的经验,JNDI太复杂,不同容器之间的差异太大,无法使用。此外,手工编辑XML非常容易出现语法错误,因此放弃了这个想法。我们通过基于以下几条规则的设计解决了这一问题:

1) 只应使用简单的名称=值项

2) 只需更改一个参数即可加载新配置

3) 我们的WAR二进制必须是可重新配置的,不需要重新打包

4) 敏感参数(密码)永远不会打包在二进制文件中

对所有配置使用.properties文件,并使用
System.getProperty(“域”)要加载适当的属性文件,我们能够满足要求。但是,系统属性并不指向文件URL,而是创建了一个称为“域”的概念来指定要使用的配置。配置的位置始终为:
$HOME/appName/config/$DOMAIN.properties

因此,如果我想使用自己的配置运行我的应用程序,我可以通过将域设置为我的名称来启动应用程序:
-Ddomain=jason

启动时,应用程序加载文件:
/home/jason/appName/config/jason.properties

这使开发人员可以共享配置,这样我们就可以重新创建应用程序的相同状态以进行测试和部署,而无需重新编译或重新打包。然后使用域值从标准位置加载.properties,该位置不在绑定的WAR中

我可以使用生产配置在工作站上完全重新创建生产环境,如:
-Ddomain=ec2
哪个将加载:
/home/jason/appName/config/ec2.properties


这种设置允许我们在每个环境中使用不同的配置,使用一组编译的二进制文件进行开发/质量保证/发布周期。在二进制文件中没有捆绑密码/etc的风险,人们可以共享他们的配置来重新创建我们看到的问题。

+1:如果您已经在使用数据库,那么将配置参数存储在表中是最简单的解决方案。由于您已经拥有生产/开发/测试数据库,因此可以轻松地为不同的部署存储不同的值。在进行更改时,您甚至不必重新启动应用程序。但是,如何获取连接到数据库的连接信息(这正是我希望从该解决方案中获得的信息)?这是个鸡蛋问题。同意-杰瑞德。我想说,对于DB,您依赖具有相同JNDI字符串的JNDI。因此,您的应用程序将始终指向java:comp/db/datasource。关于数据库的配置信息(URL、用户、pwd等)存储在容器外部。DB属性将适用于URL、外部字符串和环境。依赖常量值等。一些容器提供将所有这些指定为JNDI,但并非所有(例如Websphere允许将字符串值与JNDI关联,据我所知,Weblogic不允许)都简单,它的缺点是,如果需要更改值,则需要重新启动容器。如果需要更改容器的位置,则只需重新启动容器
Context initialContext = new InitialContext();
String myvar = (String) initialContext.lookup("java:comp/env/myvar");