【SpringBoot】最新版2019Spring Boot之WEB开发——springboot热部署,Thymeleaf模板引擎(速成SpringBoot)——学习笔记版解析【3】

SpringBoot


六、Web开发

1.简介

步骤:

  • 创建SpringBoot应用,选择相应的Starter

  • 在配置文件中指定必要的少量配置

  • 编写业务代码

    Web开发的自动配置类:WebMvcAutoConfiguration

2.静态资源的映射

2.1静态资源位置

查看WebMvcAutoConfiguration——>addResouceHandlers()——>getStaticLocations() ——>staticLocations

静态资源的默认位置:

  • “classpath:/META­INF/resources/”
  • “classpath:/resources/”
  • “classpath:/static/”
  • “classpath:/public/”
  • “classpath:/”(2.0中已失效)

当访问静态资源的时候会去所有静态资源文件夹中查找。

指定静态资源位置:

# 指定静态资源的位置
spring.resources.static-locations=classpath:/static,classpath:/public

2.2首页

将index.html页面放到任意一个静态资源文件夹中即可

【查看WebMvcAutoConfiguration——>WelcomePageHandlerMapping】

2.3图标

将favicon.ico放到任意一个静态资源文件夹中即可

【查看WebMvcAutoConfiguration——>内部类FaviconConfiguration——>faviconHandlerMapping】

七、模板引擎Thymeleaf

1.简介

目前Java Web开发推荐使用模板引擎,不建议使用JSP页面

  • JSP缺点:本质上就是Servlet,需要后台编译,耗时,效率低
  • 模板引擎:不需要编译,速度快

常见的模板引擎:Freemarker、Velocity、Thymeleaf等。

SpringBoot推荐使用Thymeleaf,且默认不支持JSP,因为JSP必须要打包war包才行
补充:目前主流Web开发更推荐采用前后端分离的形式,前端使用MVVM框架:Vue.js、Angular、React等

2.步骤

  • 添加Thymeleaf依赖

    <!--添加thymeleaf依赖-->
    		<dependency>
    			<groupId>org.springframework.boot</groupId>
    			<artifactId>spring-boot-starter-thymeleaf</artifactId>
    			<version>2.1.3.RELEASE</version>
    		</dependency>
    
  • 将HTML页面放到templates目录中

    templates目录下的HTML页面默认不能被直接访问,需要通过controller来访问,由thymeleaf来渲染,自动添加前缀和后缀

    【查看ThymeleafAutoConfiguration——>ThymeleafProperties——>DEFAULT_PREFIX/DEFAULT_SUFFIX1550286186572

  • 使用Thymeleaf

    页面:

    <!doctype html>
    <!--导入thymeleaf命名空间-->
    <html lang="en" xmlns:th="http://www.thymeleaf.org">
    <head>
        <meta charset="UTF-8">
        <meta name="viewport"
              content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0">
        <meta http-equiv="X-UA-Compatible" content="ie=edge">
        <title>success</title>
    </head>
    <body>
        <h1>success</h1>
        <!--使用th:text属性,设置元素中的文字,表达式${}可以获取作用域中的值}-->
        <div th:text="${name}"></div>
    </body>
    </html>
    

    Controller:

    package cn.cz.controller;
    
    import org.springframework.stereotype.Controller;
    import org.springframework.ui.Model;
    import org.springframework.web.bind.annotation.RequestMapping;
    
    /**
     * 访问模板页面
     *
     * @author czzhao2
     * @created 2019年02月16日 10:58:05
     * @lastModified
     * @history
     */
    @Controller
    public class TemplateController {
        @RequestMapping("/test1")
        public String test1(Model model){
            model.addAttribute("name","alice");
            System.out.println("====TemplateController/test1======");
            return "success";//自动添加前缀/templates和后缀.html
        }
    }
    
    
  • 修改页面后,让其立即生效

    由于thymeleaf默认启用了缓存,所以修改html页面并不会实时生效

    # 禁用thymeleaf的缓存
    spring.thymeleaf.cache=false
    

    启动IDEA的自动编译,IDEA默认是不自动编译

    • Settting——>搜索Compiler——>Build Project Automatically

      1550286907926

    • Help——>Find Action——>搜索Registry——>勾选compiler.automake…

      1550286947244

      1550286993444

3.语法规则

3.1常用属性

  • th:text、th:utext
    设置元素中的文本内容
    th:text对特殊字符进行转义,等价于内联方式[[${ }]],即普通文本字符

    th:utext对特殊字符不进行转义,等价于内联方式[(${ })]

    1550288541816

  • th:html原生属性
    用来替换指定的html原生属性的值

    (这里验证的时候需要在网页检查元素查看id/title信息)

    1550298601717

  • th:if、th:unless、th:switch、th:case
    条件判断,类似于c:if

  • th:each
    循环,类似于c:forEach

  • th:object、th:field
    用于表单数据对象的绑定,将表单绑定到Controller的一个JavaBean参数,常与th:field一起使用 需要和*{}选择表达式配合使用

    (下方有完整代码)

    1550298788464

  • th:fragment
    声明代码片段,常用于页面头部和尾部的引入

  • th:include、th:insert、th:replace引入代码片段,类似于jsp:include

    区别:

    th:include 保留自己的标签(当前页面的标签),不要th:frament的标签(即引入页面的标签)(Thymeleaf 3.0中不推荐使用)
    th:insert 保留自己的标签,保留th:frament的标签
    th:replace 不要自己的标签,保留th:frament的标签

    1550299663015

    完整代码:

    1550299716873

    User.java

    package cn.cz.bean;
    
    /**
     * 功能
     *
     * @author czzhao2
     * @created 2019年02月16日 14:17:03
     * @lastModified
     * @history
     */
    public class User {
        private  Integer id;
        private String name;
        private Integer age;
    
        @Override
        public String toString() {
            return "User{" +
                    "id=" + id +
                    ", name='" + name + '\'' +
                    ", age=" + age +
                    '}';
        }
    
        public User(Integer id, String name, Integer age) {
            this.id = id;
            this.name = name;
            this.age = age;
        }
    
        public User() {
    
        }
    
        public Integer getId() {
            return id;
        }
    
        public void setId(Integer id) {
            this.id = id;
        }
    
        public String getName() {
            return name;
        }
    
        public void setName(String name) {
            this.name = name;
        }
    
        public Integer getAge() {
            return age;
        }
    
        public void setAge(Integer age) {
            this.age = age;
        }
    }
    
    

    TemplateController.java

    package cn.cz.controller;
    
    import cn.cz.bean.User;
    import org.springframework.stereotype.Controller;
    import org.springframework.ui.Model;
    import org.springframework.web.bind.annotation.ModelAttribute;
    import org.springframework.web.bind.annotation.RequestMapping;
    import org.springframework.web.bind.annotation.ResponseBody;
    
    import java.util.Arrays;
    
    /**
     * 访问模板页面
     *
     * @author czzhao2
     * @created 2019年02月16日 10:58:05
     * @lastModified
     * @history
     */
    @Controller
    public class TemplateController {
        @RequestMapping("/test1")
        public String test1(Model model){
            model.addAttribute("name","alice");
            System.out.println("====TemplateController/test1======");
            return "success";//自动添加前缀/templates和后缀.html
        }
    
        @RequestMapping("/test2")
        public String test2(Model model){
            model.addAttribute("hello","<mark>您好</mark>");
    
            model.addAttribute("id","mydiv");
            model.addAttribute("title","this is a div");
    
            model.addAttribute("age",18);
            model.addAttribute("role","teacher");
            model.addAttribute("names", Arrays.asList("tom","alice","kill"));
    
            User user=new User(1001,"cz",18);
            model.addAttribute("user",user);
    
            return "result";
        }
    
        @RequestMapping("/modify")
        @ResponseBody
        //将表单绑定到Controller的一个JavaBean参数
        public String modify(@ModelAttribute("user") User user){
            System.out.println("TemplateController.modify"+user);
            return "修改成功";
        }
    }
    

    header.html

        <header th:fragment="head">
            这是页面的头部,导航
        </header>
    

    footer.html

        <!--th:fragment-->
        <header th:fragment="copy">
            这是页面的底部,版权
        </header>
    

    result.html

    <!doctype html>
    <!--导入thymeleaf命名空间-->
    <html lang="en" xmlns:th="http://www.thymeleaf.org">
    <head>
        <meta charset="UTF-8">
        <meta name="viewport"
              content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0">
        <meta http-equiv="X-UA-Compatible" content="ie=edge">
        <title>Document</title>
    </head>
    <body>
    <!--th:text、th:utext-->
        <div th:text="${hello}"></div>
        <div th:utext="${hello}"></div>
    <!--使用内联方式-->
        <div>[[${hello}]]aaa</div>
        <div>[(${hello})]bbb</div>
    <hr>
    <!--th:html-->
        <div id="div1" title="这是一个div" th:id="${id}" th:title="${title}">div</div>
    <!--th:if、th:unless、th:switch、th:case-->
        <p th:if="${age>=16}">成年</p>
        <p th:unless="${age<=16}">成年</p>
        <p th:switch="${role}">
            <span th:case="admin">管理员</span>
            <span th:case="teacher">老师</span>
            <span th:case="student">学生</span>
            <span th:case="*">其他</span>
        </p>
    <!--th:each-->
        <ul>
            <li th:each="name:${names}" th:text="${name}"></li>
            <li th:each="name:${names}" >内联显示[[${name}]]</li>
        </ul>
    <!--th:object、th:field-->
        <hr>
        <h3>修改用户信息</h3>
        <form action="modify" method="post" th:object="${user}">
            编号:<input type="text" th:field="*{id}"><br>
            姓名:<input type="text" th:field="*{name}"><br>
            年龄:<input type="text" th:field="*{age}"><br>
            <input type="submit" value="修改">
        </form>
    
    <!--th:include、th:insert、th:replace-->
        <hr>
        <!--表示引入templates/include/header.html的fragment=head的片段-->
        replace<div th:replace="include/header::head"></div>
        insert<div th:insert="include/footer::copy"></div>
        replace<div th:replace="include/header::head"></div>
    </body>
    </html>
    

    截图展示:

    1550299966542

3.2表达式

  • ${} 变量表达式
    获取对象的属性、方法(EL表达式是不能用的)
    使用内置的基本对象,如session、application等
    使用内置的工具对象,如#strings、#dates、#arrays、#lists、#maps等

  • *{}选择表达式(星号表达式)
    需要和th:object配合使用,简化获取对象的属性

  • @{} url表达式

    <a href="" th:href="@{/findUser(username=${user.name})}">查询指定用户的信息</a>
    

    1550301959071

    可以引入css

    1550302126763

    可以引入js

    <a href="" th:href="@{/findUser(username=${user.name})}">查询指定用户的信息</a>
    

    运算符

    eq gt le == != 三目运算符 等

完整代码:

list.html

<!doctype html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head>
    <meta charset="UTF-8">
    <meta name="viewport"
          content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>Document</title>
    <!--<link rel="stylesheet" th:href="@{/css/style.css}">-->
</head>
<body>
    <!--获取对象的属性和方法-->
    <div th:text="${user.name}"></div>
    <div th:text="${user['age']}"></div>
    <hr>
    <div th:text="${users[1].name}"></div>
    <hr>
    <div th:text="${users.size()}"></div>
    内联:<div>元素个数:[[${users.size()}]]</div>
    <hr>
    <!--使用内置的基本对象-->
    <div th:text="${session.sex}"></div>
    <div th:text="${application.hobby}"></div>
    <hr>
    <!--使用内置的工具对象-->
    <div th:text="${#strings.startsWith(user.name,'o')}"></div>
    <div th:text="${#strings.substring(user.name,2)}"></div>
    <div th:text="${#strings.length(user.name)}"></div>

    <div th:text="${#dates.createNow()}"></div>
    <div th:text="${#dates.create(2019,2,14)}"></div>

    <div th:text="${#dates.format(birthday,'yyyy-MM-dd HH:mm:ss')}"></div>
    <hr>
<!--*{}选择表达式-->
    <!--普通方式-->
    <div th:text="${user.id}"></div>
    <div th:text="${user.name}"></div>
    <div th:text="${user.age}"></div>
    <!--表达式-->
    表达式:
    <div th:object="${user}">
        <div th:text="*{id}"></div>
        <div th:text="*{name}"></div>
        <div th:text="*{age}"></div>
    </div>
    <hr>
<!--@{} url表达式-->
    <!--<script th:src="@{/js/common.js}"></script>-->
    <a href="" th:href="@{/findUser(username=${user.name})}">查询指定用户的信息</a>

<!--运算符-->
    性别:
    <input type="radio" name="sex" value="male" th:checked="${session.sex eq 'male'}">boy
    <input type="radio" name="sex" value="female" th:checked="${session.sex eq 'female'}">girl

    <div th:if="${address==null}">未找到地址信息</div>
    <div th:text="${users.size()>=2?'人员信息大于等于2个':'人员信息小于等于2个'}"></div>
</body>
</html>

TemplateController.java

 @RequestMapping("/test3")
    public String test3(Model model , HttpSession session){
        model.addAttribute("user",new User(1002,"orange",22));
        List<User> users=new ArrayList<>();
        users.add(new User(0,"tom",20));
        users.add(new User(1,"tom1",21));
        users.add(new User(2,"tom2",22));
        model.addAttribute("users",users);

        session.setAttribute("sex","male");
        session.getServletContext().setAttribute("hobby","game");

        model.addAttribute("birthday",new Date());
        return "list";
    }
    @RequestMapping("/findUser")
    @ResponseBody
    public String findUser(String username){
        System.out.println("TemplateController.user");
        return "success";
    }

八、热部署

使用SpringBoot提供的devtools实现热部署
原理:实现监控classpath下文件的变化,如果发生变化则自动重启
配置:添加devtools依赖

<!--热部署-->
		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-devtools</artifactId>
			<version>2.1.3.RELEASE</version>
			<!--该依赖不传递-->
			<optional>true</optional>
		</dependency>

PS:需要完整版笔记,请评论留下邮箱,我看到后回发给你PDF完整版记录~~~

点击查看分版笔记目录:

【SpringBoot】最新版2019Spring Boot快速入门(速成SpringBoot)——学习笔记版解析【1】
【SpringBoot】最新版2019Spring Boot配置解析,源码解析(速成SpringBoot)——学习笔记版【2】
【SpringBoot】最新版2019Spring Boot之WEB开发——Thymeleaf模板引擎速成(速成SpringBoot)——学习笔记版解析【3】
【SpringBoot】最新版2019Spring Boot之MVC功能,异常处理,servlet容器(速成SpringBoot)——学习笔记版解析【4】
【SpringBoot】最新版2019Spring Boot之连接数据库——JDBC,MyBATIS,分页,MyBatis­Plus(速成SpringBoot)——学习笔记版解析【5】

猜你喜欢

转载自blog.csdn.net/OrangeChenZ/article/details/87460069