杰瑞科技汇

Java Web中INF路径如何正确访问?

什么是 WEB-INF

WEB-INF (Web Application) 目录是 Java Web 应用程序中的一个特殊目录,它遵循 Java Servlet 规范,是 Web 应用程序的标准目录结构的一部分。

Java Web中INF路径如何正确访问?-图1
(图片来源网络,侵删)

核心特点:

  1. 对客户端不可直接访问:这是 WEB-INF 最重要、最核心的特点,浏览器(客户端)无法通过 URL 直接访问 WEB-INF 目录及其下的任何资源,如果你有一个文件 WEB-INF/config.properties,用户在浏览器中输入 http://yourdomain.com/your-app/WEB-INF/config.properties 是无法访问到这个文件的。
  2. 存放核心配置和资源:这个目录用于存放那些不应该被外界直接访问,但被服务器端代码(如 Servlet, Filter, JSP)所必需的文件。
  3. 受服务器保护:Web 服务器(如 Tomcat, Jetty, JBoss)会确保所有对 WEB-INF 的直接访问请求都被拒绝。

WEB-INF 目录下的常见子目录和文件

一个典型的 WEB-INF 目录结构如下:

your-web-app/
├── index.html
├── images/
│   └── logo.png
├── css/
│   └── style.css
├── js/
│   └── app.js
└── WEB-INF/              <-- 根目录下的 WEB-INF
    ├── web.xml           <-- 部署描述符(Servlet 3.0 以前是必须的)
    ├── classes/          <-- 存放编译后的 .class 文件(Java 源代码在 src 目录下)
    │   ├── com/
    │   │   └── example/
    │   │       └── MyServlet.class
    │   └── META-INF/
    │       └── MANIFEST.MF
    └── lib/              <-- 存放第三方依赖的 JAR 包
        ├── jackson-core-2.13.0.jar
        └── commons-lang3-3.12.0.jar

详解:

  • web.xml (Web Application Deployment Descriptor)

    • 作用:Web 应用的配置文件,它定义了 Servlet、Filter、Listener、Servlet 映射、欢迎页面、错误页面等。
    • 重要性:在 Servlet 3.0 规范之前,web.xml 是配置 Web 应用的唯一方式,从 Servlet 3.0 开始,引入了注解(如 @WebServlet)和编程式配置,web.xml 变为可选,但很多老项目或复杂配置仍在使用它。
  • classes/ 目录

    • 作用:存放编译后的 Java 字节码文件(.class 文件)。
    • 类加载路径:这个目录是 Web 应用的根类路径(Root Classpath),服务器会自动加载此目录下的所有类。
    • 注意:如果你的源代码在 src 目录下,那么在构建项目(如使用 Maven 或 Gradle)时,编译后的 .class 文件会被自动复制到 WEB-INF/classes 目录下。
  • lib/ 目录

    Java Web中INF路径如何正确访问?-图2
    (图片来源网络,侵删)
    • 作用:存放第三方库的 JAR 包。
    • 类加载路径:此目录下的所有 JAR 包也会被 Web 应用加载。lib 目录下的 JAR 优先级高于 classes 目录。
    • 依赖管理:在现代项目中(如 Maven, Gradle),你通常不需要手动将 JAR 包复制到这里,构建工具会自动处理依赖,并将其打包到最终的 WAR 文件中的 WEB-INF/lib 目录。
  • lib/classes/ 的区别

    • classes/ 存放项目自己编写的代码。
    • lib/ 存放外部的、第三方的库。
    • 两者共同构成了 Web 应用的类加载路径,但 lib 中的 JAR 会被优先加载。

为什么要把资源放在 WEB-INF 下?(主要用途)

  1. 安全性

    • 这是最主要的原因,数据库配置文件(如 db.properties)、Spring 的配置文件(如 applicationContext.xml)、日志配置文件等包含了敏感信息,绝不能被外部用户直接访问,将它们放在 WEB-INF 下,可以确保只有服务器端的 Java 代码才能读取,而浏览器无法通过 URL 直接获取。
  2. 保护核心资源

    • 有些 JSP 页面或 HTML 页面可能只应通过特定流程(如登录后)才能访问,或者作为内部模板使用,将它们放在 WEB-INF 下,可以防止用户直接通过 URL 访问,只能通过服务器端跳转(如 RequestDispatcher.forward())来展示。
  3. 作为应用的私有目录

    Java Web中INF路径如何正确访问?-图3
    (图片来源网络,侵删)
    • WEB-INF 是 Web 应用的私有空间,应用可以在此目录下创建自己的临时文件、缓存文件等,而不用担心被外部干扰或直接访问。

如何在 Java 代码中访问 WEB-INF 下的资源?

由于 WEB-INF 对外不可见,你不能使用普通的文件路径来访问,必须使用 Servlet API 提供的方法。

使用 ServletContext.getResourceAsStream()

这是最推荐、最标准的方法。ServletContext 对象代表了整个 Web 应用,它可以用来获取应用内的任何资源。

场景:读取配置文件(如 config.properties)。

假设文件路径:WEB-INF/config/config.properties

import javax.servlet.ServletContext;
import javax.servlet.http.HttpServlet;
import java.io.InputStream;
import java.util.Properties;
public class MyConfigLoader extends HttpServlet {
    public void loadConfig() {
        // 1. 获取 ServletContext 对象
        ServletContext context = getServletContext();
        // 2. 使用 getResourceAsStream 获取文件的输入流
        //    路径必须以 "/" 开头,表示从 Web 应用的根目录开始
        String path = "/WEB-INF/config/config.properties";
        InputStream inputStream = context.getResourceAsStream(path);
        if (inputStream != null) {
            try {
                Properties props = new Properties();
                props.load(inputStream);
                // 读取配置项
                String dbUrl = props.getProperty("db.url");
                String dbUser = props.getProperty("db.user");
                System.out.println("Database URL: " + dbUrl);
                System.out.println("Database User: " + dbUser);
            } catch (Exception e) {
                e.printStackTrace();
            } finally {
                // 3. 关闭流
                try {
                    if (inputStream != null) {
                        inputStream.close();
                    }
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        } else {
            System.err.println("Config file not found at: " + path);
        }
    }
}

关键点

  • context.getResourceAsStream("/WEB-INF/..."):路径必须以 开头,它相对于 Web 应用的根目录。
  • 这个方法返回的是一个 InputStream,非常适合读取文本、XML、属性文件等配置资源。
  • 它不能直接获取文件的绝对路径(如 C:\tomcat\webapps\app\WEB-INF\...),因为 Web 应用可能被打包成 WAR 文件,路径是虚拟的。

使用 ServletContext.getRealPath() 结合 RequestDispatcher

场景:你想将一个位于 WEB-INF 下的 JSP 页面(如 WEB-INF/views/dashboard.jsp)转发给客户端显示。

你不能直接 new File("/WEB-INF/views/dashboard.jsp"),因为路径不对,你需要先获取其服务器上的真实路径,然后转发。

import javax.servlet.RequestDispatcher;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
public class DashboardServlet extends HttpServlet {
    protected void doGet(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        // 1. 获取 WEB-INF 下 JSP 文件的虚拟路径
        String jspPath = "/WEB-INF/views/dashboard.jsp";
        // 2. 使用 RequestDispatcher 进行服务器端转发
        //    这是访问 WEB-INF 下 JSP 的标准方式!
        RequestDispatcher dispatcher = request.getRequestDispatcher(jspPath);
        // 可以在转发前向 request 中添加一些数据
        request.setAttribute("username", "John Doe");
        // 3. 执行转发
        dispatcher.forward(request, response);
    }
}

关键点

  • request.getRequestDispatcher("/WEB-INF/..."):这是访问 WEB-INF 下 JSP 页面的唯一正确方式
  • RequestDispatcher.forward() 是在服务器端完成的,浏览器地址栏的 URL 不会改变,仍然是请求 DashboardServlet 的 URL。
  • 不要尝试用 getRealPath() 来读取 JSP 内容或进行文件操作,它的主要用途是获取文件的物理路径(用于文件上传后保存),但对于 WEB-INF 下的资源,forward 是首选。

路径总结

访问方式 路径示例 说明
浏览器 URL 直接访问 http://.../index.html index.html 在 Web 根目录下,可以访问。
http://.../WEB-INF/web.xml 错误,无法访问,会被服务器拒绝。
ServletContext.getResourceAsStream() context.getResourceAsStream("/WEB-INF/config.properties") 正确,用于读取配置文件等资源,返回 InputStream,路径以 开头。
request.getRequestDispatcher() request.getRequestDispatcher("/WEB-INF/views/page.jsp").forward(req, resp); 正确,用于将 WEB-INF 下的 JSP 页面转发给客户端显示。

记住以下几点,你就能完全掌握 WEB-INF 路径的使用:

  1. 核心规则WEB-INF安全区,对客户端完全封闭。
  2. 放什么:放敏感配置、私有 JSP、核心资源。
  3. 怎么读:用 ServletContext.getResourceAsStream() 来读取文件内容。
  4. 怎么显示 JSP:用 RequestDispatcher.forward() 来转发 WEB-INF 下的 JSP。
  5. 放代码:自己写的 .classclasses,第三方 JAR 放 lib

正确使用 WEB-INF 是构建一个安全、规范的 Java Web 应用的基础。

分享:
扫描分享到社交APP
上一篇
下一篇