SpringBoot實作Java高并發秒殺系統之Web層開發(三)
接着上一篇文章:SpringBoot實作Java高并發之Service層開發,今天我們開始講SpringBoot實作Java高并發秒殺系統之Web層開發。
Web層即Controller層,當然我們所說的都是在基于Spring架構的系統上而言的,傳統的SSH項目中,與頁面進行互動的是struts架構,但struts架構很繁瑣,後來就被SpringMVC給頂替了,SpringMVC架構在與頁面的互動上提供了更加便捷的方式,MVC的設計模式也是目前非常流行的一種設計模式。這次我們針對秒殺系統講解一下秒殺系統需要和頁面互動的操作和資料都涉及哪些?
本項目的源碼請參看:springboot-seckill 如果覺得不錯可以star一下哦(#^.^#)
本項目一共分為四個子產品來講解,具體的開發教程請看我的部落格文章:
- SpringBoot實作Java高并發秒殺系統之DAO層開發(一)
- SpringBoot實作Java高并發秒殺系統之Service層開發(二)
- SpringBoot實作Java高并發秒殺系統之并發優化(四)
首先如果你對SpringBoot項目還是不清楚的話,我依然推薦你看一下我的這個項目:優雅的入門SpringBoot2.x,整合Mybatis實作CRUD
前端互動流程設計
編寫Controller就是要搞清楚:1.頁面需要什麼資料?2.頁面将傳回給Controller什麼資料?3.Controller應該傳回給頁面什麼資料?
帶着這些問題我們看一下秒殺詳情頁流程邏輯(不再講基本的
findById
和
findAll()
方法):
因為整個秒殺系統中最核心的業務就是:1.減庫存;2.查詢訂單明細。我們看一下Controller層的源碼:
|
下面我以問答的形式講解一下Controller層方法的定義:
1.
@ResponseBody
注解分别有什麼作用?
@RestController
-
注解辨別的方法,Spring會将此方法return的資料轉換成JSON格式且不會被Spring視圖解析器所掃描到,也就是此方法永不可能傳回一個視圖頁面。且這個注解隻能用在方法體上,不能用在類上。@ResponseBody
-
注解辨別的類,Spring會将其下的所有方法return的資料都轉換成JSON格式且不會被Spring視圖解析器掃描到,也就是此類下面的所有方法都不可能傳回一個視圖頁面。且這個注解隻能用在類上,不能用在方法體上。@RestController
2.中
@RequestMapping
的文法是什麼?
{xx}
注解的用處是什麼?
@PathVariable
Spring架構很早就支援開發REST資源。也是就是現在我們定義的RESTful URL,在Spring架構上支援的尤為完美,我們可以在Controller中定義這樣一個URL映射位址:
/{id}/detail
,他是合理的RESTful URL定義方式。
這種URL的特點:URL位址由動态的資料拼接組成的,而不是将所有的資源全部映射到一個路徑下,比如:
/article/detail
。
這種URL結構的優勢:我們能很容易從URL位址上判斷出該位址所展示的頁面是什麼?比如:
/1/detail
就可能表示ID為1的文章的詳情頁,看起來設計的很清晰。
這種URL如何進行互動:我們定義了
/{id}/detail
這樣一個URL映射位址,其對應的映射方法上就應該添加
@PathVariable
注解辨別,如:
@PathVariable("id") Long id
Spring就能裝配前端傳遞的URL中指定位置的資料并指派給
id
這個參數。比如前端調用後端接口:
localhost:8080/seckill/1/detail
,後端存在一個映射方法:
@RequestMapping("/{id}/detail")
,這樣就能剛好比對上這個URL映射位址。
是以我們看一下秒殺系統的RESTful URL設計:
3.為什麼要單獨寫一個接口用來擷取目前系統時間?
由于我們開發的系統肯定不是給自己用的,我們的使用者可能處于不同的時區,他們的目前系統時間也是不同的,是以我們寫一個通用的時間規範:就是目前伺服器的時間。
4.SeckillResult是什麼?
在前面我們将Service層系統開發的時候就手動建立了很多類來封裝一些通用的結果資訊。而對于Controller層也會傳回很多結果資料,比如傳入的URL中id值為null,那麼就沒必要繼續向下請求,而是直接給頁面傳回false資訊。
于是我們建立:
SeckillResult.java
|
泛型
T
表示可以代表不同類型的對象。這是泛型類應用很廣泛的一個特性,我們調用SeckillResult類,将其中的T用什麼替換那麼T就表示這個替換的對象類型。
頁面設計
用了哪些技術?
- HTML頁面,用Bootstrap繪制。
- Thymeleaf模闆引擎渲染HTML頁面,使得HTML頁面擁有類似JSP頁面一樣功能。
- JS方面使用原生的JQuery。
我們來看一下前端的頁面設計:
本項目使用Cookie存儲使用者手機号的方式模拟使用者登入功能,實際上沒有與後端互動的操作。如果使用者沒有登入就打開了商品詳情頁會直接彈出一個手機号登入框提醒使用者登入,且沒有登入時無法關閉登入框的。
具體的源碼請看:GitHub
思考
在從JSP頁面轉換到HTML頁面的時候我常會遇到這麼一個問題:前端如何取出來後端查詢到的資料?
在之前我們寫的JSP頁面中,可以通過将後端查詢到的資料放進request,session域對象中,JSP頁面可以直接調用Java中域對象的資料,甚至可以通過EL表達式(
${}
)來直接擷取參數,但是這種方法有一個弊端:Controller必須是傳回一個視圖,這樣才能在此視圖中擷取存進域對象中的資料。
而我們現在都開始用HTML頁面,也無法從域對象中取出資料該怎麼辦呢?我這裡提供兩個思路:
- 1.像本項目中一樣,前端使用Thymeleaf模闆引擎渲染頁面,那麼Thymeleaf内置很多方法如同JSP頁面的EL表達式。Thymeleaf在HTML中取出域對象資料使用:
;在JS中取出域對象資料:<span th:text="${xx}">
(當然都必須是在HTML頁面中,在外部JS檔案中是得不到資料的)。var v = [[${xx}]]
- 2.使用原生js提供的
對象,我們先看一下URL的組成結構:location
詳細介紹請看:博文
舉個栗子
|