什么是在Java EE Web应用程序中使用的WEB-INF?

我正在使用以下源代码结构处理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的XML文件,Spring bean接线上下文以及JSP标签和视图。

问题的标题是基本的,但是我想了解的是约束/定义这个结构。 例如,JSP文件总是必须在WEB-INF或者它们可能在其他地方? 还有什么可以在WEB-INF ? 维基百科的WAR文件入口提及Java类的类和JAR文件的lib – 不确定当除了其他源文件位置之外还需要这些文件时,我已经完全掌握了。

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

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

这意味着WEB-INF资源可以被Web应用程序的资源加载器访问,并且不能直接显示给公众。

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

尽pipe从技术的angular度来看,您的JSP文件可以在任何地方。 比如在Spring中,你可以明确地将它们configuration成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/classesWEB-INF/lib文件夹是Servlet规范在运行时所需的文件夹示例。

在项目的结构和生成的WAR文件的结构之间做出区别是非常重要的。

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

从项目结构到生成的WAR文件的转换由构build过程完成。

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

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

另一个例子WEB-INF/lib文件夹稍后将包含应用程序所需的所有jar文件。 在Maven项目中,为你pipe理依赖关系,maven自动将所需的jar文件复制到你的WEB-INF/lib文件夹中。 这就解释了为什么你在maven项目中没有lib文件夹。

当您部署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的要求,您可以根据需要组织Web应用程序的其他部分。
– 您可以将您的资源(JSP文件,纯文本文件,脚本文件)放在您的应用程序根目录中。 但是,人们可以直接从浏览器访问它们,而不是通过应用程序提供的某些逻辑处理它们的请求。 因此,为了防止您的资源被直接访问,您可以将它们放在WEB-INF目录中,其内容只能由服务器访问。
如果你使用一些框架,他们经常使用configuration文件。 大多数这些框架(struts,spring,hibernate)都要求你把他们的configuration文件放在类path(“classes”目录)中。

您应该在WEB-INF中放入您不想公开的任何页面或页面。 通常,JSP或facelets可以在WEB-INF之外find,但在这种情况下,它们很容易被任何用户访问。 如果您有一些授权限制,可以使用WEB-INF。

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

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

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

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

为了安全起见,遵循这个惯例。 例如,如果未经授权的人员被允许直接从URL访问根JSP文件,那么他们可以在整个应用程序中导航,而不需要任何身份validation,并且可以访问所有的安全数据。