隨著異步 I/O 和 Netty 等框架的流行,響應式編程逐漸走入大眾的視野。但是,響應式編程本身并不是太新的概念,這個術語最早出現在 1985 年 David Harel 和 Amir Pnueli 的論文“響應式系統的開發”之中,他們對復雜計算機系統的特征進行了歸納,提出了一種新穎的二分方式:轉換式(Transformative)與響應式(Reactive)系統。轉換式系統接收已知的一組輸入,轉換這些輸入并產生輸出,而響應式系統則會持續受到外部環境的刺激,它們的角色就是持續響應刺激。在構建響應式 Web 服務上,Spring 5 中引入了全新的編程框架,那就是 Spring WebFlux。作為一款新型的 Web 服務開發框架,它與傳統的 WebMVC 相比具體有哪些優勢呢?
介紹
Spring WebFlux 作為一個響應式 (reactive-stack) web 框架補充,在 5.0 的版本開始加入到 Spring 全家桶。這是一個完全非阻塞的,支持 Reactive Streams, 運行在諸如 Netty, Undertow, 以及 Servlet 3.1+ 容器上的,Spring WebFlux 構建在 Reactor 框架之上,提供了基于注解和函數式兩種方式來配置和運行。Spring WebFlux 可以讓你使用更少的線程去處理并發請求,同時能夠讓你使用更少的硬件資源來拓展你的應用。WebFlux 使用Netty作為默認的web服務器,其依賴于非阻塞IO,并且每次寫入都不需要額外的線程進行支持。也可以使用Tomcat、Jetty容器,不同與SpringMVC依賴于Servlet阻塞IO,并允許應用程序在需要時直接使用Servlet API,WebFlux依賴于Servlet 3.1非阻塞IO。使用Undertow作為服務器時,WebFlux直接使用Undertow API而不使用Servlet API。
特點
場景
WebFlux 用于構建響應式 Web 服務。微服務架構的興起為 WebFlux 的應用提供了一個很好的場景。我們知道在一個微服務系統中,存在數十乃至數百個獨立的微服務,它們相互通信以完成復雜的業務流程。這個過程勢必會涉及大量的 I/O 操作,尤其是阻塞式 I/O 操作會整體增加系統的延遲并降低吞吐量。如果能夠在復雜的流程中集成非阻塞、異步通信機制,我們就可以高效處理跨服務之間的網絡請求。針對這種場景,WebFlux 是一種非常有效的解決方案。控制層一旦使用 Spring WebFlux,它下面的安全認證層、數據訪問層都必須使用 Reactive API。其次,Spring Data Reactive Repositories 目前只支持 MongoDB、Redis 和 Couchbase 等幾種不支持事務管理的 NOSQL。技術選型時一定要權衡這些弊端和風險。
響應式編程
響應式編程是一種面向數據流和變化傳播的編程范式,這意味著可以在編程語言中很方便地表達靜態或動態的數據流,而相關的計算模型會自動將變化的值通過數據流進行傳播,電子表格程序就是響應式編程的。
響應式應用應該具備如下的四個特點:
并發模型
WebFlux模型主要依賴響應式編程庫Reactor,Reactor 有兩種模型,Flux 和 Mono,提供了非阻塞、支持回壓機制的異步流處理能力。WebFlux API接收普通Publisher作為輸入,在內部使其適配Reactor類型,使用它并返回Flux或Mono作為輸出。
介紹
SpringMvc是一種基于java的實現Mvc設計模式的請求驅動類型的輕量級web框架,屬于SpringFrameWork的后續產品,已經融合在Spring Web Flow中,SpringMvc已經成為目前最主流的MVC框架之一,并且隨著Spring3.0的發布,全面超越Struts2,成為最優秀的mvc框架,他通過一套注解,讓一個簡單的java類成為處理請求的控制器,他無需實現任何接口,同時他還支持RESTful編程風格的請求。
特點
MVC
Spring web MVC框架提供了MVC(模型 - 視圖 - 控制器)架構和用于開發靈活和松散耦合的Web應用程序的組件。 MVC模式導致應用程序的不同方面(輸入邏輯,業務邏輯和UI邏輯)分離,同時提供這些元素之間的松散耦合。
并發模型
servlet由servlet container進行生命周期管理。container啟動時構造servlet對象并調用servlet init()進行初始化;container關閉時調用servlet destory()銷毀servlet;container運行時接受請求,并為每個請求分配一個線程(一般從線程池中獲取空閑線程)然后調用service()。
處理請求的時候同步操作,一個請求對應一個線程來處理,并發上升,線程數量就會上漲(上線文切換,內存消耗大)影響請求的處理時間。現代系統多數都是IO密集的,同步處理讓線程大部分時間都浪費在了IO等待上面。雖然Servlet3.0后提供了異步請求處理與非阻塞IO支持,但是使用它會遠離Servlet API的其余部分,比如其規范是同步的(Filter, Servlet)或阻塞的(getParameter,getPart),而且其對響應的寫入仍然是阻塞的。
Spring WebFlux 不是 Spring MVC 的替代方案,Spring WebFlux 是 Spring Framework 5.0中引入的新的響應式web框架。與Spring MVC不同,它不需要Servlet API,是完全異步且非阻塞的,并且通過Reactor項目實現了Reactive Streams規范。Spring MVC依然構建在 Servlet API 以及 Servlet 容器之上;Spring Security 為兩種不同的技術棧提供了安全性的支持,Spring Data 分別為兩種不同的技術棧實現了 Repository;在數據訪問方面,響應式 Repository 已經涵蓋了 Mongo、Cassandra、Redis 以及 Couchbase。但是在關系型數據庫方面,因為 JBDC 規范本身就是阻塞式的,所以進展并不明顯。但是,像 PostgreSQL 和 MySQL 已經有了異步驅動。異步非阻塞并不會使程序運行得更快。WebFlux 并不能使接口的響應時間縮短,它僅僅能夠提升吞吐量和伸縮性。Spring WebFlux 是一個異步非阻塞的 Web 框架,所以,它特別適合應用在 IO 密集型的服務中,比如微服務網關這樣的應用中。
pring MVC的表單標簽為Java程序員提供了許多額外的支持。例如數據綁定,允許自動設置數據并從Java對象中檢索數據。
從2.0版本開始,Spring提供了一組全面的數據綁定感知標記,用于在使用JSP和Spring Web MVC時處理表單元素。每個標記都支持其相應HTML標記對應的屬性集,使標記熟悉且直觀易用。標記生成的HTML符合HTML 4.01 / XHTML 1.0 標準。
在本文中我們會瀏覽所有這些表單標簽,并查看每個標簽的使用方式。
表單標記庫被捆綁在spring-webmvc.jar中,庫描述符稱為spring-form.tld。
要使用此庫中的標記,請將以下指令添加到JSP頁面的頂部:
此標記呈現HTML“form”標記,并公開內部標記的綁定路徑以進行綁定。 它將命令對象放在PageContext中,以便內部標記可以訪問命令對象。 此庫中的所有其他標記都是表單標記的嵌套標記。
假設我們有一個名為User的域對象。它是一個JavaBean,具有firstName和lastName等屬性。我們將它用作表單控制器的表單支持對象,它返回form.jsp。如下所示:
firstName和lastName值是從頁面控制器放置在PageContext中的命令對象中檢索的。加載表單時,Spring MVC將對user.getFirstName()和getLastName()(getter方法)進行分類。提交表單時,Spring MVC將調用user.setFirstName()和user.setLastName()方法。 生成的HTML看起來是這樣:
input 標記默認使用綁定值和type='text'呈現HTML 'input'標記,舉個例子:
生成的HTML代碼如下所示:
此標記呈現帶有“checkbox”類型的HTML “input”標記,例如:
生成的代碼如下所示:
此標記呈現多個帶有“checkbox”類型的HTML “input”標記,示例如下:
此標記呈現帶有“radio”類型的HTML “input”標記,典型的使用模式將涉及綁定到同一屬性但具有不同值的多個標記實例:
此標記呈現多個帶有“radio”類型的HTML “input”標記,例如:
此標記使用綁定值呈現帶有“password”類型的HTML “input”標記,如下:
請注意,默認情況下,密碼值不會顯示。如果您確實需要顯示密碼值,請將“showPassword”屬性的值設置為true,如下所示:
此標記呈現HTML“select”元素,它支持數據綁定到所選選項以及使用嵌套選項和標記。示例如下:
選擇一個Skill,則可能HTML代碼如下:
此標記呈現HTML “option”,它根據綁定值設置“selected”,如下:
如果選擇了 “Gryffindor”,則相應的代碼如下:
此標記呈現HTML 'option'標記的列表,它根據綁定值設置“selected”屬性,如下:
實際生成的HTML代碼有可能是這樣:
此標記呈現HTML “textarea”,如下:
此標記使用綁定值呈現類型為“hidden”的HTML“input”標記,如下:
此標記在HTML “span”標記中呈現字段錯誤,它可以訪問控制器中創建的錯誤或由與控制器關聯的任何驗證器創建的錯誤。假設我們希望在提交表單后顯示firstName和lastName字段的所有錯誤消息,有一個名為UserValidator的User類實例的驗證器,如下:
form.jsp 代碼如下:
如果firstName和lastName字段中有一個為空,那么提交后的是HTML是這樣:
如果想顯示給定頁面的整個錯誤列表怎么辦? 下面的示例顯示errors標記還支持一些基本的通配符功能。path=“*”顯示所有錯誤; path=“lastName”顯示與lastName字段關聯的所有錯誤; 僅顯示對象錯誤。下面的示例將在頁面頂部顯示錯誤列表,然后是字段旁邊的特定錯誤:
生成的HTML代碼如下:
從Spring 3開始,Spring表單標記庫允許輸入動態屬性,這意味著可以輸入任何HTML5特定屬性。在Spring 3.1中,表單輸入標記支持輸入“text”以外的type屬性。這旨在允許呈現新的HTML5特定輸入類型,例如“email”,“date”,“range”等。請注意,不需要輸入type='text',因為'text'是默認類型。
文主要分享了對整合jsp的springboot項目打jar包,如何正確的配置maven pom。
1.pom.xml添加spring-boot-maven-plugin配置
如果只是普通的項目打包,上面的配置足夠了,但是帶src/main/webapp的打包,還不行,會發現src/main/webapp的內容都沒有打進jar包
2.pom.xml添加配置resources配置
這個配置可將src/main/webapp打包到jar包中,但是這個jar包還不能讓jsp正常訪問
注:如果沒有配置<targetPath>META-INF/resources</targetPath>,src/main/webapp的內容會保存到BOOT-INF/ 目錄下。經測試,jsp頁面無法正常訪問,需要指定到META-INF/resources才能正常訪問
3.spring-boot-maven-plugin的版本指定為1.4.2.RELEASE
springboot官方推薦的前端模板引擎是thymeleaf,所以對于jsp的支持可能存在兼容性。1.4.2.RELEASE是經過測試出來。具體原因未知,不過確實可用。
如果項目中沒有多個main方法,mainClass可以不配置
4.最終版配置
怎么樣?如果你覺得有用的話,還不快快收藏起來!!!
附:涉及的代碼目錄
gitee:https://gitee.com/jq_di/springcloud-template
*請認真填寫需求信息,我們會在24小時內與您取得聯系。