201

我正在开发具有以下源代码目录结构的 Java EE Web 应用程序:

src/main/java                 <-- multiple packages containing Java classes
src/test/java                 <-- multiple packages containing JUnit tests
src/main/resources            <-- includes properties files for textual messages
src/main/webapp/resources     <-- includes CSS, images and all Javascript files
src/main/webapp/WEB-INF
src/main/webapp/WEB-INF/tags
src/main/webapp/WEB-INF/views

我感兴趣的文件夹是WEB-INF:它包含web.xml用于设置 servlet、Spring bean 连接上下文和 JSP 标记和视图的 XML 文件。我试图了解是什么限制/定义了这个结构。例如,JSP 文件总是必须在其中WEB-INF还是可以在其他地方?还有什么可以进去的WEB-INF吗?Wikipedia 的WAR 文件条目提到classes了 Java 类和libJAR 文件 - 除了其他源文件位置之外,我不确定何时需要这些文件。

4

5 回答 5

235

Servlet 2.4 规范说明了关于 WEB-INF的内容(第 70 页):

应用程序层次结构中存在一个特殊目录,名为 WEB-INF. 此目录包含与应用程序相关但不在应用程序文档根目录中的所有内容。WEB-INF节点不是应用程序公共文档树的一部分。目录中包含的任何文件WEB-INF都不能由容器直接提供给客户端。但是,目录的内容对 servlet 代码使用 上的 and方法调用WEB-INF是可见的,并且可以使用调用公开。getResourcegetResourceAsStreamServletContextRequestDispatcher

这意味着WEB-INF您的 Web 应用程序的资源加载器可以访问资源,而不是直接对公众可见。

这就是为什么许多项目将他们的资源(如 JSP 文件、JAR/库和他们自己的类文件或属性文件或任何其他敏感信息)放在WEB-INF文件夹中的原因。否则,可以使用简单的静态 URL 访问它们(例如,用于加载 CSS 或 Javascript)。

从技术角度来看,您的 JSP 文件可以在任何地方。例如,在 Spring 中,您可以将它们配置为WEB-INF显式:

<bean id="viewResolver" class="org.springframework.web.servlet.view.InternalResourceViewResolver"
    p:prefix="/WEB-INF/jsp/" 
    p:suffix=".jsp" >
</bean>

Wikipedia 的WAR 文件文章中提到的WEB-INF/classes和文件夹是 Servlet 规范在运行时所需的文件夹示例。WEB-INF/lib

区分项目的结构和生成的 WAR 文件的结构很重要。

项目的结构在某些情况下会部分反映 WAR 文件的结构(对于 JSP 文件或 HTML 和 JavaScript 文件等静态资源,但情况并非总是如此。

从项目结构到生成的 WAR 文件的转换是通过构建过程完成的。

虽然您通常可以自由设计自己的构建过程,但现在大多数人将使用标准化方法,例如Apache Maven。除此之外,Maven 定义了项目结构中的哪些资源映射到生成的工件中的哪些资源的默认值(在这种情况下,生成的工件是 WAR 文件)。在某些情况下,映射由纯复制过程组成,在其他情况下,映射过程包括转换,例如过滤或编译等。

一个示例:该WEB-INF/classes文件夹稍后将包含所有需要由 Classloader 加载以启动应用程序的已编译的 java 类和资源(src/main/java和)。src/main/resources

另一个示例:该WEB-INF/lib文件夹稍后将包含应用程序所需的所有 jar 文件。在 maven 项目中,为您管理依赖项,并且 maven 会自动为您将所需的 jar 文件复制到WEB-INF/lib文件夹中。lib这就解释了为什么在 Maven 项目中没有文件夹。

于 2013-11-05T10:04:15.803 回答
63

当您部署 Java EE Web 应用程序(使用或不使用框架)时,其结构必须遵循一些要求/规范。这些规格来自:

  • servlet 容器(例如 Tomcat)
  • Java Servlet API
  • 您的应用程序域
  1. Servlet 容器要求
    如果您使用 Apache Tomcat,您的应用程序的根目录必须放在 webapp 文件夹中。如果您使用另一个 servlet 容器或应用程序服务器,情况可能会有所不同。

  2. Java Servlet API 要求
    Java Servlet API 规定您的根应用程序目录必须具有以下结构:

    ApplicationName
    |
    |--META-INF
    |--WEB-INF
          |_web.xml       <-- Here is the configuration file of your web app(where you define servlets, filters, listeners...)
          |_classes       <--Here goes all the classes of your webapp, following the package structure you defined. Only 
          |_lib           <--Here goes all the libraries (jars) your application need
    

这些要求由 Java Servlet API 定义。

3. 您的应用程序域
现在您已经满足了 Servlet 容器(或应用程序服务器)的要求和 Java Servlet API 要求,您可以根据需要组织 webapp 的其他部分。
- 您可以将您的资源(JSP 文件、纯文本文件、脚本文件)放在您的应用程序根目录中。但是,人们可以直接从他们的浏览器访问它们,而不是由您的应用程序提供的某些逻辑处理他们的请求。因此,为了防止您的资源被这样直接访问,您可以将它们放在 WEB-INF 目录中,其内容只能由服务器访问。
- 如果你使用一些框架,它们通常会使用配置文件。大多数这些框架(struts、spring、hibernate)都要求您将它们的配置文件放在类路径(“类”目录)中。

于 2013-11-05T10:40:43.057 回答
12

您应该将您不想公开的任何页面或页面片段放入 WEB-INF。通常,JSP 或 facelets 位于 WEB-INF 之外,但在这种情况下,任何用户都可以轻松访问它们。如果您有一些授权限制,可以使用 WEB-INF。

WEB-INF/lib 可以包含您不想在系统级别打包的第 3 方库(JAR 可用于您服务器上运行的所有应用程序),但仅适用于此特定应用程序。

一般来说,很多配置文件也会进入WEB-INF。

至于 WEB-INF/classes - 它存在于任何网络应用程序中,因为这是放置所有已编译源的文件夹(不是 JARS,而是您自己编写的已编译 .java 文件)。

于 2013-11-05T10:04:56.883 回答
4

出于安全原因,遵循此约定。例如,如果允许未经授权的人直接从 URL 访问根 JSP 文件,那么他们无需任何身份验证即可浏览整个应用程序,并且他们可以访问所有受保护的数据。

于 2016-11-16T22:49:30.903 回答
3

将 jsp 页面放在 WEB-INF 目录下有一个约定(不是必需的),这样它们就不能被深度链接或添加书签。这样所有对jsp页面的请求都必须通过我们的应用程序,这样才能保证用户体验。

于 2016-04-15T08:11:06.653 回答