Spring Boot |配置和切換Servlet容器


在使用SpringBoot之前,需要將Web應用打成war包,在外部配置好Tomcat的環境(Tomcat就是Servlet的容器),將web應用放在Tomcat上,在外部啓動Tomcat;使用了SpringBoot時,無需使用外部Tomcat環境,原因就在於SpringBoot自帶了嵌入式的Tomcat。本文詳細介紹如何配置嵌入式Servlet容器。

一、配置嵌入式Servlet容器

SpringBoot默認使用Tomcat作爲嵌入式的Servlet容器,可以在IDEA的pom文件中showDependencies,查看依賴圖:

在這裏插入圖片描述
由依賴圖可以發現SpringBoot默認使用了嵌入式的Servlet容器。這就出現了一個問題,之前使用外置的Tomcat如果想定製或優化,可以在conf目錄的server.xml文件中修改。使用了SpringBoot後,可以在application.properties文件中定製和修改與server相關的配置。實際上修改的是ServerProperties類的屬性。

  • 通用的Servlet容器可以設置爲server.xxx
  • Tomcat相關的可以設置爲tomcat.xxx
配置 說明
server.port=8081 設置項目訪問路徑
server.servlet.context-path=/crud 修改訪問映射
server.tomcat.uri‐encoding=UTF‐8 設置編碼格式

除了在application.properties文件中修改配置,還可以像下面的代碼這樣編寫一個嵌入式Servlet容器定製器 ,來修改Servlet容器的配置,兩種方式雖然實現上不同,但底層都是相同的原理。

@Configuration
public class MyServerConfig {
    /**
     * 配置嵌入式Servlet容器
     */
    @Bean
    public WebServerFactoryCustomizer<ConfigurableWebServerFactory> webServerFactoryCustomizer(){
        return new WebServerFactoryCustomizer<ConfigurableWebServerFactory>(){
            //定製嵌入式Servlet容器相關的規則
            @Override
            public void customize(ConfigurableWebServerFactory factory) {
                factory.setPort(8083);
            }
        };
    }
}

二、註冊Servlet三大組件

SpringBoot默認是以jar包的方式啓動嵌入式的Servlet容器,進而啓動SpringBoot的web應用,所以沒有web.xml文件。(標準的Web目錄結構,三大組件配置在src/main/webapp/WEB-INF/web.xml)。

Servlet三大組件 註冊方式 自己的組件需要做的工作
Servlet ServletRegistrationBean 繼承HttpServlet
Filter FilterRegistrationBean 實現Filter
Listener ServletListenerRegistrationBean 實現ServletContextListener

2.1 使用ServletRegistrationBean註冊Servlet

@Configuration
public class MyServerConfig {
    /**
     * 註冊Servlet:使用ServletRegistrationBean
     */
    @Bean
    public ServletRegistrationBean myServlet(){
        ServletRegistrationBean registrationBean = new ServletRegistrationBean(new MyServlet(),"/myServlet");
        return registrationBean;
    }
}

創建自己的Servlet需要實現HttpServlet接口。

public class MyServlet extends HttpServlet {
    //處理GET請求
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        doPost(req, resp);
    }

    //處理POST請求
    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
       resp.getWriter().write("Hello MyServlet");
    }
}

2.2 使用FilterRegistrationBean註冊Filter

@Configuration
public class MyServerConfig {
    /**
     * 註冊Filter:使用FilterRegistrationBean
     */
    @Bean
    public FilterRegistrationBean myFilter() {
        FilterRegistrationBean registrationBean = new FilterRegistrationBean();
        registrationBean.setFilter(new MyFilter());
        registrationBean.setUrlPatterns(Arrays.asList("/hello", "/myServlet"));
        return registrationBean;
    }
}

創建自己的Filter需要實現Filter接口。

public class MyFilter implements Filter {

    @Override
    public void init(FilterConfig filterConfig) throws ServletException {

    }

    @Override
    public void destroy() {

    }

    @Override
    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
        System.out.println("MyFilter process...");
        filterChain.doFilter(servletRequest,servletResponse);
    }
}

2.3 使用ServletListenerRegistrationBean註冊Listener

@Configuration
public class MyServerConfig {
    /**
     * 註冊Listener:使用ServletListenerRegistrationBean
     */
    @Bean
    public ServletListenerRegistrationBean myListener() {
        ServletListenerRegistrationBean<MyListener> registrationBean = new ServletListenerRegistrationBean<MyListener>(new MyListener());
        return registrationBean;
    }
}

創建自己的Listener需要實現ServletContextListener接口。

public class MyListener implements ServletContextListener{
    @Override
    public void contextInitialized(ServletContextEvent sce) {
        System.out.println("contextInitialized...web應用啓動");
    }

    @Override
    public void contextDestroyed(ServletContextEvent sce) {
        System.out.println("contextDestroyed...當前web項目銷燬");
    }
}

三、切換爲其他嵌入式Servlet容器

SpringBoot默認使用Tomcat,除此之外,SpringBoot還支持Jetty容器(適合長鏈接應用,)、Undertow容器(不支持JSP,但是性能高、非阻塞、併發性能好)

在這裏插入圖片描述

3.1 切換爲Jetty容器

打開pom文件的依賴圖,excloud掉spring-boot-starter-tomcat之後,引入Jetty容器。

        <!--引入Jetty容器-->
        <dependency>
            <artifactId>spring-boot-starter-jetty</artifactId>
            <groupId>org.springframework.boot</groupId>
        </dependency>

等待加載完畢,就可以看到生成了Jetty的依賴。
在這裏插入圖片描述

3.2 切換爲Undertow容器

打開pom文件的依賴圖,excloud掉spring-boot-starter-tomcat之後,引入Undertow容器。

  		<!--引入Undertow容器-->
        <dependency>
            <artifactId>spring-boot-starter-undertow</artifactId>
            <groupId>org.springframework.boot</groupId>
        </dependency>

等待加載完畢,就可以看到生成了Undertow的依賴。
在這裏插入圖片描述

四、切換爲外部Servlet容器

使用嵌入式Servlet容器的優點在於簡單、便捷、直接打成jar包就能運行;缺點是默認不支持JSP,需要優化定製時比較複雜(需要用到ServerPropertiesEmbeddedServletContainerCustomizer或自己編寫嵌入式Servlet容器的創建工廠)。使用外置的Servlet容器,即在外部安裝Tomcat,應用war包的形式打包。

4.1 配置外部Servlet容器

首先需要創建一個打war包的SpringBoot項目,並且手動創建src\main\webapp目錄和web.xml文件。

在這裏插入圖片描述
然後引入自己外部的tomcat。
在這裏插入圖片描述

4.2 使用外部Servlet容器的步驟

第一步:創建一個war項目(利用idea創建好目錄結構)

第二步:將嵌入式的Tomcat指定爲provided。

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

第三步:編寫一個SpringBootServletInitializer的子類,並調用configure方法。
該步驟IDEA幫助我們自動完成了。

public class ServletInitializer extends SpringBootServletInitializer {
    @Override
    protected SpringApplicationBuilder configure(SpringApplicationBuilder application) {
    	 //傳入SpringBoot應用的主程序
        return application.sources(SpringBoot04WebJspApplication.class);
    }
}

第四步:啓動服務器就可以使用。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章