当前位置: 首页 > 知识库问答 >
问题:

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

仲孙思源
2023-03-14

< sub >(我已经知道了答案,但是因为我经常发现自己在重新寻找答案,所以我把它贴在这里作为自己和他人的文档。这是Stackoverflow上鼓励的。)

许多 Servlet 开发人员都读过《Head First Serlet》一书

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

这个机制是如何工作的?

共有1个答案

邓嘉致
2023-03-14

在Servlet 2.4(2003年11月)中,Servlet容器(如Tomcat和Jetty)通过查找文件<code>web-INF/web来简单地启动web应用程序。xml(部署描述符)。文件网络。xml包含对servlet、过滤器和侦听器的引用,以及它们相关的url模式和参数。使用web。servlet容器确切地知道在哪里查找所有内容以及如何配置它们。

自Servlet3.0(2009年12月)以来,web。xml是可选的,您也可以使用注释或编程配置。

注释使用起来更简单。它们位于javax.servlet中。注释包,并允许您使用@WebServlet注释servlet,使用@WebFilter注释筛选器,使用@WebListener注释侦听器。servler容器将自动查找并检测这些类。然而,注释提供的配置功能比web少。xml和编程配置。

本文进一步关注如何配置编程配置以及如何启动Spring MVC。它比注释稍微复杂一些,但确实让你和框架设计人员更好地控制了引导过程

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

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

启动时,Servlet容器首先查找位于< code>WEB-INF/web.xml的部署描述符。如果这个文件的< code>metadata-complete属性设置为false,或者根本没有定义,那么容器也会搜索带注释的类,比如@WebServlet。

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

文件web-fragment.xml是一个web片段,它是(引用自JavaServlet规范)

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

web-fragment.xml的内容类似于web.xml,但使用了< code>web-fragment根元素,而不是< code>web-app元素:

<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>

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

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

尽管Spring MVC确实包含一个web-fragment.xml,但它没有定义任何servlet、过滤器或侦听器。Spring使用META-INF/services/javax.servlet.ServletContainerInitializer文件来引用它自己的ServletContainerLaunalizer实现类,它就是类SpringServletContainerLaunalizer

SpringServletContainerInitializer是一个ServletContrainerInitializer,因此它在启动时接收ServletContext。SpringServletContainerInitializer的目标是将servletContext传递给开发人员更友好的<code>WebApplicationInitializer,以便您可以添加Servlet,例如Springs<code<DispatcherServlet,它是一个前端控制器,将传入请求引导到其他控制器。(有关如何将DispatcherServlet配置到spring,请参阅spring框架参考。)

Spring MVC没有提供WebApplication ationLaunalizer的具体实现,只有一些抽象类,这样您就可以控制引导过程。在Spring Boot的情况下,提供了一个具体的实现:SpringApplication ationWebApplication ationLaunalizer以减少样板代码的数量。

有关Servlet容器引导过程的详细描述可以在官方的JavaServlet规范中找到。有关Spring MVC的更多信息可以在Spring Framework参考中找到。

 类似资料:
  • 我知道这可以在Servlet3.0中通过@Webservlet注释实现,在这里您只需分配url模式,而不必在web.xml中进行任何配置。是否有一种方法可以通过编程方式为运行Servlet2.5的应用程序分配servlets url模式? 我正在创建一个库,多个应用程序将依赖于它,并试图使它,以便这些应用程序中的每一个都不必显式配置任何servlet url映射,我正在创建的库中的servlet在

  • TL;DR:将@webservlet(“/find-customers”)放在servlet(通过Tomcat 7部署)的开头并不是将servlet映射到host:port/webproject/find-customers中,即使servlet位于src文件夹中。

  • 问题内容: 我正在尝试设置spring xml配置,而不必创建进一步的。但是,即使我将数据库属性包括在 spring.xml: 我在这里想念什么? 问题答案: 在entityManagerFactory bean定义中指定“ packagesToScan”和“ persistenceUnitName”属性。 请注意,这适用于Spring版本> 3.1

  • 我正在尝试设置SpringXML配置,而不必创建进一步的。但是我经常遇到以下异常,即使我在 spring.xml: 我错过了什么?

  • 我有一个简单的servlet配置在web.xml: 如何为SpringBootServletInitializer重写它?

  • 我尝试在bean部分中使用环境: 但环境中只有系统属性 所以问题是如何从application.yml加载配置,以及如何以这样的函数式实现@ConfigurationProperties的模拟? 注释、和开始工作。但是注释仅存在于依赖项中,而yml解析类仅存在于中。 在包含依赖项并将添加到beans部分之后,注释开始工作,但也未包含来自application.yml的配置。所以我增加了这一节: 到