熵增學院-Anders-劍走偏鋒,瞭解Spring Boot內部Servlet容器

還記得大明湖畔的servlet嗎?其實Spring Boot支持內嵌的Tomcat, Jetty和Undertow服務器,多數開發者只須要使用合適的'Starter'來獲取一個徹底配置好的實例便可,內嵌服務器默認監聽8080端口的HTTP請求。java

這樣子是否是以爲很簡單,很方便,有種開發nodejs的感受.....node

 

1. 在SpringBoot中還有Servlets, Filters和listeners嗎?

使用內嵌servlet容器時,你能夠經過使用Spring beans或掃描Servlet組件的方式註冊Servlets,Filters及特定Servlet相關的全部listeners(好比HttpSessionListener)。web

將Servlets,Filters和listeners註冊爲Spring beansspring

全部ServletFilter或Servlet *Listener實例,只要是Spring bean,都會註冊到內嵌容器中。若是想在配置期間引用application.properties的屬性,這是很是方便的。默認狀況下,若是上下文只包含單個Servlet,那它將被映射到/。若是存在多個Servlet beans,那麼bean的名稱將被用做路徑的前綴,過濾器將映射到/*json

若是基於約定(convention-based)的映射不夠靈活,你可使用ServletRegistrationBeanFilterRegistrationBeanServletListenerRegistrationBean實現徹底的控制。tomcat

 

1 建立servlet服務器

package com.gala.servlet;
import java.io.IOException;
import java.io.PrintWriter;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
public class TestServlet extends HttpServlet {    
  private static final long serialVersionUID = -2646554587718007415L;    
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {        
    // 設置返回類型爲json
        resp.setContentType("application/json");        
        // 設置返回字符集
        resp.setCharacterEncoding("UTF-8");        
        // 輸出對象
        PrintWriter writer = resp.getWriter();        
        // 輸出error消息
        writer.write("成功執行doGet方法");
        writer.close();
    }
}

2 使用Bean註冊Servlet(單個Servlet)cookie

package com.gala.servlet.conf;
import org.springframework.boot.web.servlet.ServletRegistrationBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import com.gala.servlet.TestServlet;
@Configuration
public class ServletConfiguration {    
        @Bean
    public ServletRegistrationBean<TestServlet> servletRegistrationBean() {        
        return new ServletRegistrationBean<TestServlet>(new TestServlet(), "/test");
    }
}

 

SpringBoot自動裝配Servlet(多個Servlet)網絡

 

SpringBoot內部提供了註解@ServletComponentScan,這個註解的做用就是自動掃描咱們SpringBoot項目內的有關Servlet配置,自動裝配到咱們的項目中。session

 

TestServlet須要與ServletConfiguration同目錄或在其子目錄中

 

修改ServletConfiguration,增長@ServletComponentScan

package com.gala.servlet.conf;

import org.springframework.boot.web.servlet.ServletComponentScan;
import org.springframework.context.annotation.Configuration;

@Configuration
@ServletComponentScan
public class ServletConfiguration {

}

修改TestServlet,增長@WebServlet(urlPatterns = "/test2")

package com.gala.servlet;

import java.io.IOException;
import java.io.PrintWriter;

import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

@WebServlet(urlPatterns = "/test2")
public class TestServlet extends HttpServlet {

    private static final long serialVersionUID = -2646554587718007415L;

    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        // 設置返回類型爲json
        resp.setContentType("application/json");
        // 設置返回字符集
        resp.setCharacterEncoding("UTF-8");
        // 輸出對象
        PrintWriter writer = resp.getWriter();
        // 輸出error消息
        writer.write("成功執行doGet方法");
        writer.close();
    }
}

 

 

2. 在Filters和listeners怎麼使用

 

內嵌servlet容器不會直接執行Servlet 3.0+的javax.servlet.ServletContainerInitializer接口,或Spring的org.springframework.web.WebApplicationInitializer接口,這樣設計的目的是下降war包內運行的第三方庫破壞Spring Boot應用的風險。

若是須要在Spring Boot應用中執行servlet上下文初始化,你須要註冊一個實現org.springframework.boot.context.embedded.ServletContextInitializer接口的bean。onStartup方法能夠獲取ServletContext,若是須要的話能夠輕鬆用來適配一個已存在的WebApplicationInitializer。

掃描Servlets, Filters和listeners

當使用一個內嵌容器時,經過@ServletComponentScan能夠啓用對註解@WebServlet,@WebFilter和@WebListener類的自動註冊。

注 在獨立的容器(非內嵌)中@ServletComponentScan不起做用,取爲代之的是容器內建的discovery機制。

 

3. 自定義配置servlet容器

 

常見的Servlet容器配置能夠經過Spring Environment進行設置,一般將這些屬性定義到application.properties文件中。

常見的服務器配置包括:

網絡設置:監聽進入Http請求的端口(server.port),接口綁定地址server.address等。

Session設置:session是否持久化(server.session.persistence),session超時時間(server.session.timeout),session數據存放位置(server.session.store-dir),session-cookie配置(server.session.cookie.*)。

Error管理:錯誤頁面的位置(server.error.path)等。

SSL。

HTTP壓縮

 

Spring Boot會盡可能暴露經常使用設置,但這並不老是可能的。對於不可能的狀況,可使用專用的命名空間提供server-specific配置(查看server.tomcat,server.undertow)。例如,能夠根據內嵌servlet容器的特性對access logs進行不一樣的設置。

注 具體參考ServerProperties。

 

4. 老生常談的JSP

 

當使用內嵌servlet容器運行Spring Boot應用時(並打包成一個可執行的存檔archive),容器對JSP的支持有一些限制

Tomcat只支持war的打包方式,不支持可執行jar。

Jetty只支持war的打包方式。

Undertow不支持JSPs。

建立的自定義error.jsp頁面不會覆蓋默認的error handling視圖。

本文相關視頻

相關文章
相關標籤/搜索