不懂 Servlet 如何用 Kotlin 開發網頁程式?

Vaadin-on-Kotlin DSL

Maggie Kuo
6 min readJun 28, 2022

前面文章提到,Vaadin-on-Kotlin 是基於 Vaadin 延伸的小型框架,提供非網頁開發者專注於 Kotlin code 的開發,即使不懂何謂 Servlet 也能開網頁應用程式。本系列範例改寫自Vaadin on Kotlin 網站,假設讀者並無 JavaEE、Spring 等相關開發經驗,以 Kotlin code 開發 Vaadin 網頁程式為主,不會對Java (Kotlin) 如何開發網頁程式有過多解釋,有興趣了解更多,請參考 Vaadin官網

Karibu-DSL

VoK 使用 Karibu-DSL 封裝了 Vaadin 渲染 View 的方式,Karibu-DSL 是 Vaadin 框架的 Kotlin 擴展/DSL 函式庫,讓開發者以結構化的方式 Create Vaadin UI,讓開發者編寫畫面程式碼時更為易讀易寫。以下分別為不使用 DSL 和 使用 DSL 方式編寫畫面程式,讀者可比較差異。

VerticalLayout
\---- FormLayout
|----- TextField
\----- TextField

以下將介紹如何顯示及輸入資料。

寫一個自己的首頁

延續上一篇文章所下載的專案。開新檔案,名為 MainView.kt

MainView.kt 繼承 KComposite,實作 ui() 方法並取名為 root 是官方推薦的方式,整個畫面由 ui{} 區段包起來,verticalLayout 為垂直排列。content、h1、h2…都是 Karibu-DSL 一員。

相信寫過 TornadoFX、KTOR HTML DSL、Flutter、Android Jetpack Compose 等框架的開發者對階層式的頁面編寫模式或許不陌生,僅管背後運作機制不盡相同。

同樣的程式,若不使用 Karibu-DSL 寫起來會像這樣:

看似差不多,但畫面一旦更複雜些,可想而知其繁雜且不若 DSL 階層式容易除錯,更不用說還要自訂css了。

第3行 @Route("") 定義這個 View 為首頁,接受 http://localhost:8080/ 請求,在此之前,專案裡已在 WelcomeView.kt 定義了首頁,為避免衝突,請開啟 WelcomeView.kt 修改 Route 為 old :

WelcomeView 改為接收 http://localhost:8080/old 發送的請求。

在 Terminal 視窗執行 ./gradlew build web:appRun,瀏覽器開啟 http://localhost:8080 將會出現下列畫面 :

目前畫面看起來還很陽春,接下來將會逐步改善。首先開新檔名為 MainLayout.kt,此為整個畫面的佈局,日後若要加入選單或修改畫面樣式,皆可藉由修改 MainLayout 達成。

畫面輸入

1. 建立學生資料

開新檔 Student.k,新增學生資料 Data class

第 8–15 行,學生基本資料欄位。
第 16 行,實作 KEntity 實例化 Student 類,KEntity 後所帶的 <Long> 定義 Student 實例類的 id 型態。

KEntity 是 vok-orm 套件裡關於資料表的 interface,上述定義了學生資料表的實體類(entity class) Student。

2. 新增學生資料畫面

開啟新檔 CreateStudentView.kt :

第 4 行,Route 除了指定此畫面路徑外,後面多了個參數 layout,即是先前建立的主要佈局 MainLayout.kt。
第 6 行,使用 beanValidationBinder 方法,綁定實體類 Student。
第 10-26 行,因應欄位型態輸入需求,使用不同 UI Component 供使用者輸入。
第 11 行,將游標停留在輸入姓名欄位。
第 12 行,將畫面輸入欄位和實例類欄位進行綁定。
第 17 行,性別欄為 comboBox,在這裡使用 enum 填充選項,enum 定義在 Student.kt 檔第 20 行。

到目前為止,執行畫面如下

但按下Save鍵尚無反應

儲存資料

3. 建立資料表

關於 DB 的依賴設定,在這個範例裡使用 H2 database、Flyway Migration。H2 資料庫是個記憶體資料庫,其優劣不在此一一贅述,主要用於開發和測試,也就是說,資料不會存在磁碟上,一旦程式停止運作,所儲存的資料隨即消失。Flyway 用於資料庫遷移 (migration),簡言之,通常我們開發系統時,隨著應用程式版本異動,資料庫可能隨之改變,不同版本程式的資料結構不盡相同,Flyway 即是用於資料庫的版本控制。

請在 /web/src/main/resources/db/migration/ 路徑下建立一個 create table 的 SQL DDL script,命名為 V01__CreateStudent.sql,檔名格式 : V[編號]__[檔名].sql,若有多個 migration 檔,將按照版本(編號)依序執行,且只執行一次。

因此專案使用的是H2 database,Server 一旦停止運作資料庫就消失了,每次重新執行程式,所有migrations 都會被依序一一執行

4. 儲存

定義好資料表後,寫好相應程式,資料即可實際被儲存,請開啟 CreateStudentView.kt,加入下列程式碼 :

第 2 行,增加 onLeftClick listener。
第 4 行,writeBeanIfValid() 方法先檢查 student 是否可儲存再回傳boolean 值。
第 5 行,Student 實體類因實作了 KEntity,因此帶有 save()方法。

顯示資料

透過顯示單筆資料頁顯示,以確定資料是否真被儲存了 。開新檔案 StudentView.kt。

第 14–22 行,產生欲顯示資料欄位,給定預設值為空字串。
第 26–31 行,實作 interface HasUrlParameter setParameter() 方法,用來解析 url 帶的參數。此例中,url http://localhost:8080/student/1,studentID 即為 1。
第 26 行,接收參數 studentId
第 27 行,使用 getById() 方法查詢 id=1 的學生資料
第 28–30 行,分別將取得資料寫到類別屬性,因繪製畫面時已綁定 ui{} 區塊內的 text()欄位,故類別屬性異動後,畫面隨之被更新。

自動導航畫面

最後,在CreateStudentView.kt save()方法最後加上一行,傳遞參數 student.id 並跳轉到 StudentView 頁。

執行結果

--

--