Configuration Glassfish/Java EE 5 web服务的应用程序配置文件

Configuration Glassfish/Java EE 5 web服务的应用程序配置文件,configuration,properties,jakarta-ee,glassfish,Configuration,Properties,Jakarta Ee,Glassfish,我正在尝试编写一些简单的Java web服务,以便我们可以从.NET调用Java代码。到目前为止,我在Glassfish下得到了一个概念证明。当IDE完成所有工作时,非常简单 现在我真的陷入了Java中那些应该非常简单的东西。例如,我想将配置外部化,这样我就可以在不重新编译的情况下更改连接字符串/用户名/应用程序变量等内容 在.NET中,您只需在网站根目录的web.config文件中粘贴一些字符串并使用:ConfigurationManager.AppSettings[“whateverIwan

我正在尝试编写一些简单的Java web服务,以便我们可以从.NET调用Java代码。到目前为止,我在Glassfish下得到了一个概念证明。当IDE完成所有工作时,非常简单

现在我真的陷入了Java中那些应该非常简单的东西。例如,我想将配置外部化,这样我就可以在不重新编译的情况下更改连接字符串/用户名/应用程序变量等内容

在.NET中,您只需在网站根目录的web.config文件中粘贴一些字符串并使用:
ConfigurationManager.AppSettings[“whateverIwant”]

我可以让java.util.Properties做我想做的事情(从一个独立的客户机),但是我不知道把.Properties文件放在哪里,以及如何从web服务中获取它的路径


我还需要我的方法在WebSphereApplicationServer中工作。谢谢

不幸的是,应用程序配置依赖于容器。通常,您可以通过JNDI访问配置。我最近使用的方法如下:

  • 使数据库可用于您的应用程序(通过JNDI,使用Glassfish数据库“向导”)。这是一个依赖于容器的部件
  • 创建一个实体bean,从数据库中反序列化您的设置。这里最简单的解决方案是这样:
@实体 公共班级设置{ @身份证 私有字符串名称; 私有字符串值; ... } 然后是执行
em.find(Setting.class,“whateveriwant”).getValue()
的问题。或者,您可以创建一个将所有设置作为属性的实体bean。
无论采用哪种方法,这种方法都将容器依赖性降至最低。

唉,JavaEE在应用程序配置方面有一个巨大的漏洞

您的最佳选择是:

  • 使用JNDI在应用服务器环境中存储配置。这是很难做到的便携性,痛苦,绝对是一个噩梦的用户做任何配置。配置UI取决于正在使用的应用程序服务器和版本,并且可能是特定于该应用程序服务器的仅限命令行的实用程序

  • 使用Preferences API存储配置,并生成自己的UI来编辑配置。这没关系。。。除了无法控制刷新和重新初始化设置的时间。某些应用服务器会在重新部署应用程序时执行此操作,而您可能不希望这样做

总而言之,情况绝对糟糕。对于应用服务器来说,没有干净、合理的方法为应用提供一个简单的属性映射和UI,以便使用应用服务器的管理工具对其进行编辑

我尝试使用web上下文参数来解决这个问题,但发现它们也有缺陷。Glassfish忽略的不仅仅是设置的第一个web上下文参数,如果没有servlet上下文,它们很难访问,因此您无法在整个应用程序中轻松访问它们

如果有人有更好的答案,我很乐意听到,因为对于一个已经经历了几次主要迭代的规范来说,目前的情况似乎非常惊人


另请参见:

正如其他人所提到的,它在很大程度上取决于容器,但动态配置几乎总是存储在数据库中,而不是XML或.properties文件中

正如我看到的,这就像一个概念证明,这里有一个快速而肮脏的解决方案:(不要对生产代码这样做)使用系统属性。 缺点:每次更改都需要重新启动容器,但不需要重新编译应用程序

要在Glassfish中使用系统属性,您可以转到“配置->系统属性”部分并在那里添加属性。然后从应用程序内部调用

String myValue = System.getProperty("myProperty");

以获取值。所有java应用程序都支持这些属性,但我不知道如何在Websphere中配置它们。

到目前为止,我找到的最佳解决方案是“”。我已经在许多项目中成功地使用了

将以下代码放入ServletContextListener的contextInitialized方法中:

ServletContext sc = sce.getServletContext();
Properties systemProps = System.getProperties();            
String path = sc.getRealPath("WEB-INF/application.properties");
systemProps.load(new FileInputStream(path));

这将在WEB应用程序启动时从WEB应用程序的WEB-INF文件夹中读取application.properties。这将需要在每次配置更改时重新启动,但在我看来,这是应该的。

hmm。我真的怀疑在这个问题中使用“.net”标记的必要性。您可以使用MXbean来存储设置(属性映射=值)因此,您可以使用jconsole/visualvmI等工具在运行时读取/更新设置。我不明白为什么您会说这些系统属性是一个快速而肮脏的解决方案,而不是用于生产。据我所知,我认为它们在数据库存储之外,在极少数情况下,以及在生产中都有自己的位置。对于一些属性,这可能是可以的,但它们并不意味着要取代应用程序的完整配置。一个问题是关注点的分离,因为关注点可以从任何地方获得,因此仅由一个层使用的配置也可能在其他地方被误用。另一个问题是安全性,我不确定,但我认为它们在服务器上部署的所有应用程序之间共享,因为它们运行在同一个JVM中。如果部署了恶意应用程序并通过调用System.setProperty(“myProperty”、“fakeValue”)更改您的配置,会发生什么情况?它们是可变的超全局值。如果我们要走这条路,这是针对我们情况的最佳答案。我们使用的是配置存储系统,但需要在不同的glassfish服务器之间设置环境。我们希望在任何glassfish服务器上使用相同的war文件,因此我们的目标是将当前环境(本地、开发、生产等)从war中排除,以便我们知道从配置存储中获得什么配置。或者,我们考虑存储在配置存储中,并基于服务器检查环境,默认为本地。还有其他想法吗
ServletContext sc = sce.getServletContext();
Properties systemProps = System.getProperties();            
String path = sc.getRealPath("WEB-INF/application.properties");
systemProps.load(new FileInputStream(path));