如何在非Servlet的Java文件中读取上下文参数/web.xml的值?

19

我有一个常规的Java文件,用于更新和查询MySQL数据库,但我需要将该文件中的可配置选项(如主机名、密码等)放入web.xml文件中(或者如果可以的话,放到另一个文件中,但最好是在web.xml中)。

但我不知道如何从普通的非Servlet Java文件中访问web.xml值。

或者,我需要读取XML文件(像读取其他XML文件一样...或者有快捷方法吗...)


1
你确实需要提到这个“常规非servlet Java文件”是在ServletContextListener#contextInitialized()中实例化和执行的(根据你之前的问题)。这将对正确答案产生很大的影响... - BalusC
你使用的是哪个服务器?Tomcat,JBoss,???。根据服务器不同,参数可以通过多种方式在服务器实例级别上设置。 - stjohnroe
5个回答

32

您需要将所需参数放在web.xml文件的env-entry条目中:

<env-entry> 
    <env-entry-name>dbhost</env-entry-name>
    <env-entry-type>java.lang.String</env-entry-type>
    <env-entry-value>localhost</env-entry-value> 
</env-entry>

然后通过 JNDI 上下文访问它们

import javax.naming.Context;
import javax.naming.InitialContext;
...
// Get the base naming context
Context env = (Context)new InitialContext().lookup("java:comp/env");

// Get a single value
String dbhost = (String)env.lookup("dbhost");

请务必在env-entry-value之前指定env-entry-type,否则可能会出现XML验证错误。 - luke
也许您可以添加导入。 :) - alexander
@alexander,这是给你的。 - stjohnroe
你的解决方案能否使用注释实现? - qualebs

11
你可以在web.xml中使用context-parameters和javax.servlet.ServletContextListener来填充一些静态字段。在你的普通Java类中,你读取这些静态字段。
<?xml version="1.0" encoding="UTF-8"?>
<web-app version="2.5" xmlns="http://java.sun.com/xml/ns/javaee"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd">
...
<context-param>
    <description>Prameter</description>
    <param-name>myParam</param-name>
    <param-value>123456790</param-value>
</context-param>
...
</web-app>
您可以使用 ServletContext.getInitParameter 访问此上下文参数。

3

一种方法是读取xml文件并解析它。

ServletContextListener中解析后,您可以将其放置在某些静态映射上。


1
实现一个ServletContextListener
package util;

import javax.servlet.ServletContext;
import javax.servlet.ServletContextEvent;
import javax.servlet.ServletContextListener;

public class MyConfigListener implements ServletContextListener {
    @Override
    public void contextInitialized(ServletContextEvent sce) {
        ServletContext ctx = sce.getServletContext();

        String hostname = ctx.getInitParameter("my.config.hostname");

        // now go and do something with that
    }

    @Override
    public void contextDestroyed(ServletContextEvent sce) {}

}

不要忘记在web.xml中注册它:
<context-param>
  <param-value>somewhere.example.org</param-value>
  <param-name>my.config.hostname</param-name>
</context-param>
<listener>
  <listener-class>util.MyConfigListener</listener-class>
</listener>

0
创建一个静态类,该类将从其中一个servlets init进行初始化。

1
这里的难点在于哪个Servlet的init方法。您不希望您的应用程序依赖于Servlet何时被首先初始化。 - Eric Wilson

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接