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

Mar*_* K. 37 java parameters ear war java-ee

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

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

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

在我的例子中,SOAP/WS端点只有简单的Key => Value对(String,String).

kgi*_*kis 27

有关读取WAR文件之外的属性文件,请参阅此问题.

请参阅此问题以从JNDI读取变量值.我相信这是最好的解决方案.您可以使用以下代码读取String变量:

Context initialContext = new InitialContext();
String myvar = (String) initialContext.lookup("java:comp/env/myvar");
Run Code Online (Sandbox Code Playgroud)

上面的代码适用于所有容器.在Tomcat中,您在conf/server.xml中声明以下内容:

<GlobalNamingResources ...>
  <Environment name="myvar" value="..."
         type="java.lang.String" override="false"/>
</GlobalNamingResources>
Run Code Online (Sandbox Code Playgroud)

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

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

这些是JNDI提供的好处:

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

  • 在许多组织中,配置由网络管理员执行.在某些情况下,只允许管理员配置密码或其他敏感数据.这些人可能没有多少XML经验. (4认同)
  • 在我的情况下,参数设置需要由"未经训练的"最终用户完成 - 导航复杂的XML文件以找到唯一需要更改的东西不是一个选项(风险太大他们改变了他们不应该做的事情)并打破整个容器.) (2认同)

Jas*_*her 11

在为不同的开发人员部署webapp时,我们有类似的配置要求,在Amazon的EC2上:我们如何将配置与二进制代码分开?根据我的经验,JNDI太复杂,并且在要使用的容器之间变化太大.此外,手动编辑XML非常容易受到语法错误的影响,因此这个想法被抛弃了.我们通过基于一些规则的设计解决了这个问题:

1)只应使用简单的name = value条目

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

这种设置允许我们在每个环境中使用不同的配置来完成具有完全一组编译二进制文件的dev/QA/release周期.没有密码/ etc捆绑在二进制文件中的风险,人们可以共享他们的配置来重新创建我们正在看到的问题.


Jar*_*red 10

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

这是一些示例代码(从内存中输入 - 我没有编译/测试过):

public void loadConfiguration() {
   String configUrlStr = System.getenv("CONFIG_URL"); // You'd want to use a more
                                                      // Specific variable name.
   if(configUrlStr == null || configUrlStr.equals("") {
       // You would probably want better exception handling, too.
       throw new RuntimeException("CONFIG_URL is not set in the environment."); 
   }


   try {
       URI uri = new URI(configUrlStr);
       File configFile = new File(uri);
       if(!configFile.exists()) {
          throw new RuntimeException("CONFIG_URL points to non-existant file");
       }
       if(!configFile.canRead()) {
          throw new RuntimeException("CONFIG_URL points to a file that cannot be read.");
       }
       this.readConfiguration(configFile);
   } catch (URISyntaxException e) {
       throw new RuntimeException("Malformed URL/URI in CONFIG_URL");
   }



}
Run Code Online (Sandbox Code Playgroud)


Aar*_*ers 9

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

这很简单,也很简单......除非我遗漏了什么

  • 虽然这听起来太简单而不好,但它确实是一个很好的选择.许多应用服务器都有添加到类路径的路径,因此您可以在那里删除.properties文件. (2认同)