37

I'm pre-packaging a JSP web-app that relies on some file path settings found within web.xml. These settings are unknown at packaging time, because they reference a path the customer will set when deploying the entire application (of which the web-app is a management interface).

It seems that the easiest way to avoid tokens and file modifications in my installer script, is to ask the user for an install location, set this location as an environment variable (e.g JAVA_HOME), and have web.xml always reference that variable.

Is there a way to reference an environment variable value from within web.xml? Google searches lead to the J2EE method of SETTING environment variables from ejb xml files. This is not what I'm looking for.

4

7 回答 7

40

您可以在任何 tomcat xml 配置文件中使用 Ant 样式的变量替换,例如:

<servlet-mapping>
    <servlet-name>mvc-dispatcher</servlet-name>
    <url-pattern>${foo}</url-pattern>
</servlet-mapping>

Java 系统属性(sysprop)foo在哪里。

你不能直接使用操作系统环境变量(envvars),我认为......

要使用 envvars,你可以把

set "CATALINA_OPTS=-DsomeJavaSysProp=%SOME_OS_ENVVAR%"

bin/setenv.bat(或类似地在bin/setenv.sh*nix 中)。您可能需要创建该文件。Tomcat 将在启动时运行此文件。

作为CATALINA_OPTS一个 envvar(与命令行选项相反),它不应该被系统上的其他用户看到(保存古老的 Unix),尽管我没有对此进行测试。

http://tomcat.apache.org/tomcat-7.0-doc/config/

如果您使用的是 Spring,您可以创建一个<context:property-placeholder/>bean,然后直接在 Spring XML 配置文件中使用 envvars 或 sysprops(虽然不是web.xml)。

于 2013-10-15T20:17:26.893 回答
12

我认为您不想使用环境变量(我认为无法从 web.xml 访问),而是使用环境条目[ 1、2 ]。像这样:

<env-entry>
    <env-entry-name>Bla/SomeFilePath</env-entry-name>
    <env-entry-type>java.lang.String</env-entry-type>
    <env-entry-value>/opt/bla</env-entry-value>
</env-entry>

你可以使用 SomeFilePath 像:

InitialContext ic = new InitialContext();
String s = (String) ic.lookup("java:comp/env/ejb/Bla/SomeFilePath");
于 2009-09-11T02:53:56.507 回答
9

基本上,你不会那样做。应该包含事物的web.xml默认值,是的,但是您应该在实际进行部署时覆盖它们。如果您要部署到 Tomcat,您可以通过在context.xml用于部署的 中包含适当的条目来执行此操作。例如:

<Context path="/app">
    <!-- For things described by webapp parameters -->
    <Parameter name="foobar" value="grill" />

    <!-- For things described by environment entries -->
    <Environment name="Bla/SomeFilePath" type="java.lang.String"
            value="/opt/bla" />
</Context>

其他容器将有自己的机制来执行此操作。您必须查看他们的文档(或使您的帮助请求更加集中)。

于 2011-01-05T17:16:48.730 回答
5

可以在 xml 文件中访问环境变量,如下所示:

${env.ENVIRONMENT_VARIABLE_NAME}

显然用户帐户设置和访问问题可能存在问题,但我已经尝试使用系统变量并且它有效!

于 2018-07-20T13:34:02.470 回答
1

您必须按顺序放置 env-entry:

<env-entry>
  <env-entry-name>maxAmount</env-entry-name>
  <env-entry-type>java.lang.String</env-entry-type>
  <env-entry-value>aString</env-entry-value>
</env-entry>

否则您将在 web.xml 上出现验证错误

参考:https ://community.oracle.com/thread/840452?tstart=0

于 2014-04-20T04:52:54.130 回答
1

我并不完全清楚您的限制,但也许您可以这样做(我假设它是您要配置的 init-param):

1) 在 web.xml 中保留未指定的变量
2) 创建一个 ServletContextListener 并将其添加到您的应用程序
3) 侦听 servlet 的初始化
4) 在该点设置 servlet 的 init-param

我用类似的问题尝试了这个,但它失败了,因为事实证明第 3 方 servlet(我也不想弄乱)实际上根本不是 servlet,所以上下文从来没有初始化。但也许这里有机会......

于 2013-11-20T20:47:35.350 回答
0

如果您使用的是Spring - 您可以FilterConfig通过ConfigurableBeanFactory.resolveEmbeddedValue来启用属性占位符插值支持web.xml

使 FilterConfig 参数可解析的代理类。

public class ResolvableFilterConfig implements FilterConfig {

    private final FilterConfig source;
    private final ConfigurableBeanFactory resolver;

    public ResolvableFilterConfig(FilterConfig source, ConfigurableBeanFactory resolver) {
        this.source = source;
        this.resolver = resolver;
    }

    @Override
    public String getFilterName() {
        return source.getFilterName();
    }

    @Override
    public ServletContext getServletContext() {
        return source.getServletContext();
    }

    @Override
    public String getInitParameter(String name) {
        final String value = source.getInitParameter(name);
        return resolver.resolveEmbeddedValue(value);
    }

    @Override
    public Enumeration<String> getInitParameterNames() {
        return source.getInitParameterNames();
    }
}

过滤器实现示例代码

    @Override
    public void init(FilterConfig config) throws ServletException {
        // configure
        final ServletContext servletContext = config.getServletContext();
        final AbstractApplicationContext aac = (AbstractApplicationContext) getRequiredWebApplicationContext(servletContext);
        final ConfigurableBeanFactory beanFactory = aac.getBeanFactory();
        config = new ResolvableFilterConfig(config, beanFactory);
        // ... do the rest
    }
于 2020-08-27T13:22:56.630 回答