You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

动态Web项目中conf.properties在Servlet不识别但main方法可用的原因

问题描述

我在Web应用根目录下放置了conf.properties文件,在ManageBDD类中编写了init方法用于初始化参数。当在Servlet中调用该init方法时,文件无法被识别;但在ManageBDD类的main方法中调用该方法却可以正常工作。请问为何会出现这种差异?(throws Exception仅用于测试该方法)

相关代码

ManageBDD类的init方法

public static void init() throws Exception {
    FileInputStream file = new FileInputStream("conf.properties");
    Properties prop = new Properties();
    prop.load(file);
    pDriver = prop.getProperty("jdbc.driver");
    pUrl = prop.getProperty("jdbc.url");
    pLogin = prop.getProperty("jdbc.login");
    pPass = prop.getProperty("jdbc.pass");
    System.out.println("in class : " + prop.getProperty("jdbc.login"));
    System.out.println("in class : " + prop.getProperty("jdbc.pass"));
    System.out.println("in class : " + prop.getProperty("jdbc.driver"));
    System.out.println("in class : " + prop.getProperty("jdbc.url")); 
}

项目目录结构

项目目录结构

可正常运行的调用(main方法)

public static void main(String[] args) throws Exception {
    init();
}

无法正常工作的调用(Servlet)

protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
    try {
        ManageBDD.init();
    } catch (Exception e) {
        e.printStackTrace();
    }
    //request.getRequestDispatcher("/index.jsp").forward(request, response);        
}
原因分析

两种场景的核心差异是当前工作目录不同:

  • 用main方法运行时,程序的当前工作目录就是你的项目根目录,刚好是conf.properties所在的位置,所以FileInputStream能直接找到文件。
  • 当Web应用部署到服务器运行时,程序的当前工作目录是服务器的启动目录(比如Tomcat的bin目录),不是你的Web应用根目录,自然找不到这个配置文件。

另外,FileInputStream是基于本地文件系统读取的,一旦Web应用打包成WAR包,配置文件会被嵌入包内,此时用文件系统路径也无法访问到包里的资源。

解决方法

针对Web应用场景,推荐两种正确的资源读取方式:

方法一:类加载器读取(推荐)

把conf.properties放到项目的src/main/resources目录下(编译后会自动进入类路径),然后用类加载器读取资源流:

public static void init() throws Exception {
    InputStream inputStream = ManageBDD.class.getClassLoader().getResourceAsStream("conf.properties");
    Properties prop = new Properties();
    prop.load(inputStream);
    pDriver = prop.getProperty("jdbc.driver");
    pUrl = prop.getProperty("jdbc.url");
    pLogin = prop.getProperty("jdbc.login");
    pPass = prop.getProperty("jdbc.pass");
    // 保留原打印逻辑
}

方法二:通过Servlet上下文获取Web根路径

如果要保留conf.properties在Web应用根目录,可以在Servlet中获取Web根的绝对路径,再传递给init方法:

修改Servlet中的调用代码

protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
    try {
        String webRootPath = getServletContext().getRealPath("/");
        ManageBDD.init(webRootPath);
    } catch (Exception e) {
        e.printStackTrace();
    }
}

修改ManageBDD的init方法

public static void init(String webRootPath) throws Exception {
    FileInputStream file = new FileInputStream(webRootPath + "conf.properties");
    Properties prop = new Properties();
    prop.load(file);
    pDriver = prop.getProperty("jdbc.driver");
    pUrl = prop.getProperty("jdbc.url");
    pLogin = prop.getProperty("jdbc.login");
    pPass = prop.getProperty("jdbc.pass");
    // 保留原打印逻辑
}

内容的提问来源于stack exchange,提问作者Nicolas Zanforlini

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.06 07:10:28