詳細SpringBoot教程之(zhī)Web開發(三) - 新聞資訊 - 雲南小程序開發|雲南軟件開發|雲南網站建設-昆明融晨信息技術有限公司

159-8711-8523

雲南網建設/小程序開發/軟件開發

知識

不(bù)管是(shì)網站,軟件還是(shì)小程序,都要(yào / yāo)直接或間接能爲(wéi / wèi)您産生價值,我們在(zài)追求其視覺表現的(de)同時(shí),更側重于(yú)功能的(de)便捷,營銷的(de)便利,運營的(de)高效,讓網站成爲(wéi / wèi)營銷工具,讓軟件能切實提升企業内部管理水平和(hé / huò)效率。優秀的(de)程序爲(wéi / wèi)後期升級提供便捷的(de)支持!

您當前位置>首頁 » 新聞資訊 » 網站建設 >

詳細SpringBoot教程之(zhī)Web開發(三)

發表時(shí)間:2020-2-26

發布人(rén):融晨科技

浏覽次數:54

寫在(zài)前面

鑒于(yú)有人(rén)留言說(shuō)想要(yào / yāo)學習SpringBoot相關的(de)知識,我這(zhè)裏打算寫一個(gè)SpringBoot系列的(de)相關博文,目标呢是(shì)想讓看了(le/liǎo)這(zhè)一系列博文的(de)同學呢,能夠對SpringBoot略窺門徑,這(zhè)一系列的(de)博文初步都定下來(lái)包括SpringBoot介紹、入門、配置、日志相關、web開發、數據訪問、結合docker、緩存、消息隊列、檢索、任務安全、分布式等等一系列的(de)博文,工作量很大(dà),是(shì)個(gè)漫長的(de)過程,每一步我都盡量詳細,配上(shàng)截圖說(shuō)明,也(yě)希望對看的(de)同學真的(de)有用。
單純就(jiù)是(shì)想分享技術博文,還想說(shuō)一句就(jiù)是(shì),如果覺得有用,請點個(gè)關注、給個(gè)贊吧,也(yě)算對我來(lái)說(shuō)是(shì)個(gè)寬慰,畢竟也(yě)得掉不(bù)少頭發,嘿嘿嘿

系列文章傳送條

詳細SpringBoot教程之(zhī)入門(一)
詳細SpringBoot教程之(zhī)入門(二)
詳細SpringBoot教程之(zhī)配置文件(一)
詳細SpringBoot教程之(zhī)配置文件(二)
詳細SpringBoot教程之(zhī)日志框架
詳細SpringBoot教程之(zhī)Web開發(一)
詳細SpringBoot教程之(zhī)Web開發(二)
詳細SpringBoot教程之(zhī)Web開發(三)
詳細SpringBoot教程之(zhī)數據訪問
詳細SpringBoot教程之(zhī)啓動配置原理
詳細SpringBoot教程之(zhī)緩存開發

錯誤處理機制

SpringBoot默認的(de)錯誤處理機制

我們接上(shàng)一篇博文的(de)項目,我們現在(zài)把攔截器關掉,直接在(zài)主配置文件注釋掉注入就(jiù)可以(yǐ)直接關掉了(le/liǎo),像這(zhè)樣
在(zài)這(zhè)裏插入圖片描述
然後我們現在(zài)通過浏覽器随便訪問一個(gè)不(bù)存在(zài)的(de)連接,會出(chū)現下面這(zhè)樣的(de)錯誤提示,應該不(bù)陌生吧,之(zhī)前肯定是(shì)遇到(dào)過的(de)。
在(zài)這(zhè)裏插入圖片描述
我們可以(yǐ)查看一下浏覽器發送請求的(de)請求頭,如下:
在(zài)這(zhè)裏插入圖片描述

當然SpringBoot還另外規定了(le/liǎo)客戶端訪問無效鏈接的(de)錯誤機制,如果我們通過客戶端訪問會返回一個(gè)默認的(de)json數據,像下面這(zhè)樣

{
	"timestamp": 1519637719324,
	"status": 404,
	"error": "Not Found",
	"message": "No message avaliable",
	"path":  "/dbc/aaa",
}

默認錯誤處理機制原理

老樣子(zǐ),我們想要(yào / yāo)錯誤處理機制也(yě)有自己的(de)自動配置類(之(zhī)前說(shuō)過,SpringBoot功能是(shì)通過配置文件來(lái)進行控制的(de),而(ér)配置文件一般是(shì)通過xxxAutoConfiguration這(zhè)樣的(de)自動配置類來(lái)實現的(de)),所以(yǐ)SpringBoot的(de)默認的(de)錯誤處理機制可以(yǐ)參照自動配置類,也(yě)就(jiù)是(shì)ErrorMvcAutoConfiguration。

ErrorMvcAutoConfiguration通過給給容器中添加了(le/liǎo)以(yǐ)下組件,來(lái)控制錯誤處理機制

  • DefaultErrorAttributes:幫我們在(zài)頁面共享信息;
  • BasicErrorController:處理默認/error請求
  • ErrorPageCustomizer:系統出(chū)現錯誤以(yǐ)後來(lái)到(dào)error請求進行處理;
  • DefaultErrorViewResolver:用來(lái)控制錯誤時(shí),啓用模闆引擎視圖,還是(shì)默認;

也(yě)就(jiù)是(shì)默認的(de)錯誤處理流程是(shì),一但系統出(chū)現4xx或者5xx之(zhī)類的(de)錯誤,ErrorPageCustomizer就(jiù)會生效(定制錯誤的(de)響應規則),接着就(jiù)會來(lái)到(dào)/error請求,然後就(jiù)可以(yǐ)通過BasicErrorController來(lái)進行處理,進行相應時(shí),響應頁面去哪個(gè)頁面是(shì)由DefaultErrorViewResolver解析得到(dào)的(de);

如何定制錯誤響應

如何定制錯誤頁面

如果有模闆引擎的(de)情況下(我們項目中使用的(de)是(shì)Thymeleaf模闆引擎),可以(yǐ)通過error/狀态碼的(de)形式來(lái)進行控制,也(yě)就(jiù)是(shì)說(shuō),我們可以(yǐ)将錯誤頁面命名爲(wéi / wèi)“錯誤狀态碼.html”,然後放在(zài)模闆引擎文件夾(即templates目錄下)裏面的(de)error文件夾下,沒有error文件夾就(jiù)創建一個(gè),發生此狀态碼的(de)錯誤就(jiù)會來(lái)到(dào) 對應的(de)頁面,因爲(wéi / wèi)SpringBoot規則中已經默認規定好了(le/liǎo)。

更準确的(de)将我們可以(yǐ)使用4xx和(hé / huò)5xx作爲(wéi / wèi)錯誤頁面的(de)文件名,進而(ér)來(lái)匹配該種類型的(de)所有錯誤,匹配的(de)時(shí)候遵循精确優先(優先尋找精确的(de)狀态碼.html),像下面這(zhè)樣
在(zài)這(zhè)裏插入圖片描述
我們在(zài)默認的(de)錯誤頁面中可以(yǐ)獲得如下信息:、

  • timestamp:時(shí)間戳
  • tstatus:狀态碼
  • terror:錯誤提示
  • texception:異常對象
  • tmessage:異常消息
  • terrors:JSR303數據校驗的(de)錯誤都在(zài)這(zhè)裏

這(zhè)裏要(yào / yāo)說(shuō)明一下的(de)是(shì),如果我們項目中沒有使用模闆引擎(或者模闆引擎找不(bù)到(dào)這(zhè)個(gè)錯誤頁面),就(jiù)會去靜态資源文件夾下找。如果靜态資源文件夾中也(yě)沒有錯誤頁面,就(jiù)是(shì)默認來(lái)到(dào)SpringBoot默認的(de)錯誤提示頁面。

如何定制錯誤的(de)json

可以(yǐ)自定義異常處理和(hé / huò)返回定制json數據,像下面這(zhè)樣,我們可以(yǐ)專門定義一個(gè)配置類用來(lái)解決錯誤定制的(de),我這(zhè)裏命名爲(wéi / wèi)MyExceptionHandler,然後通過@ExceptionHandler來(lái)定制響應的(de)相關錯誤,進而(ér)返回定制數據
在(zài)這(zhè)裏插入圖片描述
不(bù)過這(zhè)樣處理會有個(gè)問題,就(jiù)是(shì)我們确實是(shì)定制了(le/liǎo)返回的(de)json數據,但是(shì)本來(lái)SpringBoot會根據我們用什麽訪問請求,然後響應什麽,比如我們用浏覽器訪問,響應html頁面,客戶端響應json數據,現在(zài)這(zhè)樣寫,返回的(de)都是(shì)接送數據了(le/liǎo),所以(yǐ)我們需要(yào / yāo)換種方式,通過将相應轉發到(dào)/error進行自适應響應效果處理,像下面這(zhè)樣
在(zài)這(zhè)裏插入圖片描述

攜帶定制數據

前面我們講過,出(chū)現錯誤以(yǐ)後,會來(lái)到(dào)/error請求,會被BasicErrorController處理,響應出(chū)去可以(yǐ)獲取的(de)數據是(shì)由getErrorAttributes得到(dào)的(de)(是(shì)AbstractErrorController(ErrorController)規定的(de)方法)

所以(yǐ),我們可以(yǐ)通過編寫一個(gè)ErrorController的(de)實現類或者是(shì)編寫AbstractErrorController的(de)子(zǐ)類,然後放在(zài)容器中,我們要(yào / yāo)知道(dào),頁面上(shàng)能用的(de)數據,或者是(shì)json返回能用的(de)數據都是(shì)通過errorAttributes.getErrorAttributes得到(dào),也(yě)就(jiù)是(shì)說(shuō)容器中DefaultErrorAttributes.getErrorAttributes()來(lái)默認進行數據處理的(de),我們定制自定義ErrorAttributes,如下
在(zài)這(zhè)裏插入圖片描述
這(zhè)樣,我們的(de)錯誤響應是(shì)自适應的(de),可以(yǐ)通過定制ErrorAttributes改變需要(yào / yāo)返回的(de)内容,就(jiù)不(bù)在(zài)隻有原先的(de)默認屬性了(le/liǎo),形象的(de)将,我們返回的(de)信息就(jiù)會是(shì)如下

  • timestamp:時(shí)間戳
  • tstatus:狀态碼
  • terror:錯誤提示
  • texception:異常對象
  • tmessage:異常消息
  • terrors:JSR303數據校驗的(de)錯誤都在(zài)這(zhè)裏
  • author: dbc

配置嵌入式Servlet容器

SpringBoot默認使用Tomcat作爲(wéi / wèi)嵌入式的(de)Servlet容器,這(zhè)我們都是(shì)知道(dào)的(de)
在(zài)這(zhè)裏插入圖片描述
那麽這(zhè)個(gè)時(shí)候我們如果想要(yào / yāo)換成其他(tā)的(de)Servlet容器,我們應該怎麽做呢?那麽接下來(lái)我們就(jiù)來(lái)講解怎麽搞

如何定制和(hé / huò)修改Servlet容器的(de)相關配置

修改和(hé / huò)server有關的(de)配置(ServerProperties即也(yě)是(shì)使用WebServerFactoryCustomizer),在(zài)主配置文件中可以(yǐ)通過這(zhè)樣的(de)形式來(lái)設置
在(zài)這(zhè)裏插入圖片描述
除了(le/liǎo)在(zài)主配置文件中進行相關的(de)設置之(zhī)外,我們還可以(yǐ)通過注冊WebServerFactoryCustomizer組件來(lái)在(zài)類中自定義配置,也(yě)就(jiù)是(shì)嵌入式的(de)Servlet容器的(de)定制器,來(lái)修改Servlet容器的(de)配置
在(zài)這(zhè)裏插入圖片描述

注冊Servlet三大(dà)組件

Servlet三大(dà)組件分别是(shì)Servlet、Filter、Listener,如果我們原先熟悉SpringMVC開發的(de)應該知道(dào),我們在(zài)Webapp下面的(de)web.xml中,經常需要(yào / yāo)配置這(zhè)三大(dà)組件用來(lái)過濾監聽相關的(de)請求,而(ér)在(zài)SpringBoot中,由于(yú)SpringBoot默認是(shì)以(yǐ)jar包的(de)方式啓動嵌入式的(de)Servlet容器來(lái)啓動SpringBoot的(de)web應用,所以(yǐ)并沒有沒有web.xml文件。但是(shì)我們依舊可以(yǐ)通過SpringBoot特有的(de)相關注冊Bean進行注冊,分别是(shì)

  • ServletRegistrationBean
//注冊三大(dà)組件
@Bean
public ServletRegistrationBean myServlet(){
    ServletRegistrationBean registrationBean = new ServletRegistrationBean(new MyServlet(),"/myServlet");
    return registrationBean;
}

  • FilterRegistrationBean
@Bean
public FilterRegistrationBean myFilter(){
    FilterRegistrationBean registrationBean = new FilterRegistrationBean();
    registrationBean.setFilter(new MyFilter());
    registrationBean.setUrlPatterns(Arrays.asList("/hello","/myServlet"));
    return registrationBean;
}
  • ServletListenerRegistrationBean
@Bean
public ServletListenerRegistrationBean myListener(){
    ServletListenerRegistrationBean<MyListener> registrationBean = new ServletListenerRegistrationBean<>(new MyListener());
    return registrationBean;
}

SpringBoot幫我們自動配置SpringMVC的(de)時(shí)候,會自動的(de)注冊SpringMVC的(de)前端控制器,即DIspatcherServlet,我們通過查閱DispatcherServletAutoConfiguration發現,會默認攔截,“/”的(de)所有請求,包括靜态資源,但是(shì)不(bù)攔截jsp請求,/*會攔截jsp,可以(yǐ)通過server.servletPath來(lái)修改SpringMVC前端控制器默認攔截的(de)請求路徑

更換其他(tā)嵌入式Servlet容器

我們知道(dào),SpringBoot是(shì)默認支持Tomcat的(de),也(yě)就(jiù)是(shì)在(zài)pom.xml中通過如下依賴引入的(de)
在(zài)這(zhè)裏插入圖片描述
所以(yǐ),我們不(bù)能整個(gè)去除web依賴,因爲(wéi / wèi)裏面還有其他(tā)除了(le/liǎo)Tomcat的(de)依賴,所以(yǐ)我們在(zài)web下直接排除Tomcat的(de)依賴就(jiù)可以(yǐ)了(le/liǎo),然後添加其他(tā)的(de)嵌入式Servlet容器的(de)依賴,不(bù)同的(de)嵌入式Servlet依賴如下

Jetty

在(zài)這(zhè)裏插入圖片描述

Undertow

在(zài)這(zhè)裏插入圖片描述

使用外置的(de)Servlet容器

在(zài)我們之(zhī)前學習的(de)SpringBoot應用,是(shì)通過嵌入式Servlet容器,應用打成可執行的(de)jar,這(zhè)樣做的(de)優點顯而(ér)易見,就(jiù)是(shì)簡單、便攜,但是(shì)缺點就(jiù)是(shì)默認不(bù)支持JSP、優化定制比較複雜(使用定制器ServerProperties、自定義WebServerFactoryCustomizer,自己編寫嵌入式Servlet容器的(de)創建工廠ConfigurableWebServerFactory);
但是(shì)不(bù)着急,我們可以(yǐ)使用外置的(de)Servlet容器,也(yě)就(jiù)是(shì)外面安裝Tomcat,然後應用war包的(de)方式打包。

步驟

  • 必須創建一個(gè)war項目,利用idea創建好目錄結構
    在(zài)這(zhè)裏插入圖片描述

  • 将嵌入式的(de)Tomcat指定爲(wéi / wèi)provided;

<dependency>
   <groupId>org.springframework.boot</groupId>
   <artifactId>spring-boot-starter-tomcat</artifactId>
   <scope>provided</scope>
</dependency>
  • 必須編寫一個(gè)SpringBootServletInitializer的(de)子(zǐ)類,并調用configure方法
public class ServletInitializer extends SpringBootServletInitializer {

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

}
  • 啓動服務器就(jiù)可以(yǐ)使用;

我這(zhè)裏說(shuō)一下jar包和(hé / huò)war包啓動的(de)區别

  • jar包:執行SpringBoot主類的(de)main方法,啓動ioc容器,創建嵌入式的(de)Servlet容器;
  • war包:啓動服務器,服務器啓動SpringBoot應用通過SpringBootServletInitializer,啓動ioc容器;

相關案例查看更多