知識庫 / Spring RSS 訂閱

在Java中註冊Servlet的方法

Jakarta EE,Spring
HongKong
10
02:39 PM · Dec 06 ,2025

1. 簡介

本文將提供對如何在 Jakarta EE 和 Spring Boot 中註冊 Servlet 的概述。 尤其是,我們將探討兩種在 Jakarta EE 中註冊 Java Servlet 的方法:一種使用 web.xml 文件,另一種使用註解。 此外,我們還將使用 XML 配置、Java 配置和可配置屬性在 Spring Boot 中註冊 Servlet。

關於 Servlet 的優秀入門文章可以在這裏找到。

2. 在 Jakarta EE 中註冊 Servlet

讓我們回顧一下在 Jakarta EE 中註冊 Servlet 的兩種方法。第一種方法是使用 <em >web.xml</em > 文件進行註冊。 另一種方法是使用 Jakarta EE 的 `@WebServlet> 註解。

2.1. 通過 web.xml

在 Jakarta EE 應用程序中註冊 Servlet 的最常見方法是在 web.xml 文件中將其添加:

<welcome-file-list>
    <welcome-file>index.html</welcome-file>
    <welcome-file>index.htm</welcome-file>
    <welcome-file>index.jsp</welcome-file>
</welcome-file-list>
<servlet>
    <servlet-name>Example</servlet-name>
    <servlet-class>com.baeldung.Example</servlet-class>
</servlet>
<servlet-mapping>
    <servlet-name>Example</servlet-name>
    <url-pattern>/Example</url-pattern>
</servlet-mapping>

如您所見,這涉及兩個步驟:(1) 將我們的servlet添加到 servlet 標籤中,確保同時指定 servlet 所在的類路徑;(2) 在 url-pattern 標籤中指定 servlet 將暴露的 URL 路徑。

Jakarta EE 中的 web.xml 文件通常位於 WebContent/WEB-INF

2.2. 通過註解進行註冊

現在,我們使用 <em @WebServlet</em> 註解在自定義 Servlet 類上註冊 Servlet。 這消除了在 <em server.xml</em> 中進行 Servlet 映射以及在 <em web.xml</em> 中註冊 Servlet 的需求。

@WebServlet(
  name = "AnnotationExample",
  description = "Example Servlet Using Annotations",
  urlPatterns = {"/AnnotationExample"}
)
public class Example extends HttpServlet {	
 
    @Override
    protected void doGet(
      HttpServletRequest request, 
      HttpServletResponse response) throws ServletException, IOException {
 
        response.setContentType("text/html");
        PrintWriter out = response.getWriter();
        out.println("<p>Hello World!</p>");
    }
}

上述代碼演示瞭如何直接將標註添加到servlet上。servlet將繼續在之前的URL路徑下可用。

3. 在 Spring Boot 中註冊 Servlet

現在我們已經展示瞭如何在 Jakarta EE 中註冊 Servlet,接下來讓我們看看在 Spring Boot 應用程序中註冊 Servlet 的幾種方法。

3.1. 編程方式註冊

Spring Boot 支持對 Web 應用程序的 100% 編程方式配置。

首先,我們將實現 WebApplicationInitializer 接口,然後實現 WebMvcConfigurer 接口,這允許您覆蓋預設的默認值,而不是必須指定每個特定的配置設置,從而節省您的時間和精力,並能夠使用經過驗證的設置。

以下是一個 WebApplicationInitializer 的示例實現:

public class WebAppInitializer implements WebApplicationInitializer {
 
    public void onStartup(ServletContext container) throws ServletException {
        AnnotationConfigWebApplicationContext ctx
          = new AnnotationConfigWebApplicationContext();
        ctx.register(WebMvcConfigure.class);
        ctx.setServletContext(container);

        ServletRegistration.Dynamic servlet = container.addServlet(
          "dispatcherExample", new DispatcherServlet(ctx));
        servlet.setLoadOnStartup(1);
        servlet.addMapping("/");
     }
}

接下來,讓我們實現 WebMvcConfigurer 接口:

@Configuration
public class WebMvcConfigure implements WebMvcConfigurer {

    @Bean
    public ViewResolver getViewResolver() {
        InternalResourceViewResolver resolver
          = new InternalResourceViewResolver();
        resolver.setPrefix("/WEB-INF/");
        resolver.setSuffix(".jsp");
        return resolver;
    }

    @Override
    public void configureDefaultServletHandling(
      DefaultServletHandlerConfigurer configurer) {
        configurer.enable();
    }

    @Override
    public void addResourceHandlers(ResourceHandlerRegistry registry) {
        registry.addResourceHandler("/resources/**")
          .addResourceLocations("/resources/").setCachePeriod(3600)
          .resourceChain(true).addResolver(new PathResourceResolver());
    }
}

我們在此明確指定了一些默認設置,以支持 .jsp 視圖和靜態資源服務。

3.2. XML 配置

通過 <em >web.xml</em >> 也是一種配置和註冊servlet的方式。

<servlet>
    <servlet-name>dispatcher</servlet-name>
    <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
    <init-param>
        <param-name>contextConfigLocation</param-name>
        <param-value>/WEB-INF/spring/dispatcher.xml</param-value>
    </init-param>
    <load-on-startup>1</load-on-startup>
</servlet>

<servlet-mapping>
    <servlet-name>dispatcher</servlet-name>
    <url-pattern>/</url-pattern>
</servlet-mapping>

Spring 中使用的 web.xml 用於指定配置,與 Jakarta EE 中發現的類似。上面你可以看到,我們通過在 servlet 標籤下的屬性來指定一些額外的參數。

這裏我們使用另一個 XML 來完成配置:

<beans ...>
    
    <context:component-scan base-package="com.baeldung"/>

    <bean 
      class="org.springframework.web.servlet.view.InternalResourceViewResolver">
        <property name="prefix" value="/WEB-INF/jsp/"/>
        <property name="suffix" value=".jsp"/>
    </bean>
</beans>

請記住,您的 Spring web.xml通常位於 src/main/webapp/WEB-INF

3.3. 結合 XML 和程序化註冊

讓我們將 XML 配置方法與 Spring 的程序化配置相結合:

public void onStartup(ServletContext container) throws ServletException {
   XmlWebApplicationContext xctx = new XmlWebApplicationContext();
   xctx.setConfigLocation('classpath:/context.xml');
   xctx.setServletContext(container);

   ServletRegistration.Dynamic servlet = container.addServlet(
     "dispatcher", new DispatcherServlet(ctx));
   servlet.setLoadOnStartup(1);
   servlet.addMapping("/");
}

讓我們也配置dispatcher servlet:

<beans ...>

    <context:component-scan base-package="com.baeldung"/>
    <bean class="com.baeldung.configuration.WebAppInitializer"/>
</beans>

3.4. 通過 Bean 註冊

我們可以使用 <em >ServletRegistrationBean</em> 編程方式配置和註冊我們的 Servlet。下面我們將使用它來註冊一個 <em >HttpServlet</em> (它實現了 <em >javax.servlet.Servlet</em> 接口):

@Bean
public ServletRegistrationBean exampleServletBean() {
    ServletRegistrationBean bean = new ServletRegistrationBean(
      new CustomServlet(), "/exampleServlet/*");
    bean.setLoadOnStartup(1);
    return bean;
}

這種方法的優勢在於,它允許您向 Spring 應用程序添加多個 Servlet 以及不同類型的 Servlet。

與其僅僅利用 DispatcherServlet,這是一種更具體的 HttpServlet,並且在我們在第 3.1 節中探索的程序化 Web 應用程序初始化器中被廣泛使用,我們將會使用一個更簡單的 HttpServlet 子類實例,該實例通過四個函數來暴露四種基本 HttpRequest 操作:doGet()doPost()doPut()doDelete(),就像在 Jakarta EE 中一樣。

請記住,HttpServlet 是一個抽象類(因此不能實例化)。但是,我們可以輕鬆地創建自定義擴展:

public class CustomServlet extends HttpServlet{
    ...
}

4. 註冊帶有屬性的 Servlet

另一種,雖然不常見,但配置和註冊 Servlet 的方式是使用自定義的屬性文件,通過 PropertyLoader, PropertySource, PropertySources 實例對象加載到應用中。

這提供了一種中間配置方式,並能夠自定義 application.properties ,該文件對於非嵌入式 Servlet 提供了很少直接的配置選項。

4.1. 系統屬性方法

我們可以向我們的application.properties文件或另一個屬性文件添加一些自定義設置。 讓我們為配置我們的 DispatcherServlet 添加幾個設置:

servlet.name=dispatcherExample
servlet.mapping=/dispatcherExampleURL

讓我們將自定義屬性加載到我們的應用程序中:

System.setProperty("custom.config.location", "classpath:custom.properties");

現在我們可以通過以下方式訪問這些屬性:

System.getProperty("custom.config.location");

4.2. 自定義屬性方法

讓我們從一個 custom.properties 文件開始:

servlet.name=dispatcherExample
servlet.mapping=/dispatcherExampleURL

我們可以使用一個普通的 Property Loader:

public Properties getProperties(String file) throws IOException {
  Properties prop = new Properties();
  InputStream input = null;
  input = getClass().getResourceAsStream(file);
  prop.load(input);
  if (input != null) {
      input.close();
  }
  return prop;
}

現在我們可以將這些自定義屬性作為常量添加到我們的 WebApplicationInitializer 實現中:

private static final PropertyLoader pl = new PropertyLoader(); 
private static final Properties springProps
  = pl.getProperties("custom_spring.properties"); 

public static final String SERVLET_NAME
  = springProps.getProperty("servlet.name"); 
public static final String SERVLET_MAPPING
  = springProps.getProperty("servlet.mapping");

我們還可以利用它們來,例如配置我們的DispatcherServlet:

ServletRegistration.Dynamic servlet = container.addServlet(
  SERVLET_NAME, new DispatcherServlet(ctx));
servlet.setLoadOnStartup(1);
servlet.addMapping(SERVLET_MAPPING);

這種方法的優勢在於沒有 xml 的維護工作,但同時具有易於修改的配置設置,無需重新部署代碼庫。

4.3. 使用 PropertySource 方式

一種更快速的方法是利用 Spring 的 PropertySource,它允許訪問和加載配置文件。

PropertyResolverConfigurableEnvironment 實現的接口,它在 Servlet 啓動和初始化時使應用程序屬性可用。

@Configuration 
@PropertySource("classpath:/com/yourapp/custom.properties") 
public class ExampleCustomConfig { 
    @Autowired 
    ConfigurableEnvironment env; 

    public String getProperty(String key) { 
        return env.getProperty(key); 
    } 
}

上述代碼中,我們通過依賴注入將依賴性引入類,並指定自定義屬性文件的位置。然後,我們可以通過調用getProperty()函數,傳入字符串值來獲取我們的關鍵屬性。

4.4. 使用 PropertySource 程序化方法

我們可以將上述方法(涉及獲取屬性值)與以下方法結合使用(該方法允許我們以編程方式指定這些值):

ConfigurableEnvironment env = new StandardEnvironment(); 
MutablePropertySources props = env.getPropertySources(); 
Map map = new HashMap(); map.put("key", "value"); 
props.addFirst(new MapPropertySource("Map", map));

我們已創建了一個將鍵映射到值的映射,並將該映射添加到 PropertySources 中,從而實現按需調用。

5. 註冊嵌入式 Servlet

最後,我們將探討 Spring Boot 中嵌入式 Servlet 的基本配置和註冊。

嵌入式 Servlet 提供完整的 Web 容器功能(如 Tomcat、Jetty 等),無需單獨安裝和維護 Web 容器.

您可以在任何支持此類功能的環境中,輕鬆地添加所需的依賴項和配置,實現簡潔、快速的部署。

我們將僅關注如何使用 Tomcat,但相同的做法也可以應用於 Jetty 和其他替代方案。

以下是在 pom.xml 中指定嵌入式 Tomcat 8 Web 容器的依賴項:

<dependency>
    <groupId>org.apache.tomcat.embed</groupId>
     <artifactId>tomcat-embed-core</artifactId>
     <version>8.5.11</version>
</dependency>

現在,讓我們添加必要的標籤,以成功地將 Tomcat 添加到 Maven 在構建時產生的 <em>.war</em> 文件中:

<build>
    <finalName>embeddedTomcatExample</finalName>
    <plugins>
        <plugin>
            <groupId>org.codehaus.mojo</groupId>
            <artifactId>appassembler-maven-plugin</artifactId>
            <version>2.0.0</version>
            <configuration>
                <assembleDirectory>target</assembleDirectory>
                <programs>
                    <program>
                        <mainClass>launch.Main</mainClass>
                        <name>webapp</name>
                    </program>
            </programs>
            </configuration>
            <executions>
                <execution>
                    <phase>package</phase>
                    <goals>
                        <goal>assemble</goal>
                    </goals>
                </execution>
            </executions>
        </plugin>
    </plugins>
</build>

如果你正在使用 Spring Boot,你可以改為將 Spring 的 spring-boot-starter-tomcat 依賴添加到你的 pom.xml 中:

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-tomcat</artifactId>
    <scope>provided</scope>
</dependency>

5.1. 通過屬性註冊

Spring Boot 支持通過 <em >application.properties</em >> 配置大部分可能的 Spring 設置。 在將必要的嵌入式 Servlet 依賴添加到你的 <em >pom.xml</em >> 後,你可以使用多種配置選項自定義和配置你的嵌入式 Servlet:

server.jsp-servlet.class-name=org.apache.jasper.servlet.JspServlet 
server.jsp-servlet.registered=true
server.port=8080
server.servlet-path=/

以下是一些可用於配置 DispatcherServlet 和靜態資源共享的應用程序設置。嵌入式 Servlet、SSL 支持和會話的設置也可用。

此處配置參數實在太多,無法一一列舉,您可以參閲 Spring Boot 文檔 以獲取完整列表。

5.2. 通過 YAML 進行配置

類似於這樣,我們也可以使用 YAML 來配置我們的嵌入式 Servlet 容器。 這需要使用專門的 YAML 屬性加載器——<em >YamlPropertySourceLoader</em>——它會暴露我們的 YAML 並使其中的鍵和值可供在我們的應用程序中使用。

YamlPropertySourceLoader sourceLoader = new YamlPropertySourceLoader();
PropertySource<?> yamlProps = sourceLoader.load("yamlProps", resource, null);

5.3. 通過 TomcatEmbeddedServletContainerFactory 進行程序化配置

通過對 EmbeddedServletContainerFactory 的子類實例進行配置,可以實現嵌入式 Servlet 容器的程序化配置。例如,可以使用 TomcatEmbeddedServletContainerFactory 來配置您的嵌入式 Tomcat servlet。

TomcatEmbeddedServletContainerFactory 封裝了 org.apache.catalina.startup.Tomcat 對象,並提供了額外的配置選項:

@Bean
public ConfigurableServletWebServerFactory servletContainer() {
    TomcatServletWebServerFactory tomcatContainerFactory
      = new TomcatServletWebServerFactory();
    return tomcatContainerFactory;
}

然後我們可以配置返回的實例:

tomcatContainerFactory.setPort(9000);
tomcatContainerFactory.setContextPath("/springboottomcatexample");

這些特定設置都可以使用之前描述的任何方法進行配置。

我們還可以直接訪問和操作org.apache.catalina.startup.Tomcat 對象:

Tomcat tomcat = new Tomcat();
tomcat.setPort(port);
tomcat.setContextPath("/springboottomcatexample");
tomcat.start();

6. 結論

在本文中,我們回顧了在 Jakarta EE 和 Spring Boot 應用程序中註冊 Servlet 的幾種方法。

user avatar
0 位用戶收藏了這個故事!
收藏

發佈 評論

Some HTML is okay.