到目前為止,我們都在用Thymeleaf模板定義閱讀列表應用程序的視圖。除了Thymeleaf,Spring Boot還支持Freemarker、Velocity和基於Groovy的模板。無論選擇哪種模板,你要做的就是添加合適的起步依賴,在Classpath根部的templates/目錄裡編寫模板。自動配置會處理剩下的事情。
Grails項目也提供GSP的自動配置。如果你想在Spring Boot應用程序裡使用GSP,必須向項目裡添加Spring Boot的GSP庫:
compile("org.grails:grails-gsp-spring-boot:1.0.0")
和Spring Boot提供的其他視圖模板一樣,庫放在Classpath裡就會觸發自動配置,設置所需的視圖解析器,以便在Spring MVC的視圖層裡使用GSP。
剩下的就是為應用程序編寫GSP模板了。在閱讀列表應用程序中,我們要把Thymeleaf的readingList.html文件用GSP的形式重寫,放在readingList.gsp文件(位於src/main/resources/ templates)裡。代碼清單6-5就是新的GSP模板的代碼。
代碼清單6-5 GSP編寫的閱讀列表應用程序主視圖
<!DOCTYPE html>
<html>
<head>
<title>Reading List</title>
<link rel="stylesheet" href="/style.css"></link>
</head>
<body>
<h2>Your Reading List</h2>
<g:if test="${books}">
<g:each in="${books}" var="book"> ←---羅列圖書
<dl>
<dt>
${book.title} by ${book.author}
(ISBN: ${book.isbn}")
</dt>
<dd>
<g:if test="book.description">
${book.description}
</g:if>
<g:else>
No description available
</g:else>
</dd>
</dl>
</g:each>
</g:if>
<g:else>
<p>You have no books in your book list</p>
</g:else>
<hr/>
<h3>Add a book</h3>
<form method="POST"> ←---圖書表單
<label for="title">Title:</label>
<input type="text" name="title"
/><br/>
<label for="author">Author:</label>
<input type="text" name="author"
/><br/>
<label for="isbn">ISBN:</label>
<input type="text" name="isbn"
/><br/>
<label for="description">Description:</label><br/>
<textarea name="description" rows="5" cols="80">
${book?.description}
</textarea>
<input type="hidden" name="${_csrf.parameterName}" ←---CSRF令牌
/>
<input type="submit" />
</form>
</body>
</html>
如你所見,GSP模板中使用了表達式語言引用(用${}
包圍的部分)以及GSP標籤庫(例如<g:if>
和<g:each>
)。這並不是Thymeleaf那樣的純HTML。但如果習慣用JSP,你會很熟悉這種方式,而且會覺得這是一個不錯的選擇。
代碼裡的絕大部分內容和第2章、第3章的Thymeleaf模板類似,映射GSP模板上的元素。但是有一點要注意,你必須要放一個隱藏域,其中包含CSRF(Cross-Site Request Forgery)令牌。Spring Security在提交POST
請求時要求帶有這個令牌,Thymeleaf在呈現HTML時會自動包含這個令牌,但在GSP裡你必須在隱藏域顯式地包含它。
圖6-1是GSP模板的顯示效果,其中添加了一些圖書。
圖 6-1 使用了GSP模板的閱讀列表
雖然GORM和GSP這樣的Grails特性很吸引人,讓Spring Boot應用程序更簡單,但你在這裡還不能真正體驗Grails。讓我們再往Spring Boot的花生醬裡放一點Grails巧克力。現在讓我們來看看Grails 3如何將兩者合二為一,帶來完整的Spring Boot和Grails開發體驗。