SpringBoot這些Web知識(shí)點(diǎn),你知道嗎?
環(huán)境:SpringBoot2.7.16
1. Servlet/Filter/*Listener注冊(cè)
任何Spring bean的Servlet、Filter或 *Listener實(shí)例都會(huì)自動(dòng)注冊(cè)到容器中。如果你想從應(yīng)用程序中引用一個(gè)值,@Value獲取application.properties值。
@Component
public class DemoServlet extends HttpServlet {
  @Override
  protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
    resp.getWriter().println("demo servlet") ;
  }
}直接將Servlet注冊(cè)為Bean,容器會(huì)自動(dòng)注冊(cè)。有一點(diǎn)需要注意:如果僅僅只有一個(gè)Servlet,那它的訪問url是 '/' 。這會(huì)與默認(rèn)的DispatcherServlet路徑一樣。如果你有多個(gè)Servlet,那么訪問路徑將是:'/beanName/',如上面的DemoServlet默認(rèn)的訪問路徑:'/demoServlet/'。
如果基于約定的映射不夠靈活,可以使用ServletRegistrationBean、FilterRegistrationBean和ServletListenerRegistrationBean類進(jìn)行完全控制。
過濾器Filter默認(rèn)映射路徑是:'/*'。
提示:
若要查看應(yīng)用程序中每個(gè)Filter的順序,請(qǐng)為web日志記錄組啟用調(diào)試級(jí)別日志記錄(logging.level.web=debug)。注冊(cè)過濾器的詳細(xì)信息,包括它們的順序和URL模式,將在啟動(dòng)時(shí)記錄下來。
2. Servlet Conetxt初始化
嵌入式Servlet容器不會(huì)直接執(zhí)行Servlet3.0+ javax.servlet.ServletContainerInitializer接口或Spring的org.springframework.web.WebApplicationInitializer接口。這樣做是有意為之,目的是降低在war中運(yùn)行的第三方庫(kù)破壞Spring Boot應(yīng)用程序的風(fēng)險(xiǎn)。
如果需要在Spring Boot應(yīng)用程序中執(zhí)行Servlet上下文初始化,應(yīng)該注冊(cè)一個(gè)實(shí)現(xiàn)org.springframework.boot.web.servlet.ServletContextInitializer接口的bean。onStartup方法提供了對(duì)ServletContext的訪問,如果有必要,可以很容易地將其用作現(xiàn)有WebApplicationInitializer的適配器。
3. 掃描Servlet/Filter/*Listener
在使用嵌入式容器時(shí),可以通過使用@ServletComponentScan來啟用自動(dòng)注冊(cè)帶有@WebServlet、@WebFilter和@WebListener注解的類。
@ServletComponentScan在獨(dú)立容器中沒有效果,取而代之的是容器的內(nèi)置發(fā)現(xiàn)機(jī)制。
4. ServletWebServerApplicationContext
在底層,Spring Boot使用了另一種類型的ApplicationContext來支持嵌入式servlet容器。ServletWebServerApplicationContext是一種特殊類型的WebApplicationContext,它通過搜索單個(gè)ServletWebServerFactory bean來引導(dǎo)自己。通常TomcatServletWebServerFactory、jetttyservletwebserverfactory或UndertowServletWebServerFactory都是自動(dòng)配置的。
在嵌入式容器設(shè)置中,ServletContext被設(shè)置為服務(wù)器啟動(dòng)的一部分,該啟動(dòng)發(fā)生在應(yīng)用程序上下文初始化期間。因此,ApplicationContext中的bean不能可靠地用ServletContext進(jìn)行初始化。解決這個(gè)問題的一種方法是注入ApplicationContext作為bean的依賴項(xiàng),并僅在需要時(shí)訪問ServletContext。另一種方法是在服務(wù)器啟動(dòng)后使用回調(diào)函數(shù)。這可以使用ApplicationListener來監(jiān)聽ApplicationStartedEvent,如下所示:
public class PackContext implements ApplicationListener<ApplicationStartedEvent> {
  private ServletContext servletContext;
  @Override
  public void onApplicationEvent(ApplicationStartedEvent event) {
      ApplicationContext applicationContext = event.getApplicationContext() ;
      this.servletContext = ((WebApplicationContext) applicationContext).getServletContext() ;
  }
}5. 自定義Servlet容器
可以使用Spring Environment屬性來配置常見的Servlet容器設(shè)置。通常,會(huì)在application.properties或application.yaml文件中定義屬性。
常見的服務(wù)器設(shè)置包括:
- 網(wǎng)絡(luò)設(shè)置:偵聽傳入HTTP請(qǐng)求的端口(server.port)、綁定到server.address的接口地址等。
 - 會(huì)話設(shè)置:會(huì)話是否持久(server.servlet.session.persistent),會(huì)話超時(shí)(server.servlet.session.timeout),會(huì)話數(shù)據(jù)的位置(server.servlet.session.store-dir),以及會(huì)話cookie配置(server.servlet.session.cookie.*)。
 - 錯(cuò)誤管理:錯(cuò)誤頁(yè)的位置(server.error.path)等等。
 - SSL
 - HTTP compression
 
Spring Boot盡可能地嘗試公開通用設(shè)置,但并不總是可行。對(duì)于這些情況,專用的命名空間提供特定于服務(wù)器的自定義(請(qǐng)參見server.tomcat和server.undertow)。例如,可以用嵌入式Servlet容器的特定功能配置訪問日志。
字符編碼
用于請(qǐng)求和響應(yīng)處理的嵌入式servlet容器的字符編碼行為可以使用server.servlet.encoding.*配置屬性進(jìn)行配置。
當(dāng)請(qǐng)求的Accept-Language頭指示請(qǐng)求的區(qū)域設(shè)置時(shí),servlet容器將自動(dòng)將其映射到字符集。每個(gè)容器都提供默認(rèn)的區(qū)域設(shè)置到字符集映射,您應(yīng)該驗(yàn)證它們是否滿足應(yīng)用程序的需要。如果沒有,請(qǐng)使用server.servlet.encoding.mapping配置屬性自定義映射,如下:
server:
  servlet:
    encoding:
      mapping:
        ko: "UTF-8"通過編程自定義
如果需要以編程方式配置嵌入式servlet容器,可以注冊(cè)一個(gè)實(shí)現(xiàn)WebServerFactoryCustomizer接口的Spring bean。WebServerFactoryCustomizer提供對(duì)ConfigurationServletWebServerFactory的訪問,其中包括許多自定義setter方法。示例:
@Component
public class MyWebServerFactoryCustomizer implements WebServerFactoryCustomizer<ConfigurableServletWebServerFactory> {
  @Override
  public void customize(ConfigurableServletWebServerFactory server) {
    // 設(shè)置服務(wù)端口
    server.setPort(9000) ;
    // 設(shè)置異步超時(shí)時(shí)間
    server.addConnectorCustomizers((connector) -> connector.setAsyncTimeout(Duration.ofSeconds(20).toMillis())) ; 
  }
}直接自定義ConfigurableServletWebServerFactory
對(duì)于需要從ServletWebServerFactory進(jìn)行擴(kuò)展的更高級(jí)的用例,你可以自己公開此類類型的bean。該接口提供如下配置
public interface ConfigurableServletWebServerFactory extends ConfigurableWebServerFactory, ServletWebServerFactory, WebListenerRegistry 
  void setContextPath(String contextPath);
  void setDisplayName(String displayName);
  void setSession(Session session);
  void setRegisterDefaultServlet(boolean registerDefaultServlet);
  void setMimeMappings(MimeMappings mimeMappings);
  void setDocumentRoot(File documentRoot);
  void setInitializers(List<? extends ServletContextInitializer> initializers);
  void addInitializers(ServletContextInitializer... initializers);
  void setJsp(Jsp jsp);
  void setLocaleCharsetMappings(Map<Locale, Charset> localeCharsetMappings);
  void setInitParameters(Map<String, String> initParameters);
  void setCookieSameSiteSuppliers(List<? extends CookieSameSiteSupplier> cookieSameSiteSuppliers);
  void addCookieSameSiteSuppliers(CookieSameSiteSupplier... cookieSameSiteSuppliers);
}6. JSP限制
當(dāng)運(yùn)行使用嵌入式servlet容器(并打包為可執(zhí)行歸檔文件)的Spring Boot應(yīng)用程序時(shí),JSP支持存在一些限制。
- 使用Jetty和Tomcat,如果你使用war打包,它應(yīng)該可以正常工作。當(dāng)使用java -jar啟動(dòng)時(shí),可執(zhí)行war可以正常工作,也可以部署到任何標(biāo)準(zhǔn)容器。在使用可執(zhí)行jar時(shí),不支持jsp。
 - Undertow不支持JSP。
 - 創(chuàng)建自定義error.jsp頁(yè)面不會(huì)覆蓋錯(cuò)誤處理的默認(rèn)視圖。應(yīng)該使用自定義錯(cuò)誤頁(yè)面。
 
以上是本篇文章的全部?jī)?nèi)容,希望對(duì)你有所幫助。















 
 
 







 
 
 
 