【发布时间】:2017-01-27 17:25:58
【问题描述】:
我需要一些关于如何使用 Tomcat 7 简化 Web 应用配置的想法。
我有一个 Web 应用程序,它使用 Tomcat 的 context.xml 配置文件中定义的两个资源:一个邮件会话和一个 JDBC 数据源。
<Resource name="mail/MailService" ...
<Resource name="jdbc/JDBCDatasource" ...
为了在 web 应用程序中使用它们,我必须在 web.xml 部署描述符中声明两个引用,指定相同的名称:
<resource-ref>
<res-ref-name>mail/MailService</res-ref-name>
...
<resource-ref>
<res-ref-name>jdbc/JDBCDatasource</res-ref-name>
....
然后,在应用程序代码中,我必须再次使用它们的名称查找资源:
Context ctx = new InitialContext();
Session sn = (Session) ctx.lookup("java:comp/env/mail/MailService");
DataSource ds = (DataSource) ctx.lookup("java:comp/env/jdbc/JDBCDatasource");
问题是系统管理员可以更改资源的名称;所以,我不能硬编码资源的名称。我可以使用上下文参数或类似的东西来允许系统管理员为每个资源指定选择的名称,但考虑到我必须使用资源引用部分,我不想指定相同的名称在 web.xml 文件中两次(一个用于参数,另一个用于 ref)。复制配置有点复制某人犯错的机会,我想尽量减少错误配置的机会..
我在网上搜索了 web.xml 中的变量之类的东西,但我没有找到任何东西.. 有人对此有什么想法吗?
=== 分辨率 ===
按照 Brett 指出的思路,我这样做是为了避免重复配置:
首先,将资源配置从 Tomcat 的 context.xml 移到 Tomcat 的 server.xml 中,在 GlobalNamingResources 区域内,使用通用名称:
<GlobalNamingResources>
...
<Resource name="mail/MailService1" ...
<Resource name="jdbc/JDBCDatasource1" ...
...
然后,我在应用程序 context.xml 文件中创建了两个 ResourceLink(注意不是 Tomcat 文件),其中每个链接都有应用程序使用的确切名称,并通过全局属性指向资源:
<ResourceLink name="jdbc/MyAppJDBCService" global="jdbc/JDBCDatasource1" type="javax.sql.DataSource"/>
<ResourceLink name="mail/MyAppMailService" global="mail/MailService1" type="javax.mail.Session"
/>
这样,应用程序的 web.xml 中的资源引用就不再需要了。
最后,在应用程序源代码中,我将查找部分更改为使用 context.xml 中指定的名称(而不是 server.xml 中使用的名称):
Context ctx = new InitialContext();
Session sn = (Session) ctx.lookup("java:comp/env/mail/MyAppMailService");
DataSource ds = (DataSource) ctx.lookup("java:comp/env/jdbc/MyAppJDBCService");
通过此设置,管理员负责配置 Tomcat 的 server.xml 文件中的资源,使用他/她想要的名称,部署者只需将该名称映射到应用程序使用的名称,只需修改应用的 context.xml。
现在很简单,但我以前做的很糟糕。
【问题讨论】: