模板引擎
模板的诞生是为了将显示与数据分离,模板技术多种多样,但其本质是将模板文件和数据通过模板引擎生成最终的HTML代码。
模板技术并不是什么神秘技术,干的是拼接字符串的体力活。模板引擎就是利用正则表达式识别模板标识,并利用数据替换其中的标识符。
Thymeleaf 使用总结
- Thymeleaf 是一个Java类库,它是一个xml/xhtml/html5的模板引擎,可以作为MVC的web应用的View层。
- Thymeleaf 是一个跟 Velocity、FreeMarker 类似的模板引擎,它可以完全替代 JSP 。
是Springboot推荐使用的模板引擎。 - spring-boot下,默认约定了Controller试图跳转中thymeleaf模板文件的前缀prefix是”classpath:/templates/”,后缀suffix是”.html”
1、非严格声明
在默认配置(spring.thymeleaf.mode的默认值是HTML5)下,thymeleaf对.html的内容要求很严格
因此,改为LEGACYHTML5可以得到一个可能更友好亲切的格式要求。建议增加下面这段:
spring.thymeleaf.mode = LEGACYHTML5
或yml格式文件
#thymeleaf
thymeleaf:
mode: LEGACYHTML5
cache: false
pom.xml中增加
<dependency>
<groupId>net.sourceforge.nekohtml</groupId>
<artifactId>nekohtml</artifactId>
<version>1.9.22</version>
</dependency>
2、th标签整理
1)简单表达式
- 变量表达式 ${……}
- 选择/星号表达式 *{……} 选择表达式一般跟在th:object后,直接取object中的属性。
- 文字国际化表达式 #{……} 调用国际化的welcome语句,国际化资源文件如下
- URL表达式 @{……}
2)表达式基本对象
在上下文变量评估OGNL表达式时,一些对象表达式可获得更高的灵活性。这些对象将由#号开始引用。
- #ctx: 上下文对象.
- #vars: 上下文变量.
- #locale: 上下文语言环境.
- #httpServletRequest: (仅在web上文)HttpServletRequest 对象.
- #httpSession: (仅在web上文) HttpSession 对象.
3)表达式功能对象
- #dates:java.util.Date对象的实用方法。
- #calendars:和dates类似, 但是 java.util.Calendar 对象.
- #numbers: 格式化数字对象的实用方法。
- #strings: 字符创对象的实用方法: contains, startsWith, prepending/appending等.
- #objects: 对objects操作的实用方法。
- #bools: 对布尔值求值的实用方法。
- #arrays: 数组的实用方法。
- #lists: list的实用方法。
- #sets: set的实用方法。
- #maps: map的实用方法。
- #aggregates: 对数组或集合创建聚合的实用方法。
- #messages: 在表达式中获取外部信息的实用方法。
- #ids: 处理可能重复的id属性的实用方法 (比如:迭代的结果)。
3、静态资源引用
<link rel="stylesheet" th:href="@{/css/base1.css}" />
<script type="text/javascript" th:src="@{/js/common.js}" charset="UTF-8"></script>
4、th:include
th:include中的参数格式为templatename::[domselector]
其中templatename是模板名(如footer),domselector是可选的dom选择器。如果只写templatename,不写domselector,则会加载整个模板。
<div th:include="footer :: copyright"></div>
th:include 是加载模板的内容,而th:replace则会替换当前标签为模板中的标签
5、th:text
<p th:text="${collect.description}">description</p>
5、th:each
<li th:each="book:${booklist}" th:text="${book.bookname}">三体</li>
6、th:inline
<script type="text/javascript" th:inline="javascript">
可在内联js中使用变量,例如 [[${booklist}]]形式;
7、form表单提交及validation验证
<form action="#" th:action="@{/book/save}" method="post" th:object="${book}" method="post">
<div>
<label>书名:</label>
<input type="text" autofocus="autofocus" name="bookname" placeholder="请输入书名" th:field="*{bookname}"/>
<small th:if="${#fields.hasErrors('bookname')}" th:errors="*{bookname}">错误提示</small>
</div>
</form>
需要注意的是标签里使用了“th:object=”${book}” ”,中使用“th:field=”*{bookname}””,可是实现字段自动绑定,
但是在对应controller中需要添加下面方法,否则th:field会出错,
@ModelAttribute
Book setBook () {
return new Book ();
}
对应controller中方法如下:
@RequestMapping(value = "/save",method = RequestMethod.POST)
public String saveBook(@Valid @ModelAttribute(value="book") Book book, BindingResult result, HashMap<String, Object> map){
if(result.hasErrors()){
map.put("MSG", "出错啦!");
}else{
map.put("MSG", "提交成功!");
bookService.insertOne(book);
}
map.put("booklist",bookService.findAll(1,200));
return "/addbook";
}
实体类中可添加约束,如果违反了约束,则无法提交,并且可以用th:errors显示出错信息
public class Book {
private Integer bookid;
@NotEmpty(message="作者不能为空")
private String author;
@NotEmpty(message="书名不能为空")
private String bookname;
@Size(max = 4, message="类型名不能超过四个字")
private String booktype;
}
如果表单中要提交日期,controller中可以添加日期转换方法,防止数据类型转换失败,无法插入数据库。
@InitBinder
public void initBinder(WebDataBinder binder, WebRequest request) {
//转换日期
DateFormat dateFormat=new SimpleDateFormat("yyyy-MM-dd");
binder.registerCustomEditor(Date.class, new CustomDateEditor(dateFormat, true));// CustomDateEditor为自定义日期编辑器
}