SpringBoot 的入门学习(3):模板引擎与web实验例子

模板引擎

前端交给我们的页面,是html页面。如果是我们以前开发,我们需要把他们转成jsp页面,jsp好处就是当我们查出一些数据转发到JSP页面以后,我们可以用jsp轻松实现数据的显示,及交互等。

jsp支持非常强大的功能,包括能写Java代码,但是呢,我们现在的这种情况,SpringBoot这个项目首先是以jar的方式,不是war,像第二,我们用的还是嵌入式的Tomcat,所以呢,他现在默认是不支持jsp的

那不支持jsp,如果我们直接用纯静态页面的方式,那给我们开发会带来非常大的麻烦,那怎么办呢?

SpringBoot推荐你可以来使用模板引擎

模板引擎,我们其实大家听到很多,其实jsp就是一个模板引擎,还有用的比较多的freemarker,包括SpringBoot给我们推荐的Thymeleaf,模板引擎有非常多,但再多的模板引擎,他们的思想都是一样的,什么样一个思想呢我们来看一下这张图:

在这里插入图片描述
版本引擎的作用: 把这个模板和这个数据交给我们模板引擎,模板引擎按照我们这个数据帮你把这表达式解析、填充到我们指定的位置,然后把这个数据最终生成一个我们想要的内容给我们写出去,这就是我们这个模板引擎,不管是jsp还是其他模板引擎,都是这个思想。只不过呢,就是说不同模板引擎之间,他们可能这个语法有点不一样。

引入Thymeleaf

怎么引入呢,对于 springboot 来说,什么事情不都是一个start的事情嘛,我们去在项目中引入一下。给大家三个网址:

  • Thymeleaf 官网:https://www.thymeleaf.org/
  • Thymeleaf 在Github 的主页:https://github.com/thymeleaf/thymeleaf
  • Spring官方文档:找到我们对应的版本
    https://docs.spring.io/spring-boot/docs/2.2.5.RELEASE/reference/htmlsingle/#using-boot-starter

找到对应的pom依赖:可以适当点进源码看下本来的包!

<!--thymeleaf-->
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-thymeleaf</artifactId>
</dependency>

Maven会自动下载jar包,我们可以去看下下载的东西;
在这里插入图片描述

Thymeleaf 的使用

我们首先得按照 SpringBoot 的自动配置原理看一下我们这个Thymeleaf的自动配置规则,在按照那个规则,我们进行使用。
我们去找一下 Thymeleaf 的自动配置类:ThymeleafProperties

@ConfigurationProperties(
    prefix = "spring.thymeleaf"
)
public class ThymeleafProperties {
    private static final Charset DEFAULT_ENCODING;
    public static final String DEFAULT_PREFIX = "classpath:/templates/";
    public static final String DEFAULT_SUFFIX = ".html";
    private boolean checkTemplate = true;
    private boolean checkTemplateLocation = true;
    private String prefix = "classpath:/templates/";
    private String suffix = ".html";
    private String mode = "HTML";
    private Charset encoding;
}

我们可以在其中看到默认的前缀和后缀!
因此,我们只需要把我们的html页面放在类路径下的templates下,thymeleaf就可以帮我们自动渲染了。

测试

  • 1、编写一个TestController

    @Controller
    public class TestController {
    
        @RequestMapping("/test")
        public String test(){
            return "test";
        }
    }
    
  • 2、编写一个测试页面 test.html 放在 templates 目录下

    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>Title</title>
    </head>
    <body>
    首页
    </body>
    </html>
    
    
  • 3、启动项目请求测试
    在这里插入图片描述
    小结:

  • 只要需要使用 thymeleaf ,只需要导入对应的依赖就可以了,我们需要将 html 页面放在我们的 templates 目录下即可。

Thymeleaf 语法学习

要学习语法,还是参考官网文档最为准确,我们找到对应的版本看一下;

  • Thymeleaf 官网:https://www.thymeleaf.org/ , 简单看一下官网!我们去下载Thymeleaf的官方文档!

注意: 要使用 thymeleaf,需要在 html 文件中导入命名空间的约束

xmlns:th="http://www.thymeleaf.org"

语法规则

html 任意属性

​ th:任意html属性;来替换原生属性的值
在这里插入图片描述

变量表达式($)

变量表达式即 OGNL 表达式或Spring EL表达式(在Spring术语中也叫model attributes)。如下所示:${session.user.name}
它们将以HTML标签的一个属性来表示:

<span th:text="${book.author.name}">  
<li th:each="book : ${books}">  
选择(星号)表达式(*)

选择表达式很像变量表达式,不过它们用一个预先选择的对象来代替上下文变量容器(map)来执行
简单的来说,就是在一个作用域类,可以直接用 选择表达来表示对象中的某个属性,如下:

    <div th:object="${book}">  
      ...  
      <span th:text="*{title}">...</span>  
      ...  
    </div>  

文字国际化表达式(#)

文字国际化表达式允许我们从一个外部文件获取区域文字信息(.properties),用Key索引Value,还可以提供一组参数(可选).

#{main.title}  
#{message.entrycreated(${entryId})}  

可以在模板文件中找到这样的表达式代码:

    <table>  
      ...  
      <th th:text="#{header.address.city}">...</th>  
      <th th:text="#{header.address.country}">...</th>  
      ...  
    </table>  
URL表达式(@)

URL表达式指的是把一个有用的上下文或回话信息添加到URL,这个过程经常被叫做URL重写。如下:

@{/order/list}

URL还可以设置参数:

@{/order/details(id=${orderId})}

相对路径:

@{../documents/report}

让我们看这些表达式:

<form th:action="@{/createOrder}">
    <a href="main.html" th:href="@{/main}">

常用th标签

Text(tag body modification【标签体改造】)
关键字功能介绍案例
th:text文本替换<p th:text="${collect.description}">description</p>
th:utext支持html的文本替换<p th:utext="${htmlcontent}">conten</p>
  • 测试 如下:

    @Controller
    public class IndexController {
        @RequestMapping("/test")
        public String test(Model model){
            model.addAttribute("msg","<h1>hello springboot</h1>");
            return "test";
        }
    }
    
    
    <!DOCTYPE html>
    <html lang="en" xmlns:th="http://www.thymeleaf.org">
    <head>
        <meta charset="UTF-8">
        <title>Title</title>
    </head>
    <body>
        <div th:text="${msg}"></div>
        <div th:utext="${msg}"></div>
    </body>
    </html>
    
    

    运行项目,访问localhost:8080/test
    在这里插入图片描述

Fragment inclusion(片段的包含)
关键字功能介绍案例
th:include布局标签,替换内容到引入的文件<head th:include="layout :: htmlhead" th:with="title='xx'"></head> />
Fragment iteration(片段的迭代)
关键字功能介绍案例
th:each属性赋值<tr th:each="user,userStat:${users}">
th:each属性取值<tr th:each="user:${users}" th:text="${user}"></tr>

th:each 属性取值 :

model.addAttribute("users", Arrays.asList("张三","李四"));

<!--建议写法-->
<h3 th:each="user:${users}" th:text="${user}"></h3>

<!--同效果行内写法-->
<h3 th:each="user:${users}">[[${user}]]</h3>

在这里插入图片描述

Condition evaluation(条件评估)
关键字功能介绍案例
th:if判断条件<a th:if="${userId == collect.userId}" >
th:unless和th:if判断相反<a th:href="@{/login}"th:unless=${session.user != null}>Login</a>
th:switch多路选择配合th:case 使用 <div th:switch="${user.role}">
th:caseth:switch的一个分支<p th:case="'admin'">User is an administrator</p>
Local variable definition(局部变量的定义)
关键字功能介绍案例
th:object替换对象<div th:object="${session.user}">
th:with变量赋值运算<div th:with="isEven=${prodStat.count}%2==0"></div>
General attribute modification(通用属性修改)
关键字功能介绍案例
th:attr设置标签属性,多个属性可以用逗号分隔比如 th:attr="src=@{/image/aa.jpg},title=#{logo}",此标签不太优雅,一般用的比较少。
th:attrappend将求值的结果附加(后缀)到现有属性值。<input type="button" value="Do it!" class="btn" th:attrappend="class=${' ' + cssStyle}" />
th:attrprepend将求值的结果附加(前缀)到现有属性值。<input type="button" value="Do it!" class="btn" th:attrprepend="class=${' ' + cssStyle}" />
Specific attribute modification(特定属性修改)
关键字功能介绍案例
th:value属性赋值<input th:value="${user.name}" />
th:href链接地址<a th:href="@{/login}" th:unless=${session.user != null}>Login</a> />
th:src图片类地址引入<img class="img-responsive" alt="App Logo" th:src="@{/img/logo.png}" />
Fragment specification(片段规范)
关键字功能介绍案例
th:fragment布局标签,定义一个代码片段,方便其它地方引用<div th:fragment="alert">
Fragment removal(片段删除)
关键字功能介绍案例
th:remove删除某个属性<tr th:remove="all"> 1.all:删除包含标签和所有的孩子。

Web 实验

官方文档 - Template Layout<>

登录模块

1、创建静态资源和所需要的html
  • /static 放置 css,js等静态资源
  • /templates/login.html 登录页 。
  • /templates/main.html 主页,作为登录后跳转的页面
    注意:templates 文件夹里面的所有文件必须通过 controller 才能够访问。
2、编写 User
@AllArgsConstructor
@NoArgsConstructor
@Data
public class User {
    private String userName;
    private String password;
}
3、编写 login html。
  • 利用 模板引擎完成 登录提交的action

  • 登录页面的核心代码如下:

    <html lang="en" xmlns:th="http://www.thymeleaf.org"><!-- 要加这玩意thymeleaf才能用 -->
    <!--表单以post的方式提交,即按照Rest风格,如果是post的“/login”就为登录验证,其中“th:action”中的 “@{}”符号会自动为其添加url前缀-->
    <form class="form-signin" action="index.html" method="post" th:action="@{/login}">
    
        ...
        
        <!-- 消息提醒 -->
        <label style="color: red" th:text="${msg}"></label>
        
        <input type="text" name="userName" class="form-control" placeholder="User ID" autofocus>
        <input type="password" name="password" class="form-control" placeholder="Password">
        
        <button class="btn btn-lg btn-login btn-block" type="submit">
            <i class="fa fa-check"></i>
        </button>
        
        ...
        
    </form>
    
4、编写main

main 首先会保存login的用户名,可以使用session来保存。下面为thymeleaf内联写法,显示用户名(下面这种为行内写法,即直接的纯文本,没有用标签把它给括起来):

5、编写控制层
@Controller
public class IndexController {
    /**
     * 来登录页
     * @return
     */
    @GetMapping(value = {"/","/login"})
    public String loginPage(){

        return "login";
    }

    @PostMapping("/login")
    public String main(User user, HttpSession session, Model model){ //RedirectAttributes

        if(StringUtils.hasLength(user.getUserName()) && "123456".equals(user.getPassword())){
            //把登陆成功的用户保存起来
            session.setAttribute("loginUser",user);
            //登录成功重定向到main.html;  重定向防止表单重复提交
            return "redirect:/main.html";
        }else {
            model.addAttribute("msg","账号密码错误");
            //回到登录页面
            return "login";
        }
    }
    
     /**
     * 去main页面
     * @return
     */
    @GetMapping("/main.html")
    public String mainPage(HttpSession session, Model model){
        
        //最好用拦截器,过滤器
        Object loginUser = session.getAttribute("loginUser");
        if(loginUser != null){
        	return "main";
        }else {
            //session过期,没有登陆过
        	//回到登录页面
	        model.addAttribute("msg","请重新登录");
    	    return "login";
        }
    }
    
}

公共页面模块

  • 公共页面的路径 /templates/common.html

    <!DOCTYPE html>
    <html lang="en" xmlns:th="http://www.thymeleaf.org"><!--注意要添加xmlns:th才能添加thymeleaf的标签-->
    <head th:fragment="commonheader">
        <!--common-->
        <link href="css/style.css" th:href="@{/css/style.css}" rel="stylesheet">
        <link href="css/style-responsive.css" th:href="@{/css/style-responsive.css}" rel="stylesheet">
        ...
    </head>
    <body>
    <!-- left side start-->
    <div id="leftmenu" class="left-side sticky-left-side">
    	...
    
        <div class="left-side-inner">
    		...
    
            <!--sidebar nav start-->
            <ul class="nav nav-pills nav-stacked custom-nav">
                <li><a th:href="@{/main.html}"><i class="fa fa-home"></i> <span>Dashboard</span></a></li>
                ...
                <li class="menu-list nav-active"><a href="#"><i class="fa fa-th-list"></i> <span>Data Tables</span></a>
                    <ul class="sub-menu-list">
                        <li><a th:href="@{/basic_table}"> Basic Table</a></li>
                        <li><a th:href="@{/dynamic_table}"> Advanced Table</a></li>
                        <li><a th:href="@{/responsive_table}"> Responsive Table</a></li>
                        <li><a th:href="@{/editable_table}"> Edit Table</a></li>
                    </ul>
                </li>
                ...
            </ul>
            <!--sidebar nav end-->
        </div>
    </div>
    <!-- left side end-->
    
    
    <!-- header section start-->
    <div th:fragment="headermenu" class="header-section">
    
        <!--toggle button start-->
        <a class="toggle-btn"><i class="fa fa-bars"></i></a>
        <!--toggle button end-->
    	...
    
    </div>
    <!-- header section end-->
    
    <div id="commonscript">
        <!-- Placed js at the end of the document so the pages load faster -->
        <script th:src="@{/js/jquery-1.10.2.min.js}"></script>
        <script th:src="@{/js/jquery-ui-1.9.2.custom.min.js}"></script>
        <script th:src="@{/js/jquery-migrate-1.2.1.min.js}"></script>
        <script th:src="@{/js/bootstrap.min.js}"></script>
        <script th:src="@{/js/modernizr.min.js}"></script>
        <script th:src="@{/js/jquery.nicescroll.js}"></script>
        <!--common scripts for all pages-->
        <script th:src="@{/js/scripts.js}"></script>
    </div>
    </body>
    </html>
    
    
  • /templates/table/basic_table.html

    <!DOCTYPE html>
    <html lang="en" xmlns:th="http://www.thymeleaf.org">
    <head>
      <meta charset="utf-8">
      <meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0">
      <meta name="description" content="">
      <meta name="author" content="ThemeBucket">
      <link rel="shortcut icon" href="#" type="image/png">
    
      <title>Basic Table</title>
        <div th:include="common :: commonheader"> </div><!--将common.html的代码段 插进来-->
    </head>
    
    <body class="sticky-header">
    
    <section>
    <div th:replace="common :: #leftmenu"></div>
        
        <!-- main content start-->
        <div class="main-content" >
    
            <div th:replace="common :: headermenu"></div>
            ...
        </div>
        <!-- main content end-->
    </section>
    
    <!-- Placed js at the end of the document so the pages load faster -->
    <div th:replace="common :: #commonscript"></div>
    
    
    </body>
    </html>
    
    
  • th:include: 加载模板的内容: 读取加载节点的内容(不含节点名称),替换div内容

  • th:replace: 替换当前标签为模板中的标签,加载的节点会整个替换掉加载他的div

遍历数据与页面bug修改

  • 控制层代码:

    @GetMapping("/dynamic_table")
    public String dynamic_table(Model model){
        //表格内容的遍历
        List<User> users = Arrays.asList(new User("zhangsan", "123456"),
                                         new User("lisi", "123444"),
                                         new User("haha", "aaaaa"),
                                         new User("hehe ", "aaddd"));
        model.addAttribute("users",users);
    
        return "table/dynamic_table";
    }
    
  • 页面代码:

    <table class="display table table-bordered" id="hidden-table-info">
        <thead>
            <tr>
                <th>#</th>
                <th>用户名</th>
                <th>密码</th>
            </tr>
        </thead>
        <tbody>
            <tr class="gradeX" th:each="user,stats:${users}">
                <td th:text="${stats.count}">Trident</td>
                <td th:text="${user.userName}">Internet</td>
                <td >[[${user.password}]]</td>
            </tr>
        </tbody>
    </table>
    
    
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值