<!DOCTYPEhtml SYSTEM"http://www.thymeleaf.org/dtd/xhtml1-strict-thymeleaf-3.dtd">
<htmlxmlns="http://www.w3.org/1999/xhtml" xmlns:th="http://www.thymeleaf.org">javascript
或者使用下面的文檔聲明也能夠,這樣就沒有Thymeleaf對文檔的校驗功能了,由於沒有引入對應的DTD,並且IDE可能會提示錯誤,可是不影響對模板的解析。
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML1.0 Strict//EN""http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">css
1.簡單的表達式:html
變量表達式:$ {…}java
選擇變量表達式:* {…}程序員
國際化表達式:# {…}web
連接的網址的表達式:@{...}spring
'User is of type ' + (${user.isAdmin()} ? 'Administrator' : (${user.type} ?: 'Unknown'))
模板中獲取變量值的方式,使用${},針對不一樣類型數據,用法以下express
/*
* Access to properties using the point (.). Equivalent to calling property getters.
*/
{..}$personfathername
經過.來獲取,至關於調用getter()方法
/*
* Access to properties can also be made by using brackets ([]) and writing
* the name of the property as a variable or between single quotes.
*/
{['father']['name']}$person
使用[]等同與. []能在某些場合完成.不能完成的功能
/*
* If the object is a map, both dot and bracket syntax will be equivalent to
* executing a call on its get(...) method.
*/
{.}$countriesByCodeES
{['Stephen Zucchini'].}$personsByNameage
獲取map集合數據
/*
* Indexed access to arrays or collections is also performed with brackets,
* writing the index without quotes.
*/
{[0].}$personsArrayname
獲取數組
/*
* Methods can be called, even with arguments.
*/
{.createCompleteName()}$person
{.createCompleteNameWithSeparator('-')}$person
調用對象的方法,即使包含參數
Expression Utility Objects在模版中使用內置對象bootstrap
內置對象,提供了不少方便的功能,日期格式化,字符串處理,數字格式化等
#dates, formatting,component extraction,etc
#calendars
#numbers,formatting numeric objects.
#strings, contains,startsWith,prepending/appending,etc
#bools
#arrays
#lists
#sets
#maps
#aggregates, creating aggregates on arrays or collections
#messages, equal to using #{}
#ids, deal with id attributes, eg: as a result of an iteration
#ctx等等,還有不少!數組
例子:
格式化
th:text="${#calendars.format(today,'ddMMMM yyyy')}"
具體對應使用辦法詳情見:http://www.thymeleaf.org/doc/tutorials/2.1/usingthymeleaf.html#appendix-b-expression-utility-objects
Variable expressions notonly can be written in ${...}
expressions,but also in *{...}
ones.
變量表達式不只能夠用$ {…}表達式編寫,也能夠用在* {…}中。
There is an importantdifference, though: the asterisk syntax evaluates expressions on selectedobjects rather than on the whole context variables map. This is: as long asthere is no selected object, the dollar and the asterisk syntaxes do exactlythe same.
有一個重要的區別,雖然:星號句法表達式的值在選定的對象而不是整個上下文變量圖。這就是:只要沒有選定對象,美圓和星號語法徹底同樣
And what is that objectselection thing? A th:object
attribute.Let’s use it in our user profile (userprofile.html
)page:
<div th:object="${session.user}">
<p><span th:text="*{firstName}"></span></p> Name: Sebastian.
<p><span th:text="*{lastName}"></span></p> Surname: Pepper.
<p><span th:text="*{nationality}"></span></p> Nationality: Saturn.
</div>
Which is exactlyequivalent to:
<div>
<p><span th:text="${session.user.firstName}"></span></p> Name: Sebastian.
<p><span th:text="${session.user.lastName}"></span></p> Surname: Pepper.
<p><span th:text="${session.user.nationality}"></span></p> Nationality: Saturn.
</div>
Of course, dollar andasterisk syntax can be mixed:
<div th:object="${session.user}">
<p><span th:text="*{firstName}"></span></p> Name: Sebastian.
<p><span th:text="${session.user.lastName}"></span></p> Surname: Pepper.
<p><span th:text="*{nationality}"></span></p> Nationality: Saturn.
</div>
When an object selectionis in place, the selected object will be also available to dollar expressionsas the #object
expressionvariable:
<div th:object="${session.user}">
<p><span th:text="${#object.firstName}"></span></p> Name: Sebastian.
<p><span th:text="${session.user.lastName}"></span></p> Surname: Pepper.
<p><span th:text="*{nationality}"></span></p> Nationality: Saturn.
</div>
As said, if no objectselection has been performed, dollar and asterisk syntaxes are exactlyequivalent.
<div>
<p><span th:text="*{session.user.name}"></span></p> Name: Sebastian.
<p><span th:text="*{session.user.surname}"></span></p> Surname: Pepper.
<p><span th:text="*{session.user.nationality}"></span></p> Nationality: Saturn.
</div>
Let’s use this newsyntax. Meet the th:href
attribute:
<!-- Will produce 'http://localhost:8080/gtvg/order/details?orderId=3' (plus rewriting) -->
<a href="details.html"
th:href="@{http://localhost:8080/gtvg/order/details(orderId=${o.id})}"></a>view
<!-- Will produce '/gtvg/order/details?orderId=3' (plus rewriting) -->
<a href="details.html"th:href="@{/order/details(orderId=${o.id})}"></a>view
<!-- Will produce '/gtvg/order/3/details' (plus rewriting) -->
<a href="details.html"th:href="@{/order/{orderId}/details(orderId=${o.id})}"></a>view
· If several parameters are needed, these will be separatedby commas 連接多參數用逗號分割like@{/order/process(execId=${execId},execType='FAST')}
· The th:href
tag allowed us to (optionally) have a work ing static href
attribute in our template, so that our template linksremained navigable by a browser when opened directly for prototyping purposes
href標記容許咱們(可選的)有一個工做的靜態href屬性在咱們的模板,可打開原型
<a th:href="@{${url}(orderId=${o.id})}"></a>view
<a th:href="@{'/details/'+${user.login}(orderId=${o.id})}"></a>view
Server root relative URLs服務根路徑
An additional syntax can be used tocreate server-root-relative (instead of context-root-relative) URLs in order tolink to different contexts in the same server. These URLs will be specifiedlike @{~/path/to/something}
Text literals
Text literals are just character stringsspecified between single quotes. They can include any character, but you shouldescape any single quotes inside them as \'.
直接寫做th:text="working web application"是錯誤的,必須加上單引號
若是字符串中沒有空格,則能夠去掉單引號
<p>
Now you arelooking at a <span th:text="'working webapplication'">template file</span>.
</p>
Number literals
Numeric literals look exactly like whatthey are: numbers.
數字直接寫便可
<p>The year is<span th:text="2013">1492</span>.</p>
<p>In twoyears, it will be <span th:text="2013 + 2">1494</span>.</p>
Boolean literals
The boolean literals are true and false. For example:
<div th:if="${user.isAdmin()}== false"> ...
Note that in the above example, the == false is written outside the braces, and thusit is Thymeleaf itself who takes care of it. If it were written inside thebraces, it would be the responsibility of the OGNL/SpringEL engines:
以上判斷boolean類型時,==false是寫在${}外面的,這是thymeleaf的語法;若是false寫在${}裏面則爲el/ognl表達式的語法
<div th:if="${user.isAdmin()== false}"> ...
等同於${! }
<div th:if="${!user.isAdmin()}"> ...
The null literal
The null literal can be also used:
<div th:if="${variable.something}== null"> ...
These tokens allow a little bit ofsimplification in Standard Expressions. They work exactly the same as textliterals ('...'
), but they only allow letters (A-Z
and a-z
), numbers (0-9
), brackets ([
and ]
), dots (.
), hyphens (-
) andunderscores (_
). So no whitespaces, no commas, etc.
容許在標準表達式中的一點點簡化。徹底同樣的文本文字('...'
),,只容許字母(A-Z和a-z)、數字(0-9),括號([ and ]),點(。),連字符(-)和下劃線(_)。因此沒有空格,沒有逗號,等等。
<div th:class="content"></div>...
instead of: 若是不包括空格
<div th:class="'content'"></div>...
Texts, no matter whetherthey are literals or the result of evaluating variable or message expressions,can be easily appended using the +
operator:
用+追加文本數據
th:text="'The name of the user is ' + ${user.name}"
下面4.7是一個簡單的替換規則,無需+追加,用||則能夠輸出
Literal substitutionsallow the easy formatting of strings containing values from variables withoutthe need to append literals with '...'+ '...'
.
文字替換,容許含值的變量不須要追加文本字符串的一種簡單的格式
These substitutions mustbe surrounded by vertical bars (|
),like:
<span th:text="|Welcome to our application, ${user.name}!|">
Which is actuallyequivalent to:
<span th:text="'Welcome to our application, ' + ${user.name} + '!'">
Literal substitutions canbe combined with other types of expressions:
追加和替換混合使用
<span th:text="${onevar} + '' + |${twovar}, ${threevar}|">
Note: onlyvariable expressions (${...}
)are allowed inside |...|
literalsubstitutions. No other literals ('...'
),boolean/numeric tokens, conditional expressions etc. are.
Some arithmeticoperations are also available: +
, -
, *
, /
and %
.
prodStat.count
除以
2
求餘是否爲
0
,並賦值給
isEven
變量
th:with="isEven=(${prodStat.count} % 2 == 0)"
Note that these operatorscan also be applied inside OGNL variable expressions themselves (and in thatcase will be executed by OGNL instead of the Thymeleaf Standard Expressionengine):
th:with="isEven=${prodStat.count % 2 == 0}"
Note that textual aliasesexist for some of these operators: div
(/
), mod
(%
).
<p th:with="isEven=(888 + 2)">
<span th:text="${isEven}"></span>
</p> 頁面輸出:890
局部變量,th:with能定義局部變量:
<div th:with="firstPer=${persons[0]}">
<p>
The name of the first person is <span th:text="${firstPer.name}">Julius Caesar</span>.
</p>
</div>
Values in expressions canbe compared with the >
, <
, >=
and <=
symbols,as usual, and also the ==
and !=
operatorscan be used to check equality (or the lack of it). Note that XML establishesthat the <
and >
symbolsshould not be used in attribute values, and so they should be substituted by <
and >
.
注意,通常頁面文件儘可能避免使用<和>,應使用<和>來代替
>th:if="${prodStat.count} 1"
th:text="'Execution mode is ' + ( (${execMode} == 'dev')? 'Development' : 'Production')"
Note that textual aliasesexist for some of these operators: gt
(>
), lt
(<
), ge
(>=
), le
(<=
), not
(!
).Also eq
(==
), neq
/ne
(!=
).
知足條件取前者,不知足取後者
<tr th:class="${row.even}? 'even' : 'odd'">
...
</tr>
條件表達式也能夠嵌套使用圓括號:
<tr th:class="${row.even}? (${row.first}? 'first' : 'even') : 'odd'">
...
</tr>
能夠省略條件不知足的表達式,若是不知足,默認返回null
<div th:class="100!=100 ? 'panel panel-warningpanel-heading'">
這裏什麼樣式也不顯示
</div>
第一個表達式的結果只要不爲null,則取第一個表達式的值
A ?: B
若是A不爲空,則取A的值,反之取B
<div th:object="${session.user}">
...
<p><span th:text="*{age}?: '(no age specified)'"></span></p> Age: 27.
</div>
等同於
<div th:object="${session.user}">
...
<p><span th:text="*{age != null}? *{age} : '(no age specified)'"></span></p> Age: 27.
</div>
設置action屬性
<form action="subscribe.html"th:attr="action=@{/subscribe}">
設置value屬性
<input type="submit" value="Subscribe me!"th:attr="value=#{subscribe.submit}"/>
一次設置多個屬性
<img src="../../images/gtvglogo.png"
th:attr="src=@{/images/gtvglogo.png},title=#{logo},alt=#{logo}"/>
以上方法指定屬性賦值能夠是很是實用的,但它不是最優雅的方式建立模板,thymeleaf有不少屬性可使用:
<img src="../../images/gtvglogo.png"
th:src="@{/images/gtvglogo.png}"th:title="#{logo}"th:alt="#{logo}"/>
th:abbr |
th:accept |
th:accept-charset |
th:accesskey |
th:action |
th:align |
th:alt |
th:archive |
th:audio |
th:autocomplete |
th:axis |
th:background |
th:bgcolor |
th:border |
th:cellpadding |
th:cellspacing |
th:challenge |
th:charset |
th:cite |
th:class |
th:classid |
th:codebase |
th:codetype |
th:cols |
th:colspan |
th:compact |
th:content |
th:contenteditable |
th:contextmenu |
th:data |
th:datetime |
th:dir |
th:draggable |
th:dropzone |
th:enctype |
th:for |
th:form |
th:formaction |
th:formenctype |
th:formmethod |
th:formtarget |
th:frame |
th:frameborder |
th:headers |
th:height |
th:high |
th:href |
th:hreflang |
th:hspace |
th:http-equiv |
th:icon |
th:id |
th:keytype |
th:kind |
th:label |
th:lang |
th:list |
th:longdesc |
th:low |
th:manifest |
th:marginheight |
th:marginwidth |
th:max |
th:maxlength |
th:media |
th:method |
th:min |
th:name |
th:optimum |
th:pattern |
th:placeholder |
th:poster |
th:preload |
th:radiogroup |
th:rel |
th:rev |
th:rows |
th:rowspan |
th:rules |
th:sandbox |
th:scheme |
th:scope |
th:scrolling |
th:size |
th:sizes |
th:span |
th:spellcheck |
th:src |
th:srclang |
th:standby |
th:start |
th:step |
th:style |
th:summary |
th:tabindex |
th:target |
th:title |
th:type |
th:usemap |
th:value |
th:valuetype |
th:vspace |
th:width |
th:wrap |
th:xmlbase |
th:xmllang |
th:xmlspace |
th:attrappend th:attrprepend |
· th:alt-title will set alt and title.
· th:lang-xmllang will set lang and xml:lang.
th:alt-title、th:lang-xmllang爲thymeleaf兩個特別的屬性,它能夠同時設置兩個屬性
接上面的<img>例子,也能夠寫成
<img src="../../images/gtvglogo.png"
th:src="@{/images/gtvglogo.png}"th:alt-title="#{logo}"/>
th:attrappend
後面追加
th:attrprepend
前面追加
例如:cssStyle=warning
<input type="button"value="Do it!"class="btn"th:attrappend="class=${'' + cssStyle}"/>
即爲
<input type="button"value="Do it!"class="btn warning"/>
XHTML/HTML5中,有一些特殊的屬性,要麼沒有值,要麼爲某個固定的值
checked
selected
disabled
mutiple
readonly
若是計算結果爲true,則使用它的固定值,不然不處理。
<inputtype="checkbox" name="active" th:checked="true"/>
都包含如下屬性
th:async |
th:autofocus |
th:autoplay |
th:checked |
th:controls |
th:declare |
th:default |
th:defer |
th:disabled |
th:formnovalidate |
th:hidden |
th:ismap |
th:loop |
th:multiple |
th:novalidate |
th:nowrap |
th:open |
th:pubdate |
th:readonly |
th:required |
th:reversed |
th:scoped |
th:seamless |
th:selected |
<table>
<tr>
<th></th> NAME
<th></th> PRICE
<th></th> IN STOCK
</tr>
<tr th:each="prod : ${prods}">
<td th:text="${prod.name}"></td> Onions
<td th:text="${prod.price}"></td> 2.41
<td th:text="${prod.inStock}? #{true} : #{false}"></td> yes
</tr>
</table>
使用迭代時,可跟蹤迭代的狀態,包括如下數據:
· The current iteration index, starting with 0.This is the index property.
當前迭代索引,從0開始。這是索引屬性。
· The current iteration index, starting with 1.This is the count property.
當前迭代索引,從1開始。這是計數屬性。
· The total amount of elements in the iterated variable.This is the size property.
迭代變量中的元素的總量。這是大小屬性。
· The iter variable for each iteration.This is the current property.
每一個迭代iter變量。這是當前屬性
· Whether the current iteration is even or odd. These arethe even/odd boolean properties.
當前的迭代是不是偶數仍是奇數。這些都是偶數/奇數的布爾屬性
· Whether the current iteration is the first one. This isthe first boolean property.
是否當前的迭代是第一個。這是第一個布爾屬性
· Whether the current iteration is the last one. This isthe last boolean property.
是否當前的迭代是最後一個。這是最後一個布爾屬性
在th:each中,在iter variable變量後面,定義一個status variable,經過該變量來獲取遍歷過程當中的狀態
<tr th:each="prod,iterStat : ${prods}"th:class="${iterStat.odd}? 'odd'">
若是沒有顯式設置一個狀態變量,thymeleaf會自動爲咱們提供一個來使用,經過在iter variable後面添加後綴Stat來使用。
<tr th:each="prod: ${prods}"th:class="${prodStat.odd}? 'odd'">
當th:if條件成立時,該標籤中其它th:*標籤纔會發揮做用,若是條件不成立,則th:*不會執行
<a href="comments.html"
th:href="@{/product/comments(prodId=${prod.id})}"
th:if="${not #lists.isEmpty(prod.comments)}"></a>view
另外,還能夠用th:unless,進行條件控制。若是條件爲真,則th:*不會執行。
<a href="comments.html"
th:href="@{/comments(prodId=${prod.id})}"
th:unless="${#lists.isEmpty(prod.comments)}"></a>view
<div th:switch="${user.role}">
<p th:case="'admin'"></p> User is an administrator
<p th:case="#{roles.manager}"></p> User is a manager
<p th:case="*"></p> User is some other thing
</div>
th:case="*"
: 默認選項
th:fragment
th:include
用法:
在某個標籤中使用th:fragment屬性定義一個變量名,而後在其餘模板中經過th:include,便可引入。
we define a /WEB-INF/templates/footer.html
file containing this code, byusing the th:fragment
attribute.
在footer.html中定一個名稱叫copy
<!DOCTYPE html SYSTEM "http://www.thymeleaf.org/dtd/xhtml1-strict-thymeleaf-4.dtd">
<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:th="http://www.thymeleaf.org">
<body>
<div th:fragment="copy">
© 2011 The Good Thymes Virtual Grocery
</div>
</body>
</html>
usingone of theth:include
or th:replace
attributes:
從文件名稱爲footer的模板中引入名稱爲copy的fragment
<body>
<div th:include="footer :: copy"></div>
</body>
th:include中一樣能夠嵌套使用表達式
<div th:include="footer :: (${user.isAdmin}? #{footer.admin} : #{footer.normaluser})"></div>
th:include
引入fragment中定義的內容
th:substituteby / th:replace
引入fragment所在標籤和內容,並替換當前的標籤
<footer th:fragment="copy">
© 2011 The Good Thymes Virtual Grocery
</footer>
用th:include和th:replace引用
<body>
<div th:include="footer :: copy"></div>
<div th:replace="footer :: copy"></div>
</body>
編譯後,你會發現th:repalce會將內容引入,並替換掉標籤:
<body>
<div>
© 2011 The Good Thymes Virtual Grocery
</div>
<footer>
© 2011 The Good Thymes Virtual Grocery
</footer>
</body>
好處:簡化書寫
弊端:以prototype呈現(靜態地打開網頁),將原樣顯示
用法,在標籤上定義th:inline="text"
該標籤中任意地方均可以使用內聯樣式獲取數據
<p><span th:text="${session.user.name}"></span></p>Hello, Sebastian!
th:inline
<p th:inline="text"></p>Hello, [[${session.user.name}]]!
在標籤上定義th:inline="text",該標籤內部任意地方均可以使用內聯樣式獲取數據
parent tag中定義
<body th:inline="text">
...
<p>hello:[[${session.user.name}]]</p>
...
<body>
<script th:inline="javascript">
<![CDATA[*//*
var username = /*[[${session.user.name}]]*/ 'Sebastian';
/*]]>*/
</script>
thymeleaf將自動對user對象進行轉換,並且轉換爲javascript中的user對象
1.all:刪除包含標籤和全部的孩子。
2.body:不包含標記刪除,但刪除其全部的孩子。
3.tag:包含標記的刪除,但不刪除它的孩子。
4.all-but-first:刪除全部包含標籤的孩子,除了第一個。
5.none:什麼也不作。這個值是有用的動態評估。
<tr class="odd" th:remove="all">
something-------
</tr>
th:remove屬性能夠採起任何Thymeleaf標準表達式,只要容許它返回一個字符串值(all, tag, body, all-but-first or none)。
這意味着刪除多是有條件的:
<a href="/something" th:remove="${condition}? tag : none">Link text not to be removed</a>
th:remove
把null
等同於 none
,因此下面和上面的實際上是同樣的
<a href="/something" th:remove="${condition}? tag">Link text not to be removed</a>
所以,若是${condition}
is 是false,將返回null,所以沒有刪除會被執行。
th:remove 爲了靜態顯示時提供充分的數據,可是在模板被解析後,又不須要這些模擬的數據,須要將其刪除
可選屬性:
th:remove="all", 刪除全部
th:remove="all-but-first",刪除全部,但保留第一個
th:remove="body", 刪除內容,但保留標籤
th:remove="tag", 刪除標籤,但保留內容
在Java世界的MVC框架裏,使用的視圖技術很多,最基本的是JSP,還有知名的FreeMarker和Velocity等模板引擎。Thymeleaf也是一款優秀的模板引擎,它在HTML5/XHTML的視圖層表現的很好,也能在離線狀況下處理任何XML文件。它是徹底能夠替代JSP+JSTL的。
下面是來自於Thymeleaf官方的Q&A:
Q: 和FreeMarker,Velocity相比,Thymeleaf表現得怎樣呢?
A:FreeMarker和Velocity都是軟件領域傑出的做品,但它們在解決模板問題上的處理哲學和Thymeleaf不同。
Thymeleaf強調的是天然模板,也就是容許模板做爲產品原型使用(筆者注:由於其後綴名就是.html,能夠直接在瀏覽器打開),而FreeMarker和Velocity不行。而且Thymeleaf的語法更簡潔、更和目前Web開發的趨勢相一致。其次,從架構的角度看,FreeMarker和Velocity更像個文本處理器,因此它們可以處理不少類型的內容,而Thymeleaf是基於XML的,只能處理XML格式的數據。所以這樣看,FreeMarker和Velocity更通用些,但偏偏如此,Thymeleaf更能利用XML的特性,尤爲是在Web應用中。
視圖控制層代碼demo以下:
1. @Controller
2. @RequestMapping("/")
3. public class MessageController {
4. private final MessageRepository messageRepository;
5.
6. @Autowired
7. public MessageController(MessageRepository messageRepository) {
8. this.messageRepository = messageRepository;
9. }
10.
11. @RequestMapping
12. public ModelAndView list() {
13. Iterable<Message> messages = this.messageRepository.findAll();
14. return new ModelAndView("messages/list", "messages", messages);
15. }
16.
17. @RequestMapping("{id}")
18. public ModelAndView view(@PathVariable("id") Message message) {
19. return new ModelAndView("messages/view", "message", message);
20. }
21.
22. @RequestMapping(params = "form", method = RequestMethod.GET)
23. public String createForm(@ModelAttribute Message message) {
24. return "messages/form";
25. }
26.
27. @RequestMapping(method = RequestMethod.POST)
28. public ModelAndView create(@Valid Message message, BindingResult result,
29. RedirectAttributes redirect) {
30. if (result.hasErrors()) {
31. return new ModelAndView("messages/form", "formErrors", result.getAllErrors());
32. }
33. message = this.messageRepository.save(message);
34. redirect.addFlashAttribute("globalMessage", "Successfully created a new message");
35. return new ModelAndView("redirect:/{message.id}", "message.id", message.getId());
36. }
37.
38. @RequestMapping("foo")
39. public String foo() {
40. throw new RuntimeException("Expected exception in controller");
41. }
42.
43.}
注:@Controller:1:spring的控制層。2:spring的註解之一放在類名以前3:spring配置文件中若是配置了掃描包路徑,自動檢測該註釋的類並注入。4:spring控制層能夠接收請求,而且返回響應。
@RequestMapping:用戶請求路徑是http://localhost:8080/項目名/類的@RequestMapping的value值/方法的@RequestMapping的value值。
@Autowired:依賴注入。
@PathVariable:rest訪問方式獲取參數傳遞
ModelAndView:一次性返回model和view2個對象,有7個構造函數,用來設定返回對象和視圖,也能夠用set方法設置。
@ModelAttribute:獲取頁面傳遞參數。也能夠這樣用
1. @ModelAttribute("user")
2. public User addAccount() {
3. return new User("jz","123");
4. }
5.
6. @RequestMapping(value = "/helloWorld")
7. public String helloWorld(@ModelAttribute("user") User user) {
8. user.setUserName("jizhou");
9. return "helloWorld";
10.}
@SessionAttributes("user")用戶同上只是使用範圍不一樣而已。
RedirectAttributes:個人理解是controller控制層跳轉到控制層傳遞參數用的。
@Valid:對實體類的一個驗證。驗證符合jpa的標準。要和BindingResult result配合使用,若是驗證不經過的話,result.hasErrors(),跳轉 。如一個實體類標準:
1. import javax.validation.constraints.Min;
2. import javax.validation.constraints.NotNull;
3. import org.hibernate.validator.constraints.NotBlank;
4.
5. public class User {
6.
7. private String username;
8.
9. private String password;
10.
11. private int age;
12.
13. @NotBlank(message="用戶名不能爲空")
14. public String getUsername() {
15. return username;
16. }
17.
18. public void setUsername(String username) {
19. this.username = username;
20. }
21.
22. @NotNull(message="密碼不能爲null")
23. public String getPassword() {
24. return password;
25. }
26.
27. public void setPassword(String password) {
28. this.password = password;
29. }
30.
31. @Min(value=10, message="年齡的最小值爲10")
32. public int getAge() {
33. return age;
34. }
35.
36. public void setAge(int age) {
37. this.age = age;
38. }
39.
40.}
最後個方法就是拋出頁面異常.
html主要用ThyMeleaf標籤,Thymeleaf是一個XML/XHTML/HTML5模板引擎,可用於Web與非Web環境中的應用開發。它是一個開源的Java庫,基於Apache License 2.0許可,由Daniel Fernández建立,該做者仍是Java加密庫Jasypt的做者。
form.html代碼以下:
1. <!DOCTYPE html>
2. <html xmlns:th="http://www.thymeleaf.org"
3. xmlns:layout="http://www.ultraq.net.nz/web/thymeleaf/layout"
4. layout:decorator="layout">
5. <head>
6. <title>Messages : Create</title>
7. </head>
8. <body>
9. <h1 layout:fragment="header">Messages : Create</h1>
10. <div layout:fragment="content"
11. class="container">
12. <form id="messageForm"
13. th:action="@{/(form)}"
14. th:object="${message}"
15. action="#"
16. method="post">
17. <div th:if="${#fields.hasErrors('*')}"
18. class="alert alert-error">
19. <p th:each="error : ${#fields.errors('*')}"
20. th:text="${error}">
21. Validation error
22. </p>
23. </div>
24. <div class="pull-right">
25. <a th:href="@{/}" href="messages.html">
26. Messages
27. </a>
28. </div>
29. <label for="summary">Summary</label>
30. <input type="text"
31. th:field="*{summary}"
32. th:class="${#fields.hasErrors('summary')} ? 'field-error'"/>
33. <label for="text">Message</label>
34. <textarea
35. th:field="*{text}"
36. th:class="${#fields.hasErrors('text')} ? 'field-error'"></textarea>
37. <div class="form-actions">
38. <input type="submit" value="Create"/>
39. </div>
40. </form>
41. </div>
42. </body>
43.</html>
list.html代碼以下:
1. <!DOCTYPE html>
2. <html xmlns:th="http://www.thymeleaf.org"
3. xmlns:layout="http://www.ultraq.net.nz/web/thymeleaf/layout"
4. layout:decorator="layout">
5. <head>
6. <title>Messages : View all</title>
7. </head>
8. <body>
9. <h1 layout:fragment="header">Messages : View all</h1>
10. <div layout:fragment="content" class="container">
11. <div class="pull-right">
12. <a href="form.html" th:href="@{/(form)}">Create Message</a>
13. </div>
14. <table class="table table-bordered table-striped">
15. <thead>
16. <tr>
17. <td>ID</td>
18. <td>Created</td>
19. <td>Summary</td>
20. </tr>
21. </thead>
22. <tbody>
23. <tr th:if="${messages.empty}">
24. <td colspan="3">
25. No messages
26. </td>
27. </tr>
28. <tr th:each="message : ${messages}">
29. <td th:text="${message.id}">1</td>
30. <td th:text="${#calendars.format(message.created)}">
31. July 11, 2012 2:17:16 PM CDT
32. </td>
33. <td>
34. <a href="view.html"
35. th:href="@{'/' + ${message.id}}"
36. th:text="${message.summary}">
37. The summary
38. </a>
39. </td>
40. </tr>
41. </tbody>
42. </table>
43. </div>
44. </body>
45.</html>
view.html代碼以下:
1. <html xmlns:th="http://www.thymeleaf.org"
2. xmlns:layout="http://www.ultraq.net.nz/web/thymeleaf/layout"
3. layout:decorator="layout">
4. <head>
5. <title>Messages : View</title>
6. </head>
7. <body>
8. <h1 layout:fragment="header">Messages : Create</h1>
9. <div layout:fragment="content"
10. class="container">
11. <div class="alert alert-success"
12. th:if="${globalMessage}"
13. th:text="${globalMessage}">
14. Some Success message
15. </div>
16. <div class="pull-right">
17. <a th:href="@{/}" href="list.html">
18. Messages
19. </a>
20. </div>
21. <dl>
22. <dt>ID</dt>
23. <dd id="id" th:text="${message.id}">123</dd>
24. <dt>Date</dt>
25. <dd id="created"
26. th:text="${#calendars.format(message.created)}">
27. July 11, 2012 2:17:16 PM CDT
28. </dd>
29. <dt>Summary</dt>
30. <dd id="summary"
31. th:text="${message.summary}">
32. A short summary...
33. </dd>
34. <dt>Message</dt>
35. <dd id="text"
36. th:text="${message.text}">
37. A detailed message that is longer than the summary.
38. </dd>
39. </dl>
40. </div>
41. </body>
42.</html>
注th標籤的引用就是首先要注入標籤頭,xmlns:th="http://www.thymeleaf.org"放入html標籤內就能夠了,
# 表明 獲取對象 從 messages bundle 也就是消息的資源本地化文件
$ 表示從model裏面獲取
1. <div class="col-sm-9">
2. <input type="text" th:field="*{id}" placeholder="Order Id" class="col-xs-10 col-sm-5" />
3. <p style="color:red" th:if="${#fields.hasErrors('*{id}')}" th:errors="*{id}"></p>
4. </div>
th:fragment=「public」 至關於include標籤
th:each="user : ${users}" 至關於c:foreach 使用時候
如上面
<tr th:each="user : ${users}">
<td th:text="${user.id}">01</td>
<td th:text="${user.name}">朱遇平</td>
<td th:text="${user.xx}">java</td>
<td th:text="${user.xx}">程序員</td>
</tr>
th:href="@{/}"動態設置url參數
<form action="#"th:action="@{/users/add}" th:object="${myuser}"method="post">
這裏th:Object表示表單與 改myuser注入的實體映射,
在表單 th:field="*{id} 則表示 該表單的值 與 myuser的id綁定
th:if="${#fields.hasErrors('*')}"
th:if="${#strings.isEmpty(status)}"
${not #strings.isEmpty(status)}
if判斷顯示。
1. <div class="col-sm-9">
2. <input type="text" th:field="*{id}" placeholder="Order Id" class="col-xs-10 col-sm-5" />
3. <p style="color:red" th:if="${#fields.hasErrors('*{id}')}" th:errors="*{id}"></p>
4. </div>
th:errors錯誤信息顯示如上圖
http://blog.csdn.net/pdw2009/article/details/44410659
數據訪問模式:
${...},變量引用模式,好比${myBean.property},若是用springDialect,則使用的是springEL,若是不用spring,則用的ognl。
*{...},選擇表達式,通常是th:object以後,直接取object中的屬性。當沒有選取對象時,其功能等同${...},*{firstName}也等同於${#object.firstName},#object表明當前選擇的對象。
@{...}連接url的表達式。th:href="@{/xxx/aa.do(id=${o.id})",會自動進行url-encoding的處理。@{...}內部能夠是須要計算的表達式,好比:
th:href=」@{'/details/'+${user.login}(orderId=${o.id})}"
#{...},i18n,國際化。
須要注意的:
#{${welcomeMsgKey}(${session.user.name})}:i18n message支持佔位。各個表達式支持嵌套。
在SpringMvc配置thymeleaf時,遇到html中輸入th: 沒有自動提示的現象,
打開eclipse的插件安裝,Help—>Installationsnew SoftWare—>add
插件地址爲: http://www.thymeleaf.org/eclipse-plugin-update-site/
一路next,最後重啓Eclipse便可
http://www.cnblogs.com/java-zhao/p/5502398.html
http://www.oschina.net/question/779083_2148086
https://yq.aliyun.com/articles/25409
<!-- thymeleaf -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-thymeleaf</artifactId>
</dependency>
<!--
devtools能夠實現頁面熱部署(即頁面修改後會當即生效,這個能夠直接在application.properties文件中配置spring.thymeleaf.cache=false來實現),
實現類文件熱部署(類文件修改後不會當即生效),實現對屬性文件的熱部署。
即devtools會監聽classpath下的文件變更,而且會當即重啓應用(發生在保存時機),注意:由於其採用的虛擬機機制,該項重啓是很快的
-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-devtools</artifactId>
<optional>true</optional><!-- optional=true,依賴不會傳遞,該項目依賴devtools;以後依賴myboot項目的項目若是想要使用devtools,須要從新引入-->
</dependency>
1. devtools reload的原理:
2. 用兩個ClassLoader去加載類,一個加載器加載第三庫的jar這些jar不多更改,另一個restart ClassLoader加載你正在開發的資源。這樣,當文件更改時,restart ClassLoader會被throw away,一個新的restart ClassLoader會生成加載開發的類文件。這樣的加載機制比冷啓動快不少。
· 默認狀況下,/META-INF/maven,/META-INF/resources,/resources,/static,/templates,/public這些文件夾下的文件修改不會使應用重啓,可是會從新加載(devtools內嵌了一個LiveReload server,當資源發生改變時,瀏覽器刷新)。
· 若是想改變默認的設置,能夠本身設置不重啓的目錄:spring.devtools.restart.exclude=static/**,public/**,這樣的話,就只有這兩個目錄下的文件修改不會致使restart操做了。
· 若是要在保留默認設置的基礎上還要添加其餘的排除目錄:spring.devtools.restart.additional-exclude
若是想要使得當非classpath下的文件發生變化時應用得以重啓,使用:spring.devtools.restart.additional-paths,這樣devtools就會將該目錄列入了監聽範圍。
http://blog.jobbole.com/72992/
http://www.thymeleaf.org/doc/tutorials/2.1/usingthymeleaf.html#what-is-thymeleaf
1.build.gradle
1.1.引入jar包,添加配置
"org.springframework.boot:spring-boot-starter-thymeleaf",
"org.springframework.boot:spring-boot-devtools:1.3.0.RELEASE"
1.2.bootRun {
addResources = true
} ####若是沒有該項配置,devtools不會起做用,即應用不會restart,###但不添加彷佛也是可使用的
2. application.yml
spring.thymeleaf.cache:false
3.經過關閉自動重啓System.setProperty("spring.devtools.restart.enabled","false");
4.代碼配置
@Configuration
public class GTVGApplication {
private static TemplateEngine templateEngine;
static {
initializeTemplateEngine();
}
private static void initializeTemplateEngine() {
ServletContextTemplateResolver templateResolver = new ServletContextTemplateResolver();
// XHTML is the default mode, but we set it anyway for better
// understanding of code
templateResolver.setTemplateMode("XHTML");
// This will convert "home" to "/WEB-INF/templates/home.html"
templateResolver.setPrefix("/WEB-INF/templates/");
templateResolver.setSuffix(".html");
// Template cache TTL=1h. If not set, entries would be cached until
// expelled by LRU
templateResolver.setCacheTTLMs(3600000L);
templateEngine = new TemplateEngine();
templateEngine.setTemplateResolver(templateResolver);
}
}
http://blog.csdn.net/pdw2009/article/details/44701127
傳統標籤使用
<form:inputText name="userName"value="${user.name}"/>
改成
<input type="text" name="userName" value="James Carrot" th:value="${user.name}" />
1. 引入jar包
maven:在pom文件中加入引用的包
<dependency>
<groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-thymeleaf</artifactI>
</dependency>
gradle:在build文件中加入引用的包
org.springframework.boot:spring-boot-starter-thymeleaf
2. 配置文件
在spring-boot下,默認約定了Controller試圖跳轉中thymeleaf模板文件的的前綴prefix是」classpath:/templates/」,後綴suffix是」.html」
這個在application.properties配置文件中是能夠修改的 (能夠在類裏面指定,也能夠在yml配置文件裏面配置,由項目配置決定)
以下配置能夠修改試圖跳轉的前綴和後綴
spring.thymeleaf.prefix: /templates/
spring.thymeleaf.suffix: .html
#清除模版引擎中的緩存,頁面修改後不須要重啓
項目得打成war包
3. 引擎經常使用基礎點
一、在html頁面中引入thymeleaf命名空間,即<htmlxmlns:th=http://www.thymeleaf.org></html>,此時在html模板文件中動態的屬性使用th:命名空間修飾 二、引用靜態資源文件,好比CSS和JS文件,語法格式爲「@{}」,如@{/js/bootstrap/bootstarp.js }會引入/static目錄下的/js/bootstrap/bootstarp.js文件 三、訪問spring-mvc中model的屬性,語法格式爲「${}」,如${user.id}能夠獲取model裏的user對象的id屬性 四、循環,在html的標籤中,加入th:each=「value:${list}」形式的屬性,如<span th:each=」user:${users}」></span>能夠迭代users的數據 五、判斷,在html標籤中,加入th:if=」表達式」能夠根據條件顯示html元素 <span th:if="${not #lists.isEmpty(blog.publishTime)}"> <span id="publishtime" th:text="${#dates.format(blog.publishTime,'yyyy-MM-ddHH:mm:ss')}"></span> </span> 以上代碼表示若blog.publishTime時間不爲空,則顯示時間 六、時間的格式化, ${#dates.format(blog.publishTime,'yyyy-MM-ddHH:mm:ss')} 表示將時間格式化爲」yyyy-MM-ddHH:mm:ss」格式化寫法與Java格式化Date的寫法是一致的。 七、字符串拼接,有兩種形式 好比拼接這樣一個URL:/blog/delete/{blogId} 第一種:th:href="'/blog/delete/' + ${blog.id}" 第二種:th:href="${'/blog/delete/' + blog.id}"