框架(如Spring)如何在没有web.xml的情况下配置Servlet容器?

Devabc:

(我已经知道答案了,但是因为我经常发现自己正在寻找答案,所以我在这里将其发布为自己和其他人的文档。在Stackoverflow 鼓励这样做。)

背景介绍

许多Servlet开发人员已阅读“ Head First Serlet&JSP”这本书,以获得“认证的Web组件开发人员考试”,或者只是学习Servlet。但是自2009年以来,这本书就没有更新过,仅涵盖Servlet 2.4。从那以后很多事情改变了。当前的最新版本是4.0。更改的事情之一是servlet Web应用程序的启动过程,这可能使启动过程中不清楚发生什么以及如何初始化Web应用程序。

在Servlet 2.4及更低版本中,web.xml用于完全配置Web应用程序。但是更高的版本似乎还有其他配置Web应用程序的方式,而无需触摸web.xml和注释。例如,以.jar文件形式提供的Web框架可以某种方式挂接到Servlet容器并添加url映射。

这种机制如何运作?

Devabc:

介绍

在Servlet 2.4(2003年11月)中,一个servlet容器(例如Tomcat和Jetty)只是通过查找文件WEB-INF/web.xml部署描述符来启动Web应用程序文件web.xml包含对servlet,过滤器和侦听器的引用,以及它们的关联url模式和参数。servlet容器使用web.xml确切地知道在哪里可以找到所有内容以及如何配置它们。

从Servlet 3.0(2009年12月)开始,web.xml是可选的,因此您也可以使用注释或编程配置。

注释使用起来更简单。它们都位于javax.servlet.annotation包,并允许您注释与@一个servlet WebServlet,用@过滤网页过滤,并用@监听器WebListener然后,server容器将自动查找并检测这些类。但是,注解提供的配置功能少于web.xml和编程配置。

本文还将重点介绍如何配置程序配置以及如何启动Spring MVC。它比注释要复杂一些,但是确实为您和框架设计人员提供了对启动过程的更多控制。

如果要在Servlet 3.0版之前使用Web框架,则必须将Servlet或过滤器添加到web.xml并从那里配置框架。初始化之后,您可以开始编写Web框架已知的类(通常是非Servlet类)来创建Web应用程序。

从Servlet 3.0开始,该系统是模块化的。这样,框架和库设计人员就可以初始化servlet容器,而无需通过web.xml配置框架。您可以立即开始编写特定于Web框架的类以创建Web应用程序,而无需接触Servlet类。(在Servlet 3.0中也可以创建自己的web.xml,并且仍然允许框架对框架进行初始化,而无需在web.xml中进行定义。)

框架或库如何自动挂接到Servlet容器?

在启动时,Servlet容器首先查找位于的部署描述符WEB-INF/web.xml如果此文件的metadata-complete属性设置为false,或者根本没有定义,则容器还将搜索带注释的类,例如@WebServlet。

从Servlet 3.0开始,除了寻找web.xml和带注释的类之外,容器还将META-INF/web-fragment.xmlWEB-INF/lib目录中的.jar文件中寻找文件

文件web-fragment.xml是一个Web片段,它是(来自Java Servlet Specification的引号

Web应用程序的逻辑分区,使得Web应用程序内使用的框架可以定义所有工件,而无需要求开发人员在web.xml中编辑或添加信息。它几乎可以包含web.xml描述符使用的所有相同元素。但是,描述符的顶层元素必须是web-fragment,相应的描述符文件必须称为web-fragment.xml。与订购相关的元素在web-fragment.xml和web.xml之间也有所不同

web-fragment.xml的内容类似于web.xml,但是具有一个web-fragmentroot元素而不是web-appelement:

<web-fragment 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 
              https://java.sun.com/xml/ns/javaee/web-fragment_3_0.xsd"
              version="3.0">
  <filter>
    <filter-name>FrameworkFilter</filter-name>
    <filter-class>framework.FrameworkFilter</filter-class>
  </filter>

  <filter-mapping>
    <filter-name>FrameworkFilter</filter-name>
    <url-pattern>/*</url-pattern>
  </filter-mapping>
</web-fragment>

可以使用<absolute-ordering>来配置单个web.xml和多个web-fragment.xml文件的确切加载顺序<ordering>

除了Web片段之外,还有一种编程方法可以对Web应用程序进行分区:通过编写interface的实现javax.servlet.ServletContainerInitializerServletContainerInitializer允许访问ServletContext,其中包含用于以编程方式添加Servlet,过滤器和侦听器的方法。要使用ServletContainerInitializer它,必须在的文件中指定它META-INF/services/javax.servlet.ServletContainerInitializer该文件的内容必须是实现类的完全限定路径。

这对Spring MVC如何起作用?

尽管Spring MVC确实包含了web-fragment.xml,但它没有定义任何servlet,过滤器或监听器。Spring使用该META-INF/services/javax.servlet.ServletContainerInitializer文件来引用其自己的ServletContainerInitializer实现类,即该类SpringServletContainerInitializer

SpringServletContainerInitializer是一个ServletContainerInitializer,因此在启动时会收到ServletContext。SpringServletContainerInitializer的目标是将ServletContext传递给对开发人员更友好的WebApplicationInitializer,以便您可以添加Servlet,例如Springs DispatcherServlet,它是将传入请求定向到其他控制器的前端控制器。有关如何将DispatcherServlet配置为Spring的信息,请参见spring-framework-reference。)

Spring MVC没有提供WebApplicationInitializer的具体实现,仅提供了许多抽象类,因此您可以控制启动过程。对于Spring Boot,提供了一个具体的实现:SpringApplicationWebApplicationInitializer减少样板代码的数量。

进一步的信息

可以在官方Java Servlet规范中找到有关Servlet容器启动过程如何正确工作的详细说明有关Spring MVC的更多信息,请参见Spring Framework参考

本文收集自互联网,转载请注明来源。

如有侵权,请联系 [email protected] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章

如何在没有web.xml的情况下配置非Spring纯Javaee Web应用程序

如何在没有任何.xml配置的情况下使用spring 3.x注释

如何在没有XML文件的情况下配置Spring ACL

在没有 web.xml 的情况下配置 POJOMappingFeature

如何在没有Docker Hub集成的情况下配置Amazon容器服务

没有persistence.xml的情况下如何配置Spring?

如何在没有Java配置而不是XML的情况下使用CommandLineJobRunner启动Spring批处理

OptaPlanner:如何在没有.xml配置文件的情况下构建求解器?

如何在没有xml的情况下配置thymeleaf-extras-springsecurity4?

如何从没有Pod或部署的Yaml配置的情况下创建多容器Pod

如何在没有locations配置属性的情况下配置Spring java环境?

如何在 Python 中没有任何循环(如:for、while 等)的情况下递归 JSON 文件

如何在没有实体框架的情况下使用Windows身份框架(WIF)

如何在不修改web.xml的情况下向Servlet添加过滤器

如何在没有JSTL和EJB的情况下将数据从servlet输出到jsp

Docker:容器如何在没有卷的情况下持久存储数据?

如何在没有docker-compose停机的情况下重建和更新容器?

如何在没有rootfs的情况下创建LXC容器

如何在没有密码的情况下从centos 6.4 SSH到docker容器中?

如何在没有容器(视图)ID的情况下替换当前片段?

如何在没有 docker restart 的情况下释放 docker 容器使用的空间?

我可以在没有任何XML配置文件的情况下使用Spring注入Java对象吗?

在没有XML配置的情况下将Ehcache CacheManager(v 3.x)转换为Spring CacheManager

在没有“容器”的情况下使用 ReactDOM.render

在没有dockerfile的情况下启动Docker容器

在没有地方的情况下隐藏容器

实体框架 - 如何在没有视图模型的情况下更新多个表

如何在没有PHP框架的情况下以MVC模式编写控制器?

如何在没有任何测试框架的情况下使用嵌入式 cassandra