Tomcat:1 war,部署 2x,2 配置
Tomcat: 1 war, deployed 2x, 2 configs
简化情况:
- 我有 1 个 Tomcat 容器和 1 个使用数据库的 WAR。
- 数据库配置位于属性文件中(在 war)。
- 我部署了 WAR 2 次,一个 webapp 在 contextpath
/a
上,一个 webapp 在 contextpath /b
上。
- 两个 webapps 现在 指向相同的数据库(相同的 cfg)。
我想要的是每个webapp指向一个不同的数据库。因此,/a
上的 webapp 指向数据库 A 而 /b
上的 webapp 指向数据库 B.
你会如何解决这个问题? (不拆分 war 本身)
您可以通过 Tomcat 的 context.xml 配置来完成,而无需拆分您的代码。
您可以定义两个上下文,例如 /a
和 /b
以及两个不同的全局数据源 "sharedDataSourceA" 和 "sharedDataSourceB"。您可以将不同的全局数据源绑定到具有相同名称的这些上下文,例如 "appDataSource"。
<GlobalNamingResources>
...
<Resource name="sharedDataSourceA"
global="sharedDataSourceA"
type="javax.sql.DataSource"
factory="org.apache.tomcat.jdbc.pool.DataSourceFactory"
alternateUsernameAllowed="true"
username="bar"
password="barpass"
...
<Resource name="sharedDataSourceB"
global="sharedDataSourceB"
type="javax.sql.DataSource"
factory="org.apache.tomcat.jdbc.pool.DataSourceFactory"
alternateUsernameAllowed="true"
username="bar"
password="barpass"
...
...
</GlobalNamingResources>
<Context path="/a"...>
...
<ResourceLink
name="appDataSource"
global="sharedDataSourceA"
type="javax.sql.DataSource"
factory="org.apache.naming.factory.DataSourceLinkFactory"
username="foo"
password="foopass"
...
</Context>
<Context path="/b"...>
...
<ResourceLink
name="appDataSource"
global="sharedDataSourceA"
type="javax.sql.DataSource"
...
</Context>
然后在您的代码中,您可以通过 jndi 查找将数据源绑定到 "appDataSource"。将相同的 war 部署到 /a
和 /b
。他们将在不同的数据库上工作。
您可以通过编程方式获取当前上下文并根据获取的值配置数据源。例如使用 javax.servlet.ServletContext.getContextPath().
您也可以根据上下文名称加载属性文件。
getContextPath() was suggested, and here is a technique to use it with getInitParameter()
举个例子,如果你有两个上下文:“/dev”和“/prod” - 都是相同的 - 而你使用以下条目设置您的 web.xml 文件:
<context-param>
<param-name>database_ip_prod</param-name>
<param-value>192.168.1.10</param-value>
</context-param>
<context-param>
<param-name>database_ip_dev</param-name>
<param-value>127.0.0.1</param-value>
</context-param>
并且使用这样的方法:
public String getContextInitParam(
javax.servlet.ServletContext context, String key) {
key += context.getContextPath().replace("/","_");
return context.getInitParameter(key);
}
来自 jsp 或 servlet 的这样的调用:
getContextInitParam(request.getServletContext(), "database_ip");
会 return 192.168.1.10 在 /prod 上下文中,127.0.0.1 在 /dev 上下文中。
简化情况:
- 我有 1 个 Tomcat 容器和 1 个使用数据库的 WAR。
- 数据库配置位于属性文件中(在 war)。
- 我部署了 WAR 2 次,一个 webapp 在 contextpath
/a
上,一个 webapp 在 contextpath/b
上。 - 两个 webapps 现在 指向相同的数据库(相同的 cfg)。
我想要的是每个webapp指向一个不同的数据库。因此,/a
上的 webapp 指向数据库 A 而 /b
上的 webapp 指向数据库 B.
你会如何解决这个问题? (不拆分 war 本身)
您可以通过 Tomcat 的 context.xml 配置来完成,而无需拆分您的代码。
您可以定义两个上下文,例如 /a
和 /b
以及两个不同的全局数据源 "sharedDataSourceA" 和 "sharedDataSourceB"。您可以将不同的全局数据源绑定到具有相同名称的这些上下文,例如 "appDataSource"。
<GlobalNamingResources>
...
<Resource name="sharedDataSourceA"
global="sharedDataSourceA"
type="javax.sql.DataSource"
factory="org.apache.tomcat.jdbc.pool.DataSourceFactory"
alternateUsernameAllowed="true"
username="bar"
password="barpass"
...
<Resource name="sharedDataSourceB"
global="sharedDataSourceB"
type="javax.sql.DataSource"
factory="org.apache.tomcat.jdbc.pool.DataSourceFactory"
alternateUsernameAllowed="true"
username="bar"
password="barpass"
...
...
</GlobalNamingResources>
<Context path="/a"...>
...
<ResourceLink
name="appDataSource"
global="sharedDataSourceA"
type="javax.sql.DataSource"
factory="org.apache.naming.factory.DataSourceLinkFactory"
username="foo"
password="foopass"
...
</Context>
<Context path="/b"...>
...
<ResourceLink
name="appDataSource"
global="sharedDataSourceA"
type="javax.sql.DataSource"
...
</Context>
然后在您的代码中,您可以通过 jndi 查找将数据源绑定到 "appDataSource"。将相同的 war 部署到 /a
和 /b
。他们将在不同的数据库上工作。
您可以通过编程方式获取当前上下文并根据获取的值配置数据源。例如使用 javax.servlet.ServletContext.getContextPath().
您也可以根据上下文名称加载属性文件。
getContextPath() was suggested, and here is a technique to use it with getInitParameter()
举个例子,如果你有两个上下文:“/dev”和“/prod” - 都是相同的 - 而你使用以下条目设置您的 web.xml 文件:
<context-param>
<param-name>database_ip_prod</param-name>
<param-value>192.168.1.10</param-value>
</context-param>
<context-param>
<param-name>database_ip_dev</param-name>
<param-value>127.0.0.1</param-value>
</context-param>
并且使用这样的方法:
public String getContextInitParam(
javax.servlet.ServletContext context, String key) {
key += context.getContextPath().replace("/","_");
return context.getInitParameter(key);
}
来自 jsp 或 servlet 的这样的调用:
getContextInitParam(request.getServletContext(), "database_ip");
会 return 192.168.1.10 在 /prod 上下文中,127.0.0.1 在 /dev 上下文中。