写在前面

模板页面中的 html 上需要声明 Thymeleaf 的命名空间,具体代码如下

<html xmlns:th="http://www.thymeleaf.org">

这样比如我们在Idea中编写ThymeLeaf代码的时候,就会有相关的代码提示。

th:text和th:utext

这两个标签用于文本内容的显示操作,他们功能相近,只有区别于会不会解析。

  • th:text 进行文本替换 不会解析html
  • th:utext 进行文本替换 会解析html

示例

我们编写一个这样的代码

@RequestMapping("/th")
public String th(Model model){String msg = "<h1>我是h1</h1>";model.addAttribute("msg",msg);return "/course/th";
}

对于th:text,在HTML页面中这样编写,如下

<p th:text="text标签:  + ${msg}"></p>

因为text不会进行解析,将会获得如下结果

<p>text标签:<h1>我是h1</h1></p>

对于th:utext在HTML页面中这样编写,如下

<p th:utext="utext标签: + ${msg}"></p>

因为utext会进行解析,将会获得如下结果

当然,这里提示一下的是,使用 + 和 | | 效果是一样的,如下代码所示

<p th:utext="utext标签: + ${msg}"></p>
<p th:utext="|utext标签: ${msg}|"></p>

字符串拼接

拼接字符串通过 + 或者 | 进行拼接,请求我们先编写一个这样的代码,以及使用下面的HTML模板

 @RequestMapping("/th")public String th(Model model){model.addAttribute("a",1);model.addAttribute("b",2);return "/course/th";}
#模板一
<p th:text="${a}+${b}"></p>
#模板二
<p th:text="|${a} ${b}|"></p>
#模板三
<p th:text="${a} > ${b}"></p>

所得结果如下

#结果一
<p>3</p>
#结果二
<p>1 2</p>
#结果三
<p>false</p>

我们换过一个java代码,以及使用下面的HTML模板

@RequestMapping("/th")
public String th(Model model){model.addAttribute("flag",true);return "/course/th";
}
<p th:text="!${flag}"></p>

得到如下结果:<p>false</p>

*{…}和 ${…}表达式

一般情况下 *{…} 和 ${…}是一样的,但是 *{…} 一般和 th:object 一起使用来完成对象属性的简写,我们来举个例子,用如下java代码

@RequestMapping("/th")
public String th(Model model){User user = new User("ljk",18);model.addAttribute("user",user);return "/course/th";
}

模板操作

#使用 ${...}操作
<p th:text="${user.name}"></p>
<p th:text="${user.age}"></p>
#使用 *{...}操作
<p th:text="*{user.name}"></p>
<p th:text="*{user.age}"></p>

两个获得的结果都是如下

<p>ljk</p>
<p>18</p>

我们这里来试试使用 *{…}特有操作

<div th:object="${user}" ><p th:text="*{name}"></p><p th:text="*{age}"></p>
</div>

会得到如下结果页面:

<p>ljk</p>
<p>18</p>

#{…}表达式

用于国际化message.properties 属性读取,定义message_zh_CN.properties 配置文件


定义国际化处理转换处理类

@Configuration
public class LocaleResolverConfig {@Bean(name="localeResolver")public LocaleResolver localeResolverBean() {return new SessionLocaleResolver();}
}

定义国际化处理的controller

@Controller
public class ProductController {@Autowiredprivate LocaleResolver localeResolver;private  ProductService productService = new ProductService();@RequestMapping("/")public String useT(Model model,HttpServletRequest request,HttpServletResponse response) {//设置访问用户信息到sessionrequest.getSession(true).setAttribute("user", new User("我是", "哈哈", "CHINA", null));localeResolver.setLocale(request,response,Locale.CHINA);return "productList";}
}

如果没有定义 message_en_US.properties 和message_zh_CN.properties 会默认取message.properties中的信息。如果 Locale = Locale.CHINA 就取 message_zh_CN.properties。如果 Locale = Locale.US 就取 message_en_US.properties。我们使用如下模板代码测试一下

<p th:utext="#{home.welcome(${session.user.name})}">Welcome to our grocery store, Sebastian!</p>

得到如下结果

欢迎来到我们的杂货店,我是哈哈

~{…}片段表达式

这个一般和模版布局的语法一起使用,具体使用方式请看下面模版布局的教程。

@{…}链接网址表达式

一般和 th:href、th:src进行结合使用,用于显示Web 应用中的URL链接。通过@{…}表达式,Thymeleaf 可以帮助我们拼接上web应用访问的全路径,同时我们可以通过()进行参数的拼接

模板代码:

#模板一
<img th:src="@{/images/gtvglogo.png}"  />
#模板二
<a th:href="@{/product/comments(prodId=${prod.id})}" >查看</a>
#模板三
<a th:href="@{/product/comments(prodId=${prod.id},prodId2=${prod.id})}" >查看</a>

结果页面:

#结果一
<img src="/sbe/images/gtvglogo.png">
#结果二
<a href="/sbe/product/comments?prodId=2">查看</a>
#结果三
<a href="/sbe/product/comments?prodId=2&amp;prodId2=2">查看</a>

th:if和th:unless

  • th:if 当条件为true则显示。
  • th:unless 当条件为false 则显示。

java代码:

@RequestMapping("/thif")
public String thif(Model model){model.addAttribute("flag",true);return "/course/thif";
}

模版页面:

#模板一
<p th:if="${flag}">if判断</p>
#模板二
<p th:unless="!${flag}">unless 判断</p>

结果页面:

<p>if判断</p>
<p>unless 判断</p>

switch

  • th:switch 我们可以通过switch来完成类似的条件表达式的操作。

java代码:

@RequestMapping("/thswitch")
public String thswitch(Model model){User user = new User("ljk",23);model.addAttribute("user",user);return "/course/thswitch";
}

模版页面:

<div th:switch="${user.name}"><p th:case="'ljk'">User is  ljk</p><p th:case="ljk1">User is ljk1</p>
</div>

结果页面:

<div><p> User is ljk</p></div>

for循环

  • th:each 遍历集合

java代码:

@RequestMapping("/theach")
public String theach(Model model){List<User> userList = new ArrayList<User>();User user1 = new User("ljk",18);User user2 = new User("ljk2",19);User user3 = new User("ljk3",20);User user4 = new User("lj4",21);userList.add(user1);userList.add(user2);userList.add(user3);userList.add(user4);model.addAttribute("userList",userList);List<String> strList = new ArrayList<String>();strList.add("ljk");strList.add("ljk2");strList.add("ljk3");strList.add("lj4");model.addAttribute("strList",strList);return "/course/theach";
}

模版页面:

 <table><thead><tr><th>用户名称</th><th>用户年龄</th></tr></thead><tbody><tr th:each="user : ${userList}" th:class="${userStat.odd}? 'odd'"><td th:text="${user.name}">Onions</td><td th:text="${user.age}">2.41</td></tr></tbody>
</table>
----------------------------------------------------------------------
<table><thead><tr><th>用户名称</th></tr></thead><tbody><tr th:each="str : ${strList}" th:class="${strStat.odd}? 'odd'"><td th:text="${str}">Onions</td></tr></tbody>
</table>

结果页面:

这里解释一下th:class="${strStat.odd}? 'odd'",我们可以通过便利的变量名+Stat 来获取索引 是否是第一个或最后一个等。
便利的变量名+Stat称作状态变量,其属性有:

  • index:当前迭代对象的迭代索引,从0开始,这是索引属性;
  • count:当前迭代对象的迭代索引,从1开始,这个是统计属性;
  • size:迭代变量元素的总量,这是被迭代对象的大小属性;
  • current:当前迭代变量;
  • even/odd:布尔值,当前循环是否是偶数/奇数(从0开始计算);
  • first:布尔值,当前循环是否是第一个;
  • last:布尔值,当前循环是否是最后一个

th:href

用于声明在a 标签上的href属性的链接 该语法会和@{…} 表达式一起使用。
java代码

@RequestMapping("/thhref")
public String thhref(Model model){return "/course/thhref";
}

模板页面

<a href="../home.html" th:href="@{/}">返回首页</a>

结果页面:

<a href="/sbe/">返回首页</a>

th:class

用于声明在标签上class 属性信息。
java代码:

@RequestMapping("/thclass")
public String thclass(Model model){return "/course/thclass";
}

模版页面:

<p th:class=" 'even'? 'even' : 'odd'" th:text=" 'even'? 'even' : 'odd'"></p>

结果页面:

<p class="even">even</p>

th:attr

用于声明html中或自定义属性信息。

java代码:

@RequestMapping("/thattr")
public String thattr(Model model){return "/course/thattr";
}

模版页面:

<img  th:attr="src=@{/images/gtvglogo.png}" />

结果页面:

<img src="/sbe/images/gtvglogo.png">

th:value

用于声明html中value属性信息。
java代码:

@RequestMapping("/thvalue")
public String thvalue(Model model){model.addAttribute("name", "ljk");return "/course/thvalue";
}

模版页面:

<input type="text" th:value="${name}" />

结果页面:

<input type="text" value="ljk">

th:action

用于声明html from标签中action属性信息。
java代码:

@RequestMapping("/thaction")public String thaction(Model model){return "/course/thaction";
}

模版页面:

<form action="subscribe.html" th:action="@{/subscribe}"><input type="text" name="name" value="abc"/>
</form>

结果页面:

<form action="/sbe/subscribe"><input type="text" name="name" value="abc">
</form>

th:id

用于声明htm id属性信息。
java代码:

@RequestMapping("/thid")
public String thid(Model model){model.addAttribute("id", 123);return "/course/thid";
}

模版页面:

<p th:id="${id}"></p>

结果页面:

<p id="123"></p>

th:inline

JavaScript内联 操作使用的语法,具体请参考下面内联操作相关介绍

th:onclick

用于声明htm 中的onclick事件。

java代码:

@RequestMapping("/thonclick")
public String honclick(Model model){return "/course/thonclick";
}

模版页面:

<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
<script type="text/javascript">function showUserInfo(){alert("i am zhuoqianmingyue!")}
</script>
</head>
<body><p th:onclick="'showUserInfo()'">点我</p>
</body>
</html>

结果页面:

<p onclick="showUserInfo()">点我</p>

th:selected

用于声明htm 中的selected属性信息。

java代码:

@RequestMapping("/thselected")
public String thselected(Model model){model.addAttribute("sex", 1);return "/course/thselected";
}

模版页面:

<select><option name="sex"></option><option th:selected="1 == ${sex}">男</option><option th:selected="0 == ${sex}">女</option>
</select>

结果页面:

<select>
<option name="sex"></option><option selected="selected">男</option><option>女</option>
</select>

th:src

用于声明htm 中的img中src属性信息。

java代码:

@RequestMapping("/thsrc")
public String thsrc(Model model){return "/course/thsrc";
}

模版页面:

<img  title="GTVG logo" th:src="@{/images/gtvglogo.png}" />

结果页面:

<img title="GTVG logo" src="/sbe/images/gtvglogo.png">

th:style

用于声明htm中的标签 css的样式信息。

java代码:

RequestMapping("/thstyle")
public String thstyle(Model model){model.addAttribute("isShow", true);return "/course/thstyle";
}

模版页面:

<p th:style="'display:' + @{(${isShow} ? 'none' : 'block')} + ''"></p>

结果页面:

<p style="display:none"></p>

th:with

用于thymeleaf 模版页面中局部变量定义的使用。

java代码:

#代码一
@RequestMapping("/thwith")
public String thwith(Model model){model.addAttribute("today", new Date());return "/course/thwith";
}#代码二
@RequestMapping("/thwith")
public String thwith(Model model){List<User> users = new ArrayList<User>();users.add(new User("ljk",18));users.add(new User("ljk2",18));model.addAttribute("users",users);return "/course/thwith";
}

模版页面:

#模板一
<p th:with="df='dd/MMM/yyyy HH:mm'">Today is: <span th:text="${#dates.format(today,df)}">13 February 2011</span>
</p>#模板二
<div th:with="firstEle=${users[0]}"><p>第一个用户的名称是: <span th:text="${firstEle.name}"></span>.</p>
</div>

结果页面:

#结果一
<span>02/02/2020 06:52</span>#结果二
<div><p>第一个用户的名称是: <span>ljk</span>.</p>
</div>

还有一种用法是在模版布局中带参数的引用片段中使用方式如下:

<div th:replace="::frag" th:with="onevar=${value1},twovar=${value2}">

具体演示请参考模版布局中的介绍。

Elvis运算符

Elvis运算可以理解成简单的判断是否为null的三元运算的简写,如果值为null显示默认值,如果不为null 则显示原有的值。

java代码:

#代码一
@RequestMapping("/elvis")
public String elvis(Model model){model.addAttribute("age", null);return "/course/elvis";
}#代码二
@RequestMapping("/elvis")
public String elvis(Model model){model.addAttribute("age2", 18);return "/course/elvis";
}

模版页面:

#模板一<p>Age: <span th:text="${age}?: '年龄为nll'"></span></p>
#模板二
<p>Age2: <span th:text="${age2}?: '年龄为nll'"></span></p>

结果页面:

#结果一
<p>Age: <span>年龄为nll</span></p>#结果二
<p>Age2: <span>18</span></p>

三元表达式

我们可以在thymeleaf 的语法中使用三元表达式 具体使用方法是在th:x 中通过 表达式?1选项:2选项。

java代码:

#代码一
@RequestMapping("/threeElementOperation")
public String threeElementOperation(Model model){return "/course/threeElementOperation";
}#代码二
@RequestMapping("/threeElementOperation")
public String threeElementOperation(Model model){model.addAttribute("name", "ljk");return "/course/threeElementOperation";
}

模版页面:

#模板一
<p th:class=" 'even'? 'even' : 'odd'" th:text=" 'even'? 'even' : 'odd'"></p>#模板二
<p th:value="${name eq 'ljk' ? '帅哥':'丑男'}" th:text="${name eq 'ljk' ? '帅哥':'丑男'}"></p>

结果页面:

#结果一
<p class="even">even</p>#结果二<p value="帅哥">帅哥</p>

条件表达式操作字符:

  • gt:great than(大于)
  • ge:great equal(大于等于)
  • eq:equal(等于)
  • lt:less than(小于)
  • le:less equal(小于等于)
  • ne:not equal(不等于)

No-Operation(_)

Elvis运算符 的一种特殊简写操作,当显示的值为null 是就什么都不做。
java代码:

@RequestMapping("/noOperation")
public String noOperation(Model model){model.addAttribute("name", null);return "/course/noOperation";
}

模版页面:

<span th:text="${name} ?: _">no user authenticated</span>

结果页面:

<span>no user authenticated</span>

标准方言中存在以下固定值布尔属性:

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

针对特定的HTML5属性:

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:fragment
th:frame th:frameborder th:headers
th:height th:high th:href
th:hreflang th:hspace th:http-equiv
th:icon th:id th:inline
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:onabort th:onafterprint
th:onbeforeprint th:onbeforeunload th:onblur
th:oncanplay th:oncanplaythrough th:onchange
th:onclick th:oncontextmenu th:ondblclick
th:ondrag th:ondragend th:ondragenter
th:ondragleave th:ondragover th:ondragstart
th:ondrop th:ondurationchange th:onemptied
th:onended th:onerror th:onfocus
th:onformchange th:onforminput th:onhashchange
th:oninput th:oninvalid th:onkeydown
th:onkeypress th:onkeyup th:onload
th:onloadeddata th:onloadedmetadata th:onloadstart
th:onmessage th:onmousedown th:onmousemove
th:onmouseout th:onmouseover th:onmouseup
th:onmousewheel th:onoffline th:ononline
th:onpause th:onplay th:onplaying
th:onpopstate th:onprogress th:onratechange
th:onreadystatechange th:onredo th:onreset
th:onresize th:onscroll th:onseeked
th:onseeking th:onselect th:onshow
th:onstalled th:onstorage th:onsubmit
th:onsuspend th:ontimeupdate th:onundo
th:onunload th:onvolumechange th:onwaiting
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:inline=“text” 来开启内联操作。当然如果想整个页面使用可以直接声明在body上即可。具体使用方式如下面代码所示。

模版页面:

<div th:inline="text"><p>Hello, [[${user.name}]]!</p>
</div>

结果内容如下:

<div><p>Hello,zhuoqianmingyue!</p>
</div>

这样的操作和使用th:text是等同的。

<div><p th:text="Hello,+${user.name}"></p>
</div>

[[…]]对应于th:text,[(…)]对应于th:utext

禁用内联操作

这我们可以通过在父标签或者本标签上声明th:inline="none"来禁用内联的操作,如下面代码所示:
模版页面:

<p th:inline="none">A double array looks like this: [[1, 2, 3], [4, 5]]!</p>

结果页面:

<p>A double array looks like this: [[1, 2, 3], [4, 5]]!</p>

JavaScript内联

如果我们想在JavaScript 中使用内联操作,需要在 script 标签上声明 th:inline=“javascript” 然后我们就可以 script 标签中使用内联操作了。具体使用方式如下面代码所示:
模版页面:

<script th:inline="javascript">var username = [[${user.name}]];
</script>

结果页面:

<script th:inline="javascript">var username = "zhuoqianmingyue";
</script>

CSS内联

我们可以通过在 style 标签上声明 th:inline=“css” 来开启在css中使用内联的操作,具体操作方式如下:

<style th:inline="css">...
</style>

例如,假设我们将两个变量设置为两个不同的String值:classname = 'main_elems’以及align = ‘center’
我们可以像以下一样使用它们:

<style th:inline="css">.[[${classname}]] {text-align: [[${align}]];}
</style>

结果页面:

<style th:inline="css">.main_elems {text-align: center;}
</style>

模板布局

定义引用片段代码

SpringBoot2.0 使用模版模版布局需要先引入 thymeleaf的 thymeleaf-layout-dialect依赖

<dependency><groupId>nz.net.ultraq.thymeleaf</groupId><artifactId>thymeleaf-layout-dialect</artifactId>
</dependency>

定义footer.html页面 该页面就是我们的引用片段代码

<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head><meta charset="UTF-8"><title>Title</title>
</head>
<body><div th:fragment="copy">&copy; 2011 The Good Thymes Virtual Grocery</div>
</body>
</html>

我们可以通过 th:fragment 来定义引用片段,然后可以在其他页面进行引用。定义引用页面 index.html

<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head><meta charset="UTF-8"><title>Title</title>
</head>
<body><div th:insert="~{footer :: copy}"></div>
</body>
</html>

通过 th:insert 和 ~{…}片段引用表达式 进行引入footer.html中定义的片段,定义访问index页面的 controller

@Controller
@RequestMapping("/layout")
public class LayOutController {@RequestMapping("/index")public String index(){return "/layout/index";}
}

结果页面:

<div><div>© 2011 The Good Thymes Virtual Grocery</div>
</div>

如下面的代码2种方式的写法是一致的。如果你觉得~{footer :: copy}写法比较麻烦可以采用简写的方式footer :: copy。

<div th:insert="footer :: copy"></div>
<div th:insert="~{footer :: copy}"></div>

通过id属性来声明片段

我们可以通过 th:fragment 来定义引用片段,但是我们也可以通过在引用片段代码上声明id属性的方式进行片段的引用,具体操作方式如下:定义引用片段代码模版页面 footer.html

<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head><meta charset="UTF-8"><title>Title</title>
</head>
<body>
<div id="copy-section" >&copy; 2011 The Good Thymes Virtual Grocery
</div>
</body>
</html>

引用引用片段的模版页面:index.html

<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head><meta charset="UTF-8"><title>Title</title>
</head>
<body>
<div th:insert="~{footer :: #copy-section}"></div>
</body>
</html>

结果页面:

<div>
<div id="copy-section">© 2011 The Good Thymes Virtual Grocery
</div>
</div>

footer :: #copy-section和~{footer :: #copy-section} 结果是一致的。

th:insert和th:replace(和th:include)之间的区别

  • th:insert 是最简单的:他会将使用th:insert的标签 和引用片段的内容都显示出来
  • th:replace 插入引用片段的标签和内容
  • th:include类似于th:insert,只插入此片段的内容。

th:insert

java代码:

@Controller
@RequestMapping("/layout")
public class LayoutController {@RequestMapping("/index2")public String index2(Model model) {return "/layout/index2";}
}

声明引用片段模版页面:footer2.html

<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
</head>
<body>
<footer th:fragment="copy">&copy; 2011 The Good Thymes Virtual Grocery
</footer>
</body>
</html>

引用片段模版页面:index2.html

<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
</head>
<body>
<div th:insert="footer2 :: copy"></div>
<div th:replace="footer2 :: copy"></div>
<div th:include="footer2:: copy"></div>
</body>
</html>
#th:insert 结果:
<div>
<footer>© 2011 The Good Thymes Virtual Grocery
</footer>
</div>#th:replace结果:
<footer>© 2011 The Good Thymes Virtual Grocery
</footer>#th:include结果:
<div>© 2011 The Good Thymes Virtual Grocery
</div>

带参数的引用片段

定义引用片段代码模版页面 footer.html

<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
</head>
<body>
<div th:fragment="frag (onevar,twovar)"><p th:text="${onevar} + ' - ' + ${twovar}">...</p>
</div>
</body>
</html>

引用引用片段的模版页面:index.html

<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
</head>
<body><div th:insert="footer :: frag('a','b')"></div>
</body>
</html>

结果页面:

<div>
<div><p>a - b</p>
</div>
</div>

th:insert=“footer ::frag (onevar=‘a’,twovar=‘b’)” 和th:insert=“footer :: frag(‘a’,‘b’)效果是相等的。还有另一种写法就是使用th:with
th:insert=”::frag" th:with=“onevar=‘a’,twovar=‘b’”

删除模版片段

我们为了方便通过直接查看下面的页面 productList.html (主要是为了作为原型页面进行查看)我们需要添加一些模拟数据。

<table><tr><th>NAME</th><th>PRICE</th><th>IN STOCK</th><th>COMMENTS</th></tr><tr th:each="prod : ${prods}" th:class="${prodStat.odd}? 'odd'"><td th:text="${prod.name}">Onions</td><td th:text="${prod.price}">2.41</td><td th:text="${prod.inStock}? #{true} : #{false}">yes</td><td><span th:text="${#lists.size(prod.comments)}">2</span> comment/s<a href="comments.html" th:href="@{/product/comments(prodId=${prod.id})}" th:unless="${#lists.isEmpty(prod.comments)}">view</a></td></tr><tr class="odd"><td>Blue Lettuce</td><td>9.55</td><td>no</td><td><span>0</span> comment/s</td></tr><tr><td>Mild Cinnamon</td><td>1.99</td><td>yes</td><td><span>3</span> comment/s<a href="comments.html">view</a></td></tr>
</table>

在上面的代码中模拟数据的代码,但是我们通过正常的controller访问该页面的时候会显示出下面的模拟数据。

 <tr class="odd"><td>Blue Lettuce</td><td>9.55</td><td>no</td><td><span>0</span> comment/s</td></tr><tr><td>Mild Cinnamon</td><td>1.99</td><td>yes</td><td><span>3</span> comment/s<a href="comments.html">view</a></td></tr>

thymeleaf 为我们提供了 th:remove 帮助我们解决这个问题:

 <tr class="odd" th:remove="all"><td>Blue Lettuce</td><td>9.55</td><td>no</td><td><span>0</span> comment/s</td></tr><tr th:remove="all"><td>Mild Cinnamon</td><td>1.99</td><td>yes</td><td><span>3</span> comment/s<a href="comments.html">view</a></td></tr>

我们在模拟数据上声明th:remove=“all” 后在此通过url访问 没有了我们之前的模拟数据

all属性中的这个值是什么意思?th:remove可以根据其价值以五种不同的方式表现:

  • all:删除包含标记及其所有子标记。
  • body:不要删除包含标记,但删除其所有子标记。
  • tag:删除包含标记,但不删除其子项。
  • all-but-first:删除除第一个之外的所有包含标记的子项。
  • none: 没做什么。此值对于动态评估很有用。当我们知道没有属性的含义后我们可以通过在 声明一次即可,无需在通过定义多个 th:remove=“all”

预定义的工具对象

dates

处理日期数据 生成,转换,获取日期的具体天数 年数。
java代码:

@RequestMapping("/dates")
public String dates(Model model) throws ParseException{Date date = new Date();model.addAttribute("date",date);String dateStr = "2018-05-30";SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");Date date2 =  sdf.parse(dateStr); Date[] datesArray = new Date[2];datesArray[0] = date;datesArray[1] = date2;model.addAttribute("datesArray",datesArray);List<Date> datesList = new ArrayList<Date>();datesList.add(date);datesList.add(date2);model.addAttribute("datesList",datesList);return "/course/dates";
}

format操作

java代码:

#代码一
Date date = new Date();#代码三
Date[] datesArray = new Date[2];
datesArray[0] = date;
datesArray[1] = date2;#代码四
List<Date> datesList = new ArrayList<Date>();
datesList.add(date);
datesList.add(date2);
model.addAttribute("datesList",datesList);

模版页面:

#模板一
<span th:text="${#dates.format(date)}">4564546</span>#模板二
<span th:text="${#dates.format(date, 'dd/MMM/yyyy HH:mm')}">4564546</span>#模板三
<p th:text="${#dates.format(datesArray, 'yyyy-MM-dd HH:mm')}"></p>#模板四
<p th:text="${#dates.listFormat(datesList, 'dd/MMM/yyyy HH:mm')}"></p>

结果页面:

#结果一
<span>2020年1月30日 上午10时03分24秒 </span>结果二
<span>30/一月/2020 10:03 </span>#结果三
<p>2019-05-30 10:03</p>#结果四
<p>[30/五月/2019 10:03, 30/五月/2018 00:00]</p>

获取日期属性操作

java代码:

#代码一
Date date = new Date();

模版页面:

#模板一
<p th:text="${#dates.day(date)} "></p>#模板二
<p th:text="${#dates.month(date)}"></p>#模板三
<p th:text="${#dates.monthName(date)}"></p>#模板四
<p th:text="${#dates.monthNameShort(date)} "></p>#模板五
<p th:text="${#dates.year(date)}"></p>#模板六
<p th:text="${#dates.dayOfWeek(date)}"></p>#模板七
<p th:text="${#dates.dayOfWeekName(date)}"></p>#模板八
<p th:text="${#dates.dayOfWeekNameShort(date)}"></p>#模板九
<p th:text="${#dates.hour(date)}"></p>#模板十
<p th:text="${#dates.minute(date)}"></p>#模板十一
<p th:text="${#dates.second(date)}"></p>#模板十二
<p th:text="${#dates.millisecond(date)} "></p>

结果页面:

#结果一
<p>30</p>#结果二
<p>5</p>#结果三
<p>五月</p>#结果四
<p>五月</p>#结果五
<p>2019</p>#结果六
<p>5</p>#结果七
<p>星期四</p>#结果七
<p>星期四</p>#结果八
<p>10</p>#结果九
<p>10</p>#结果十
<p>45</p>#结果十一
<p>853</p>

生成日期操作

模版页面:

#模板一
<p th:text="${#dates.createNow()}"></p>#模板二
<p th:text="${#dates.format(#dates.createNow())}"></p>#模板三
<p th:text="${#dates.create('2019','05','30')}"></p>#模板四
<p th:text="${#dates.create('2019','05','31','10','18')}"></p>#模板五
<p th:text="${#dates.create('2019','05','30','10','18','34')}"></p>#模板六
<p th:text="${#dates.createToday()}"></p>

结果页面:

#结果一
<p>Thu May 30 10:15:55 CST 2019</p>#结果二
<p>2019年5月30日 上午10时15分55秒</p>#结果三
<p>Thu May 30 00:00:00 CST 2019</p>#结果四
<p>Fri May 31 10:18:00 CST 2019</p>#结果五
<p>Thu May 30 10:18:34 CST 2019</p>#结果六
<p>Thu May 30 00:00:00 CST 2019</p>

numbers

处理数字数据的转换。包括:

  • 对不够位数的数字进行补0(formatInteger )
  • 设置千位分隔符(formatInteger)
  • 精确小数点(formatDecimal )
  • 设置百分号(formatPercent )
  • 生成数组(sequence )
    代码演示:
@RequestMapping("/numbers")
public String numbers(Model model) throws ParseException{return "/course/numbers";
}

数字进行补0操作

模板代码:

<p th:text="${#numbers.formatInteger('123',4)}"></p>
<p th:text="${#numbers.formatInteger('123',3)}"></p>
<p th:text="${#numbers.formatInteger('123',2)}"></p>

结果页面:

<p>0123</p>
<p>123</p>
<p>123</p>

Java代码

    @RequestMapping("/numbers")public String numbers(Model model) throws ParseException{List<Integer> numList = new ArrayList<Integer>();numList.add(1);numList.add(12);numList.add(13);model.addAttribute("numList",numList);return "/course/numbers";}

模板代码:

<p th:text="${#numbers.listFormatInteger(numList,3)}"></p>

结果页面:

<p>[001, 012, 013]</p>

千位分隔符操作

模板代码:

<p th:text="${#numbers.formatInteger('1000',2,'POINT')}"></p>
<p th:text="${#numbers.formatInteger('1000',6,'POINT')}"></p>
<p th:text="${#numbers.formatInteger('1000',7,'POINT')}"></p>
<p th:text="${#numbers.formatInteger('1000',2,'COMMA')}"></p>
<p th:text="${#numbers.formatInteger('1000',2,'WHITESPACE')}"></p>
<p th:text="${#numbers.formatInteger('1000',2,'NONE')}"></p>
<p th:text="${#numbers.formatInteger('1000',2,'DEFAULT')}"></p>

结果页面:

<p>1.000</p>
<p>001.000</p>
<p>0.001.000</p>
<p>1,000</p>
<p>1 000</p>
<p>1000</p>
<p>1,000</p>

精确小数点操作

模板代码:

<p th:text="${#numbers.formatDecimal('10.123',3,2)}"></p>
<p th:text="${#numbers.formatDecimal('1000.123',5,'POINT',2,'COMMA')}"></p>

结果页面:

<p>010.12</p>
<p>01.000,12</p>

钱显示符号操作

模板代码:

<p th:text="${#numbers.formatCurrency('1000')}"></p>

结果页面:

<p>¥1,000.00</p>

百分比操作

模板代码:

<p th:text="${#numbers.formatPercent('0.2',2, 4)}"></p>
<p th:text="${#numbers.formatPercent('0.2',3, 2)}"></p>

结果页面:

<p>20.0000%</p>
<p>020.00%</p>

生成数组操作

模板代码:

<div th:each="num : ${#numbers.sequence(0,4)}" ><p th:text="${num}"></p>
</div><div th:each="num : ${#numbers.sequence(0,4,1)}" ><p th:text="${num}"></p>
</div><div th:each="num : ${#numbers.sequence(0,10,2)}" ><p th:text="${num}"></p>
</div>

结果页面:

<div><p>0</p></div>
<div><p>1</p></div>
<div><p>2</p></div>
<div><p>3</p></div>
<div><p>4</p></div><div><p>0</p></div>
<div><p>1</p></div>
<div><p>2</p></div>
<div><p>3</p></div>
<div><p>4</p></div><div><p>0</p></div>
<div><p>2</p></div>
<div><p>4</p></div>

strings

处理String的相关操作,包括:

  • 字符串转换(toString)
  • 检查字符串是否为空(isEmpty)
  • 字符串是为空替换操作(defaultString)
  • 检查字符串中是否包含某个字符串(contains + containsIgnoreCase)
  • 检查字符串是以片段开头还是结尾(startsWith endsWith)
  • 截取(substring substringAfter)
  • 替换(replace)
  • 追加(prepend append)
  • 变更大小写(toUpperCase toLowerCase)
  • 拆分和组合字符串(arrayJoin arraySplit)
  • 去空格(trim)
  • 缩写文本(abbreviate)
  • 字符串连接(concat)

java 代码

@RequestMapping("/strings")public String strings(Model model){Object object = "123";model.addAttribute("object",object);List<Integer> numList = new ArrayList<Integer>();numList.add(1);numList.add(12);numList.add(13);model.addAttribute("numList",numList);
}Object object = "123";

模板代码:

<p th:text="${object}"></p>

结果页面:

<p>123</p>

toString操作

Java代码

Object object = "123";List<Integer> numList = new ArrayList<Integer>();numList.add(1);numList.add(12);numList.add(13);

模板代码:

<p th:text="${#strings.toString(object)}"></p><p th:text="${#strings.toString(numList)}"></p>

结果页面:

<p>123</p><p>[1, 12, 13]</p>

isEmpty操作

Java代码

String name = null;

模板代码:

<p th:text="${#strings.isEmpty(name)}"></p>

结果页面:

<p>true</p>

Java代码

List<String> nameList = new ArrayList<String>();
nameList.add("1");
nameList.add(null);

模板代码:

<p th:text="${#strings.listIsEmpty(nameList)}"></p>

结果页面:

<p>[false, true]</p>

Java代码

Set<String> nameSet = new HashSet<String>();
nameSet.add(null);
nameSet.add("1");

模板代码:

<p th:text="${#strings.setIsEmpty(nameSet)}"></p>

结果页面:

<p>[true, false]</p>

defaultString操作

Java代码

String name = null;

模板代码:

<p th:text="${#strings.defaultString(text,'该值为null')}"></p>

结果页面:

<p>该值为null</p>

Java代码

List<String> nameList = new ArrayList<String>();
nameList.add("1");
nameList.add(null);

模板代码:

<p th:text="${#strings.listDefaultString(textList,'该值为null')}"></p>

结果页面:

<p>[abc, 该值为null]</p>

contains操作

模板代码:

<p th:text="${#strings.contains('abcez','ez')}"></p>
<p th:text="${#strings.containsIgnoreCase('abcEZ','ez')}"></p>

结果页面:

<p>true</p>
<p>true</p>

startsWith endsWith 操作

模板代码:

<p th:text="${#strings.startsWith('Donabcez','Don')}"></p>
<p th:text="${#strings.endsWith('Donabcezn','n')}"></p>

结果页面:

<p>true</p>
<p>true</p>

indexOf操作

模板代码:

<p th:text="${#strings.indexOf('abcefg','e')}"></p>

结果页面:

<p>3</p>

substring操作

模板代码:

<p th:text="${#strings.substring('abcefg',3,5)}"></p>

结果页面:

<p>ef</p>

replace操作

模板代码:

<p th:text="${#strings.replace('lasabce','las','ler')}"></p>

结果页面:

<p>lerabce</p>

prepend操作

模板代码:

<p th:text="${#strings.prepend('abc','012')}"></p>

结果页面:

<p>012abc</p>

append操作

模板代码:

<p th:text="${#strings.append('abc','456')}"></p>

结果页面:

<p>abc456</p>

toUpperCase操作

模板代码:

<p th:text="${#strings.toUpperCase('abc')}"></p>

结果页面:

<p>ABC</p>

toLowerCase操作

模板代码:

<p th:text="${#strings.toLowerCase('ABC')}"></p>

结果页面:

<p>abc</p>

length操作

模板代码:

<p th:text="${#strings.length('abc')}"></p>

结果页面:

<p>3</p>

trim操作

模板代码:

<p th:text="${#strings.trim(' abc ')}"></p>

结果页面:

<p>abc</p>

abbreviate操作

模板代码:

<p th:text="${#strings.abbreviate('12345678910',10)}"></p>

结果页面:

<p>1234567...</p>

#objects

处理Object对象的操作 包含obj不为空返回改值如果为空返回默认值(nullSafe)
java代码

@RequestMapping("/objects")
public String objects(Model model){Object obj = null;model.addAttribute("obj",obj);
}

模板代码:

<p th:text="${#objects.nullSafe(obj,'该对象为null')}"></p>

结果页面:

<p>该对象为null</p>

#bools

判断对象是否为ture或者是否为false的操作。

  • 数字 1 为 ture , 0 为 false;
  • “on” 为 true, “off” 为false;
  • “true” 为true, "false"为 false;

isTrue操作

模板代码:

<p th:text="${#bools.isTrue(true)} "></p>
<p th:text="${#bools.isTrue(false)} "></p>
<p th:text="${#bools.isTrue('on')} "></p>
<p th:text="${#bools.isTrue('off')} "></p>
<p th:text="${#bools.isTrue('true')} "></p>
<p th:text="${#bools.isTrue('false')} "></p>
<p th:text="${#bools.isTrue(1)} "></p>
<p th:text="${#bools.isTrue(0)} "></p>

结果页面:

<p>true</p>
<p>false</p>
<p>true</p>
<p>false</p>
<p>true</p>
<p>false</p>
<p>true</p>
<p>false</p>

#arrays

处理数组的相关操作的内置对象,包含:

  • 转换数组 toStringArray toIntegerArray
  • 获取数组的长度(length )
  • 判断数组是否为空(isEmpty )
  • 是否包含某个元素(contains)
  • 是否包含一批元素(containsAll)
  • 其中 toStringArray 等操作接受的是Object对象,containsAll 接受+ 一批元素支持数组和集合的参数。

toStringArray操作

java代码

@RequestMapping("/arrays")
public String arrays(Model model){List<String> object = new ArrayList<String>();object.add("1");object.add("2");model.addAttribute("object",object);
}

模板代码:

 <p th:text="${#arrays.toStringArray(object)} "></p>

结果页面:

<p>[Ljava.lang.String;@3cca655d</p>

length操作

java代码

Integer[] array = {1,2,3};

模板代码:

 <p th:text="${#arrays.length(array)} "></p>

结果页面:

<p>3</p>

isEmpty操作

java代码

Integer[] array = {1,2,3};

模板代码:

 <p th:text="${#arrays.isEmpty(array)} "></p>

结果页面:

<p>false</p>

contains操作

java代码

Integer[] array = {1,2,3};

模板代码:

<p th:text="${#arrays.contains(array,1)} "></p>

结果页面:

<p>true</p>

containsAll操作

java代码

Integer[] array = {1,2,3};
Integer[] array2 = {1,3};

模板代码:

 <p th:text="${#arrays.containsAll(array,array2)} "></p>

结果页面:

<p>true</p>

#lists

处理 list 相关操作的内置对象,包括:

  • 计算长度(size)
  • 检查list是否为空(isEmpty)
  • 检查元素是否包含在list中(contains,containsAll)
  • 对给定list的副本排序(sort)
    java代码
@RequestMapping("/lists")
public String lists(Model model){List<Integer> list = new ArrayList<Integer>();list.add(1);list.add(3);list.add(2);model.addAttribute("list",list);}

模板代码:

<p th:text="${#lists.size(list)} "></p>

结果页面:

<p>3</p>

java代码:

 List<Integer> list = new ArrayList<Integer>();list.add(1);list.add(3);list.add(2);

模板代码:

<p th:text="${#lists.isEmpty(list)} "></p>

结果页面:

<p>false</p>

java代码:

 List<Integer> list = new ArrayList<Integer>();list.add(1);list.add(3);list.add(2);

模板代码:

<p th:text="${#lists.contains(list, 1)}"></p>

结果页面:

<p>true</p>

java代码:

List<Integer> list = new ArrayList<Integer>();
list.add(1);
list.add(3);
list.add(2);
List<Integer> list2 = new ArrayList<Integer>();
list2.add(1);
list2.add(2);

模板代码:

<p th:text="${#lists.containsAll(list,list2)}"></p>

结果页面:

<p>true</p>

java代码:

List<Integer> list = new ArrayList<Integer>();
list.add(1);
list.add(3);
list.add(2);

模板代码:

<p th:text="${#lists.sort(list)}"></p>

结果页面:

<p>[1, 2, 3]</p>

#sets

处理 set 相关操作的内置对象,包括:

  • 转换为Set(toSet)
  • 计算长度(size)
  • 检查set是否为空(isEmpty)
  • 检查元素是否包含在set中 (contains,containsAll)

size操作

java代码

@RequestMapping("/sets")
public String sets(Model model){Set<Integer> set = new HashSet<Integer>();set.add(1);set.add(2);set.add(3);set.add(4);model.addAttribute("set",set);}

模板代码:

<p th:text="${#sets.size(set)} "></p>

结果页面:

<p>3</p>

isEmpty 操作

java代码:

Set<Integer> set = new HashSet<Integer>();set.add(1);set.add(2);set.add(3);set.add(4);

模板代码:

<p th:text="${#sets.isEmpty(set)} "></p>

结果页面:

<p>false</p>

contains操作

java代码:

Set<Integer> set = new HashSet<Integer>();set.add(1);set.add(2);set.add(3);set.add(4);

模板代码:

<p th:text="${#sets.contains(set, 1)}"></p>

结果页面:

<p>true</p>

containsAll操作

java代码

Set<Integer> set = new HashSet<Integer>();set.add(1);set.add(2);set.add(3);set.add(4);Integer[] elements = {1,2};
model.addAttribute("elements",elements);

模板代码:

<p th:text="${#sets.containsAll(set, elements)}"></p>

结果页面:

<p>true</p>

sort操作

java代码:

Set<Integer> set = new HashSet<Integer>();set.add(1);set.add(2);set.add(3);set.add(4);

模板代码:

<p th:text="${#lists.sort(list)}"></p>

结果页面:

<p>[1, 2, 3]</p>

#maps

处理 map相关操作的内置对象,包括:

  • 计算长度(size)
  • 检查map是否为空(isEmpty)
  • 检查映射中是否包含键或值(containsKey,containsAllKeys,containsValue)

java代码:

@RequestMapping("/maps")
public String maps(Model model){Map<String,Integer> map = new HashMap<String,Integer>();map.put("1",1);map.put("2",2);map.put("3",3);model.addAttribute("map",map);
}

模板代码:

<p th:text="${#maps.size(map)} "></p>

结果页面:

<p>3</p>

java代码:

 Map<String,Integer> map = new HashMap<String,Integer>();map.put("1",1);map.put("2",2);map.put("3",3);

模板代码:

<p th:text="${#maps.isEmpty(map)} "></p>

结果页面:

<p>false</p>

java代码:

 Map<String,Integer> map = new HashMap<String,Integer>();map.put("1",1);map.put("2",2);map.put("3",3);

模板代码:

<p th:text="${#maps.containsKey(map, '1')}"></p>

结果页面:

<p>true</p>

java代码:

Map<String,Integer> map = new HashMap<String,Integer>();map.put("1",1);map.put("2",2);map.put("3",3);
String[] keys = {"1","2"};
model.addAttribute("keys",keys);

模板代码:

<p th:text="${#maps.containsAllKeys(map, keys)}"></p>

结果页面:

<p>true</p>

java代码:

Map<String,Integer> map = new HashMap<String,Integer>();map.put("1",1);map.put("2",2);map.put("3",3);

模板代码:

<p th:text="${#maps.containsValue(map, 2)}"></p>

结果页面:

<p>true</p>

java代码:

Map<String,Integer> map = new HashMap<String,Integer>();map.put("1",1);map.put("2",2);map.put("3",3);
Integer[] values = {1,2};
model.addAttribute("values",values);

模板代码:

<p th:text="${#maps.containsAllValues(map, values)}"></p>

结果页面:

<p>true</p>

#aggregates

用户处理集合或者数组的一些统计操作,包括:

  • 求和(sum)
  • 求平均值(avg)
  • 处理包装类型或基本类型的数组或集合
  • 求和操作

java代码:

@RequestMapping("/aggregates")
public String aggregates(Model model){Integer[] array = {1,2,3,4};model.addAttribute("array",array);return "/course/aggregates";
}

模板代码:

<p th:text="${#aggregates.sum(array)} "></p>

结果页面:

<p>10</p>

java代码:

List<Integer> list = new ArrayList<Integer>();
list.add(1);
list.add(2);
list.add(3);
list.add(4);

模板代码:

<p th:text="${#aggregates.sum(list)} "></p>

结果页面:

<p>10</p>

求平均值操作

java代码:

 Integer[] array = {1,2,3,4};

模板代码:

<p th:text="${#aggregates.avg(array)} "></p>

结果页面:

<p>2.5</p>

java代码:

List<Integer> list = new ArrayList<Integer>();
list.add(1);
list.add(2);
list.add(3);
list.add(4);

模板代码:

<p th:text="${#aggregates.avg(list)} "></p>

结果页面:

<p>2.5</p>

小结

本文主要介绍 Thymeleaf 的基础用法、内联、模板布局、预定义的工具对象。整体来看Thymeleaf 使用语法还是很强大的。

模板引擎Thymeleaf?来这一篇就够用了相关推荐

  1. Spring Boot (四)模板引擎Thymeleaf集成

    一.Thymeleaf介绍 Thymeleaf是一种Java XML / XHTML / HTML5模板引擎,可以在Web和非Web环境中使用.它更适合在基于MVC的Web应用程序的视图层提供XHTM ...

  2. 六十四、SpringBoot中的模板引擎Thymeleaf

    @Author:Runsen 来源:尚硅谷 下面建议读者学习尚硅谷的B站的SpringBoot视频,我是学雷丰阳视频入门的. 具体链接如下:B站尚硅谷SpringBoot教程 文章目录 使用Sprin ...

  3. Spring Boot 最佳实践(四)模板引擎Thymeleaf集成

    ## 一.Thymeleaf介绍 Thymeleaf是一种Java XML / XHTML / HTML5模板引擎,可以在Web和非Web环境中使用.它更适合在基于MVC的Web应用程序的视图层提供X ...

  4. JavaWeb~模板引擎Thymeleaf总结

    文章目录 模板引擎是什么 有哪些常见的模板引擎 Thymeleaf使用流程 常用标签 链接表达式@{...} 变量表达式${...} 选择变量表达*{...} 消息表达式#{...}(了解) 回顾:几 ...

  5. 模板引擎 Thymeleaf 语法

    模板引擎 Thymeleaf 1. Thymeleaf 简介 Thymeleaf[taɪm lif],百里香叶,是一个流行的模板引擎,该模板引擎采用 Java 语言开发.Java 中常见的模板引擎有 ...

  6. SpringBoot-web开发(三): 模板引擎Thymeleaf

    [SpringBoot-web系列]前文: SpringBoot-web开发(一): 静态资源的导入(源码分析) SpringBoot-web开发(二): 页面和图标定制(源码分析) 目录 1. 引入 ...

  7. Spring boot(五)模板引擎 Thymeleaf

    Thymeleaf 是一款用于渲染 XML/XHTML/HTML 5 内容的模板引擎.类似 JSP.Velocity.FreeMaker 等,它也可以轻易的与 Spring MVC 等 Web 框架进 ...

  8. 模板引擎——Thymeleaf

    模板引擎 JSP.Velocity.Freemarker.Thymeleaf 1.引入thymeleaf: <dependency><groupId>org.springfra ...

  9. 前端模板引擎Thymeleaf快速入门

    文章目录 1. Thymeleaf特点 2. 提供数据 3. 引入启动器 4. 静态页面 5. 测试 6.模板缓存 1. Thymeleaf特点 简单说, Thymeleaf 是一个跟 Velocit ...

  10. SpringBoot入门:新一代Java模板引擎Thymeleaf(理论)

    Spring Boot 提供了spring-boot-starter-web来为Web开发予以支持,spring-boot-starter-web为我们提供了嵌入的Tomcat以及SpringMVC的 ...

最新文章

  1. android mock测试资源,Android 单元测试 --Mock 及 Mockito
  2. DSP F28335的SCI模块
  3. 最简单代码ASP.NET开源QQ登陆for Oauth2.0
  4. 从618大促聊聊华为云GaussDB NoSQL的蓬勃张力
  5. 完美者右键扩展菜单管理器 1.2.1 中文绿色版
  6. adb avd install 失败_Android 模拟器(emulator-5554...)出现错误解决办法
  7. 网易严选搜索推荐实践之:“全能选手”召回表征算法实践
  8. fastjson转换包含date类型属性的对象时报错com.alibaba.fastjson.JSONException: For input string 解决方法
  9. 自己的Linux用户
  10. 智能优化算法改进算法 -附代码
  11. linux实验十shell程序设计,实验二Linux Shell编程.doc
  12. 总结一下用caffe跑图片数据的研究流程接上篇
  13. steam登录api_steam饰品骗术——骗你说你的账户违反了 Steam 服务协议条款,然后让你转出库存给你的好友。...
  14. 无法使用内置管理员账户打开应用商店
  15. html js更新数据不刷新页面,用javascript实现无刷新更新数据
  16. 数据库SQLserver(课本)
  17. 数据库课设--基于Python+MySQL的餐厅点餐系统
  18. 移动端键盘弹起底部固定模块会被顶上去
  19. android色温选择控件,ColorPicker
  20. MIMO技术(二)衰落和干扰

热门文章

  1. 参加Kaggle比赛的流程
  2. 金蝶云星空与钉钉集成案例
  3. cannot find symbol
  4. 数学建模学习(83):模拟退火算法(SA)求解多元函数
  5. 居于ERP的普遍失败,再论企业管理与信息化
  6. 钱币兑换问题c语言编程,HDU 1284 钱币兑换问题
  7. Ubuntu下运行.sh文件
  8. 服务器指示灯详情 中兴,IBM System x服务器前面板指示灯说明(新版)
  9. 创业公司如何制定员工股份和股权的分配
  10. 【仅供参考】资源共享汇总