本文章将介绍Thymeleaf标准表达式语法中的概念。我们将使用th:ifth:unless标记在模板中迭代显示产品列表,如果产品的价格大于100,则会显示:“特殊提供”

编辑源代码以便将产品列表显示为表格行。已经将Product类的对象列表设置为具有变量名称productList的上下文模型(参考:MyController.java中的实现)。

如果要上机实践,请参考:Thymeleaf+SpringMVC5示例项目。这里不再重复创建项目的过程,这里将只介绍如何使用Thymeleaf标准表达式和标签。

这里创建一个Maven Web项目: thymeleaf-tutorials ,其目录结构如下所示 -

1523793471753562.png

数据访问类的实现:DAO.java -

  1. package com.e-learn.dao;
  2.  
  3. import java.math.BigDecimal;
  4. import java.sql.Timestamp;
  5. import java.text.ParseException;
  6. import java.text.SimpleDateFormat;
  7. import java.util.ArrayList;
  8. import java.util.Date;
  9. import java.util.List;
  10.  
  11. import com.e-learn.spring.bean.*;
  12.  
  13. /**
  14. * Mock persistence.
  15. */
  16. public class DAO {
  17.  
  18. private static final String NO_WEBSITE = null;
  19.  
  20. public static Product loadProduct() {
  21. try {
  22. SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
  23. return new Product("Wooden wardrobe with glass doors", Integer.valueOf(850), sdf.parse("2013-02-18"));
  24. } catch (ParseException ex) {
  25. throw new RuntimeException("Invalid date");
  26. }
  27. }
  28.  
  29. public static List<Product> loadAllProducts() {
  30. SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
  31. List<Product> products = new ArrayList<Product>();
  32. try {
  33. products.add(new Product("花生油", Integer.valueOf(125), sdf.parse("2018-02-18")));
  34. products.add(new Product("苏打饼干", Integer.valueOf(15), sdf.parse("208-02-15")));
  35. products.add(new Product("拿铁", Integer.valueOf(45), sdf.parse("2019-02-20")));
  36. products.add(new Product("调和油", Integer.valueOf(20), sdf.parse("2019-02-21")));
  37. products.add(new Product("大豆油", Integer.valueOf(49), sdf.parse("2019-02-15")));
  38. products.add(new Product("玉米汁", Integer.valueOf(80), sdf.parse("2019-02-17")));
  39. } catch (ParseException ex) {
  40. throw new RuntimeException("Invalid date");
  41. }
  42. return products;
  43. }
  44.  
  45.  
  46.  
  47. public static Timestamp loadReleaseDate() {
  48. try {
  49. SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm");
  50. Date date = sdf.parse("2014-01-31 15:00");
  51. return new Timestamp(date.getTime());
  52. } catch (ParseException ex) {
  53. throw new RuntimeException("Invalid date");
  54. }
  55. }
  56.  
  57. }

控制器类的实现:MyController.java -

  1. package com.e-learn.spring.controller;
  2.  
  3. import java.text.ParseException;
  4. import java.text.SimpleDateFormat;
  5. import java.util.Date;
  6. import java.util.List;
  7.  
  8. import org.springframework.stereotype.Controller;
  9. import org.springframework.ui.Model;
  10. import org.springframework.web.bind.annotation.GetMapping;
  11.  
  12. import com.e-learn.dao.DAO;
  13. import com.e-learn.spring.bean.Product;
  14.  
  15. @Controller
  16. public class MyController {
  17.  
  18. @GetMapping("/")
  19. public String index(Model model) throws ParseException {
  20. SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
  21. Product product = new Product("花生油", 129, sdf.parse("2018-02-18"));
  22. model.addAttribute("product", product);
  23. return "index";
  24. }
  25.  
  26. @GetMapping("/escape")
  27. public String escape(Model model) throws ParseException {
  28. String html = "Welcome to our <b>fantastic</b> grocery store!";
  29. model.addAttribute("html", html);
  30. return "escape";
  31. }
  32.  
  33. @GetMapping("/iteration")
  34. public String iteration(Model model) throws ParseException {
  35. List productList = DAO.loadAllProducts();
  36. model.addAttribute("productList", productList);
  37. return "iteration";
  38. }
  39.  
  40. @GetMapping("/conditional")
  41. public String conditional(Model model) throws ParseException {
  42. List productList = DAO.loadAllProducts();
  43. model.addAttribute("productList", productList);
  44. return "conditional";
  45. }
  46.  
  47. }

模板文件的实现:/webapp/WEB-INFO/views/conditional.html -

  1. <html xmlns:th="http://www.thymeleaf.org">
  2. <head>
  3. <meta charset="UTF-8">
  4. <meta http-equiv="X-UA-Compatible" content="IE=edge">
  5. <link rel="stylesheet" th:href="@{/css/main.css}" />
  6. <style>
  7. span.offer {
  8. font-weight: bold;
  9. color: green;
  10. }
  11. </style>
  12. <title>SpringMVC5+Thymeleaf条件示例</title>
  13. </head>
  14. <body>
  15. <h2>Spring MVC5 + Thymeleaf条件示例</h2>
  16. <table>
  17. <thead>
  18. <tr>
  19. <th>行序号</th>
  20. <th>产品名称</th>
  21. <th>价格</th>
  22. <th>有效日期</th>
  23. <th>备注</th>
  24. </tr>
  25. </thead>
  26. <tbody th:remove="all-but-first">
  27. <tr th:each="product : ${productList}">
  28. <td th:text="${productStat.count}">1</td>
  29. <td th:text="${product.description}">Red chair</td>
  30. <td th:text="${'¥' + #numbers.formatDecimal(product.price, 1, 2)}">¥350</td>
  31. <td th:text="${#dates.format(product.availableFrom, 'dd-MM-yyyy')}">2018-02-20</td>
  32. <td><span th:if="${product.price gt 100}" class="offer">特殊提供</span></td>
  33. </tr>
  34. <tr>
  35. <td>White table</td>
  36. <td>¥200</td>
  37. <td>2018-04-10</td>
  38. <td> </td>
  39. </tr>
  40. <tr>
  41. <td>Reb table</td>
  42. <td>¥200</td>
  43. <td>2018-02-20</td>
  44. <td> </td>
  45. </tr>
  46. <tr>
  47. <td>Blue table</td>
  48. <td>¥200</td>
  49. <td>2018-02-20</td>
  50. <td> </td>
  51. </tr>
  52. </tbody>
  53. </table>
  54.  
  55. </body>
  56. </html>

运行上面项目,在浏览器中显示效果如下 -

1523793473637978.png

高级应用

在这部分中,我们将演示其它几个标签(如:th:switchth:caseth:unless)的用法。

需要重写以下几个文件,DAO.java -

  1. package com.e-learn.dao;
  2.  
  3. import java.math.BigDecimal;
  4. import java.sql.Timestamp;
  5. import java.text.ParseException;
  6. import java.text.SimpleDateFormat;
  7. import java.util.ArrayList;
  8. import java.util.Date;
  9. import java.util.List;
  10.  
  11. import com.e-learn.spring.bean.*;
  12.  
  13. /**
  14. * Mock persistence.
  15. */
  16. public class DAO {
  17.  
  18. private static final String NO_WEBSITE = null;
  19.  
  20. public static Product loadProduct() {
  21. try {
  22. SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
  23. return new Product("Wooden wardrobe with glass doors", Integer.valueOf(850), sdf.parse("2013-02-18"), "");
  24. } catch (ParseException ex) {
  25. throw new RuntimeException("Invalid date");
  26. }
  27. }
  28.  
  29. public static List<Product> loadAllProducts() {
  30. SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
  31. List<Product> products = new ArrayList<Product>();
  32. try {
  33. products.add(new Product("花生油", Integer.valueOf(125), sdf.parse("2018-02-18"),"CG"));
  34. products.add(new Product("苏打饼干", Integer.valueOf(15), sdf.parse("208-02-15"),"CG"));
  35. products.add(new Product("拿铁", Integer.valueOf(45), sdf.parse("2019-02-20"),"PT"));
  36. products.add(new Product("调和油", Integer.valueOf(20), sdf.parse("2019-02-21"),"CX"));
  37. products.add(new Product("大豆油", Integer.valueOf(49), sdf.parse("2019-02-15"),""));
  38. products.add(new Product("玉米汁", Integer.valueOf(80), sdf.parse("2019-02-17"),""));
  39. } catch (ParseException ex) {
  40. throw new RuntimeException("Invalid date");
  41. }
  42. return products;
  43. }
  44.  
  45.  
  46.  
  47. public static Timestamp loadReleaseDate() {
  48. try {
  49. SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm");
  50. Date date = sdf.parse("2014-01-31 15:00");
  51. return new Timestamp(date.getTime());
  52. } catch (ParseException ex) {
  53. throw new RuntimeException("Invalid date");
  54. }
  55. }
  56.  
  57. }

产品类的实现:Product.java -

  1. package com.e-learn.spring.bean;
  2.  
  3. import java.util.Date;
  4.  
  5. public class Product {
  6.  
  7. private String description;
  8. private Integer price;
  9. private Date availableFrom;
  10. private String saleType;// 销售类型:促销,拼团,闪购,其它
  11.  
  12. public String getSaleType() {
  13. return saleType;
  14. }
  15.  
  16. public void setSaleType(String saleType) {
  17. this.saleType = saleType;
  18. }
  19.  
  20. public Product(final String description, final Integer price, final Date availableFrom, final String saleType) {
  21. this.description = description;
  22. this.price = price;
  23. this.availableFrom = availableFrom;
  24. this.saleType = saleType;
  25. }
  26.  
  27. public Date getAvailableFrom() {
  28. return this.availableFrom;
  29. }
  30.  
  31. public void setAvailableFrom(final Date availableFrom) {
  32. this.availableFrom = availableFrom;
  33. }
  34.  
  35. public String getDescription() {
  36. return this.description;
  37. }
  38.  
  39. public void setDescription(final String description) {
  40. this.description = description;
  41. }
  42.  
  43. public Integer getPrice() {
  44. return this.price;
  45. }
  46.  
  47. public void setPrice(final Integer price) {
  48. this.price = price;
  49. }
  50.  
  51. }

控制器类的实现:MyController.java -

  1. package com.e-learn.spring.controller;
  2.  
  3. import java.text.ParseException;
  4. import java.text.SimpleDateFormat;
  5. import java.util.Date;
  6. import java.util.List;
  7.  
  8. import org.springframework.stereotype.Controller;
  9. import org.springframework.ui.Model;
  10. import org.springframework.web.bind.annotation.GetMapping;
  11.  
  12. import com.e-learn.dao.DAO;
  13. import com.e-learn.spring.bean.Product;
  14.  
  15. @Controller
  16. public class MyController {
  17.  
  18. @GetMapping("/")
  19. public String index(Model model) throws ParseException {
  20. SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
  21. Product product = new Product("花生油", 129, sdf.parse("2018-02-18"), "");
  22. model.addAttribute("product", product);
  23. return "index";
  24. }
  25.  
  26. @GetMapping("/escape")
  27. public String escape(Model model) throws ParseException {
  28. String html = "Welcome to our <b>fantastic</b> grocery store!";
  29. model.addAttribute("html", html);
  30. return "escape";
  31. }
  32.  
  33. @GetMapping("/iteration")
  34. public String iteration(Model model) throws ParseException {
  35. List productList = DAO.loadAllProducts();
  36. model.addAttribute("productList", productList);
  37. return "iteration";
  38. }
  39.  
  40. @GetMapping("/conditional")
  41. public String conditional(Model model) throws ParseException {
  42. List productList = DAO.loadAllProducts();
  43. model.addAttribute("productList", productList);
  44. return "conditional";
  45. }
  46.  
  47. }

模板文件的实现:/webapp/WEB-INFO/views/conditional.html -

  1. <html xmlns:th="http://www.thymeleaf.org">
  2. <head>
  3. <meta charset="UTF-8">
  4. <meta http-equiv="X-UA-Compatible" content="IE=edge">
  5. <link rel="stylesheet" th:href="@{/css/main.css}" />
  6. <style>
  7. span.offer {
  8. font-weight: bold;
  9. color: green;
  10. }
  11. </style>
  12. <title>SpringMVC5+Thymeleaf条件示例</title>
  13. </head>
  14. <body>
  15. <h2>Spring MVC5 + Thymeleaf条件示例</h2>
  16. <table>
  17. <thead>
  18. <tr>
  19. <th>行序号</th>
  20. <th>产品名称</th>
  21. <th>价格</th>
  22. <th>有效日期</th>
  23. <th>销售类型</th>
  24. <th>备注</th>
  25. </tr>
  26. </thead>
  27. <tbody th:remove="all-but-first">
  28. <tr th:each="product : ${productList}">
  29. <td th:text="${productStat.count}">1</td>
  30. <td th:text="${product.description}">Red chair</td>
  31. <td th:text="${'¥' + #numbers.formatDecimal(product.price, 1, 2)}">¥350</td>
  32. <td th:text="${#dates.format(product.availableFrom, 'dd-MM-yyyy')}">2018-02-20</td>
  33. <td th:switch="${product.saleType}">
  34. <span th:case="'CG'">闪购</span>
  35. <span th:case="'PT'">拼团</span>
  36. <span th:case="'CX'">促销</span>
  37. <span th:case="*">其它</span>
  38. </td>
  39. <td><span th:class="${product.price gt 100}?'offer'" th:text="${product.price}">特殊提供</span></td>
  40. </tr>
  41. <tr>
  42. <td>White table</td>
  43. <td>¥200</td>
  44. <td>2018-04-10</td>
  45. <td> </td>
  46. </tr>
  47. <tr>
  48. <td>Reb table</td>
  49. <td>¥200</td>
  50. <td>2018-02-20</td>
  51. <td> </td>
  52. </tr>
  53. <tr>
  54. <td>Blue table</td>
  55. <td>¥200</td>
  56. <td>2018-02-20</td>
  57. <td> </td>
  58. </tr>
  59. </tbody>
  60. </table>
  61.  
  62. </body>
  63. </html>

执行上面示例代码,得到以下结果 -

1523793476148485.png