This Post is under 軟體開發
目的:在前文First Java Spring Boot Web Application Using IntelliJ IDEA Community實作了一個Say Hello的Controller,但其實這是一個RESTful API的Controller,離我們真正想要的MVC軟體架構還有一大段距離。因此本文將進一步實作MVC中的 “View”與”Controller”,以及它們之間的資料傳遞。同樣地,在參考網路資料時,因為開發軟體不斷更新與這些資料在撰寫時的時間落差仍然會讓後繼的開發者踩到一些坑;避開這些坑,也就是本文撰寫的目的。
目標:在”Controller”從資料庫撈資料(偷懶,也就是沒有Model),然後將資料表中的資料傳到 “View”表列呈現如下圖。
Step1:Controller
- 參考這篇,新增一個Controller(@Controller 為宣告)。@GetMapping(“/news/getall”) 為瀏覽器網址列路徑,如上圖所示。
- method getall 回傳的是View的樣板檔名稱,該檔位於src.main.resources.templates 底下。
- method getall 的參數 model,將會傳到View的樣板檔。可在Thymeleaf執行環境中的View讀取。參考這篇 Thymeleaf 輕鬆入門。
- 在 method getall 中使用 jdbc 從資料庫抓取資料,參考資料庫連線設定、IntelliJ 資料庫管理工具介紹、Spring JDBC 的用法 (下) – 執行 SELECT sql。使用 NamedParameterJdbcTemplate 的 queryForList 抓回來的資料表資料型別為 List<Map<String, Object>>,若是在RestController以ResponseEntity 輸出,client端接收到的就是 JSON(連轉換都省了)。但在一般的Controller可以直接設為要傳給 View 的資料,如 model.addAttribute(“news”, news);。
- 初學者注意 @Autowired 的用法。個人理解有點像是產生一個 instance,塞給Controller class的某個屬性。
NewsController.java
import ...(略) @Controller public class NewsController { @Autowired private NamedParameterJdbcTemplate namedParameterJdbcTemplate; @GetMapping("/news/getall") public String getall(Model model) { Map<String, Object> params = new HashMap<>(); List<Map<String, Object>> news = namedParameterJdbcTemplate.queryForList("select * from news", params); model.addAttribute("name", "新聞"); model.addAttribute("news", news); return "news/getall"; } }
Step2:View 或稱 template(樣板)
- 在Controller 的 method getall 回傳的是View的樣板檔名稱,該檔位於src.main.resources.templates 底下。
- 其實它就是一個 html 檔,但可在Thymeleaf執行環境中的View讀取。參考這篇 Thymeleaf 輕鬆入門。Thymeleaf 有點像是 php 等鑲嵌在一般網頁中,由 web server解譯的語法。以下以 th: 前綴的即是Thymeleaf語法,可用來取出從 Controller 傳來的資料,並用基本的迴圈將資料條列出來。
getall.html
<!DOCTYPE html> <html lang="en" xmlns:th="http://www.w3.org/1999/xhtml"> <head> <meta charset="UTF-8"> <title>Title <body> <h1 th:text="${name}"> <table> <tr> <th>ID <th>Title <th>Content </tr> <tr th:each="onenew : ${news}"> <td th:text="${onenew.id}"> <td th:text="${onenew.title}"> <td th:text="${onenew.content}"> </tr> </table> </body> </html>
至此,在Spring的架構下,Controller與View是兩個不同獨立的個體。理想的狀態下,開發網頁前後端的人可以彼此分工合作,寫Controller的人不用管前端網頁設計,而做前端網頁的人也不用管後端怎麼去抓資料。但…,現實往往不盡理想,校長兼撞鐘是非常有可能的,然而MVC架構仍然有助於軟體開發者管理他們的程式,尤其是在系統日趨複雜之後…。