4-Spring Boot 的视图(Thymeleaf)

一、概述Thymeleaf

Spring Boot可整合的模板引擎技术:1. FreeMarker 2. Groovy 3. Thymeleaf 4. Mustach

1、什么是Thymeleaf

Thymeleaf是一种现代的基于服务器端的java模板引擎技术,也是一个优秀的面向java的xml、xhtml、html5页面模板,它具有丰富的标签语言、函数和表达式,在使用springboot框架进行页面设计时,一般会选择Thymeleaf模版。

2、优点

① 界面设计人员和程序设计人员可以共享同一套页面

比如下面一段含有Thymeleaf语句的HTML代码:

<p th:text="#{hello}">欢迎进入Thymeleaf的学习</p>

界面设计人员将看到(静态展示):欢迎进入Thymeleaf的学习

程序设计人员将看到(动态展示):如果变量hello的值为“hello world!”,那么展示为hello world!

从结果看,只是内容的变化,样式不变,所以可以共享同一套页面

3、处理模板模式

①HTML

        不严格要求html标签完整,比如:<input ......>,结尾缺少“/”没事。

②XML

        要求XML格式完整,但不检查内容是否符合某种规范,比如dtd

③TEXT

④JAVASCRIPT

⑤RAW:原型,不处理模板

4、模板引擎的作用

TemplateEngine将含有逻辑的代码转换成纯输出,看下面的案例去理解

二、Thymeleaf能实现什么功能

创建Springboot项目,在pom.xml中添加如下坐标(即引入Thymeleaf依赖)

        <dependency>
            <groupId>org.thymeleaf</groupId>
            <artifactId>thymeleaf</artifactId>
        </dependency>

1、处理html

①创建测试类ThymeleafTest

public class ThymeleafTest {
	@Test
	public void testHtml() {
		TemplateEngine templateEngine = new TemplateEngine();
        Context ctx = new Context();
        ctx.setVariable("hello", "hello world");
        String result = templateEngine.process(
        		"<p th:text='${hello}'> 欢迎进入Thymeleaf的学习 </p>", 
                ctx);
        System.out.println(result);
	}
}

②输出如下:

<p>hello world</p>

结论:TemplateEngine能把含有逻辑的代码转换成纯html输出。

2、更换模板解析器,处理xml

默认模板处理模式是html,通过更换模板解析器,处理其他格式的模板,例如xml

    @Test
	public void testXML() {
		TemplateEngine templateEngine = new TemplateEngine();
        // 新建模板解析器
        StringTemplateResolver resolver = new StringTemplateResolver();
        // 设置模板模式为XML
        resolver.setTemplateMode(TemplateMode.XML);
        // 将解析器设置到引擎实例中
        templateEngine.setTemplateResolver(resolver);
        Context ctx = new Context();
        // 处理一段含有Thymeleaf逻辑的XML语句
        String result = templateEngine.process(
                "<bean id=\"myBean\" th:attr='class=org.crazyi.Test'></bean>",
                ctx);
        System.out.println(result);
	}

输出结果:<bean id="myBean" class="org.crazyi.Test"></bean>

3、处理资源文件(例如:xx.html)

①在resources下创建index.html

<input type="text" th:value="angus"/>

②创建测试方法

    @Test
	public void testClassLoader() {
		TemplateEngine templateEngine = new TemplateEngine();
        // 创建解析器
        ClassLoaderTemplateResolver resolver = new ClassLoaderTemplateResolver();
        // 设置到模板引擎中
        templateEngine.setTemplateResolver(resolver);
        // 处理classpath下的 index.html文件
        String result = templateEngine.process("index.html", new Context());
        System.out.println(result);
	}

输出:<input type="text" value="angus"/>

4、处理变量(这里变量名为data)

①创建资源文件var.html

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

②创建DataObject类,存放数据

public class DataObject {

    private String name;

    public DataObject(String name) {
        super();
        this.name = name;
    }

    public DataObject() {
        super();
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }
    
}

③创建测试方法

    @Test
	public void testVar() {
		TemplateEngine templateEngine = new TemplateEngine();
        ClassLoaderTemplateResolver resolver = new ClassLoaderTemplateResolver();
        templateEngine.setTemplateResolver(resolver);
        // 设置参数到Context中
        Context ctx = new Context();
        ctx.setVariable("data", new DataObject("angus"));
        String result = templateEngine.process("var.html", ctx);
        System.out.println(result);
	}

输出:<input type="text" value="angus"/>

5、遍历集合

①创建资源文件iteration.html

<table>
    <tr th:each="data : ${datas}">
        <td th:text="${data.name}">Angus</td>
    </tr>
</table>

②创建测试方法

    @Test
	public void testIteration() {
		TemplateEngine templateEngine = new TemplateEngine();
        // 创建解析器
        ClassLoaderTemplateResolver resolver = new ClassLoaderTemplateResolver();
        // 设置到模板引擎中
        templateEngine.setTemplateResolver(resolver);
        // 设置集合数据
        List<DataObject> datas = new ArrayList<DataObject>();
        datas.add(new DataObject("a"));
        datas.add(new DataObject("b"));
        Context ctx = new Context();
        ctx.setVariable("datas", datas);
        // 处理classpath下的 index.html文件
        String result = templateEngine.process("iteration.html", ctx);
        System.out.println(result);
	}

 输出:

<table>
    <tr>
        <td>a</td>
    </tr>
    <tr>
        <td>b</td>
    </tr>
</table>

6、设置前缀和后缀

①在resources下创建templates文件夹,并创建index.html

<span th:text="hello"></span>

②创建测试方法

    @Test
	public void testFix() {
		TemplateEngine templateEngine = new TemplateEngine();
        // 设置前缀与后缀
        ClassLoaderTemplateResolver resolover = new ClassLoaderTemplateResolver();
        resolover.setPrefix("/templates/");
        resolover.setSuffix(".html");
        templateEngine.setTemplateResolver(resolover);
        // 处理 /templates/index.html,前缀+模板名称+后缀
        String result = templateEngine.process("index", new Context());
        System.out.println(result);
	}

输出:<span>hello</span>

三、Thymeleaf基本语法

1、常用标签 

示例:

<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">

    <head>
        <meta charset="UTF-8">
        <link rel="stylesheet" type="text/css" media="all"
          href="../../css/gtvg.css" th:href="@{/css/gtvg.css}" />
        <title>Title</title>
    </head>

    <body>
        <p th:text="#{hello}">欢迎进入Thymeleaf的学习</p>
    </body>

</html>

2、标准表达式

说明

表达式语法

变量表达式

获取上下文中的变量值

${...}

选择变量表达式

用于从被选定对象获取属性值

*{...}

消息表达式

用于Thymeleaf模板页面国际化内容的动态替换和展示

#{...}

链接URL表达式

用于页面跳转或者资源的引入

@{...}

片段表达式

用来标记一个片段模板,并根据需要移动或传递给其他模板

~{...}

3、Thymeleaf内置对象

Thymeleaf为变量所在域提供了一些内置对象,如下

  • #ctx:上下文对象
  • #vars:上下文变量
  • #locale:上下文区域设置
  • #request:(仅限Web Context)HttpServletRequest对象
  • #response:(仅限Web Context)HttpServletResponse对象
  • #session:(仅限Web Context)HttpSession对象
  • #servletContext:(仅限Web Context)ServletContext对象

四、Spring Boot 中的静态资源的访问路径

1、Spring Boot默认将/**所有访问映射到以下目录:

  • classpath:/META-INF/resources/:项目类路径下的META-INF文件夹下         的resources文件夹下的所有文件。
  • classpath:/public/:项目类路径下的public文件夹下的所有文件。
  • classpath:/resources/:项目类路径下的resources文件夹下的所有文件。
  • classpath:/static/:项目类路径下的static文件夹下的所有文件。

Springboot默认依次从classpath:/META-INF/resources 、classpath:/resources/ 、classpath:/static/ 、classpath:/public/里面查找静态资源。

这个查找顺序可以通过源码查看:WebMvcAutoConfiguration--》搜索getStaticLocations--》进入该方法--》寻着轨迹就能找到

2、修改静态资源存放位置:

spring.resources.static-locations=字符串数组

五、springboot整合Thymeleaf 完成数据的页面展示

1、创建Spring Boot项目,引入Thymeleaf依赖和Web场景依赖

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

2、在全局配置文件中增加如下配置

#如设置模板缓存、模板编码、模板样式、指定模板页面存放路径、指定模板页面名称的后缀

#thymeleaf页面缓存设置(默认为true),开发中关闭缓存(false),数据改变时及时响应,上线稳定后打开缓存(true)
spring.thymeleaf.cache = false
spring.thymeleaf.encoding = UTF-8
spring.thymeleaf.mode = HTML
#默认值,模板页面存放路径
spring.thymeleaf.prefix = classpath:/templates/
#默认值,模板页面名称的后缀
spring.thymeleaf.suffix = .html
#如果下面的配置生效,那么访问路径加上项目名
#server.servlet.context-path=/my04
#拼接地址  classpath:/templates/login.html

3、创建控制类:@Controller

创建一个用于前端模板页面动态数据替换效果测试的访问实体类LoginController

注意:返回值不能是void,否则访问路径(即toLoginPage)被当成模板名称

@Controller
public class LoginController {

    @GetMapping("/toLoginPage")
    public String toLoginPage(Model model){

        model.addAttribute("currentYear", Calendar.getInstance().get(Calendar.YEAR));
        return "login";

    }

}

4、创建模板页面并引入静态资源文件

项目结构图

下载静态资源文件https://download.csdn.net/download/daqi1983/89029598

创建一个用户登录的模板页面login.html

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

    <head>
        <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
        <meta name="viewport" content="width=device-width, initial-scale=1,shrink-to-fit=no">
        <title>用户登录界面</title>
        <link th:href="@{/login/css/bootstrap.min.css}" rel="stylesheet">
        <link th:href="@{/login/css/signin.css}" rel="stylesheet">
    </head>

    <!-- 在body标签中通过th:text引入了后台动态传递过来的当前年份currentYear -->
    <body class="text-center">
        <!--  用户登录form表单 -->
        <form class="form-signin">
            <img class="mb-4" th:src="@{/login/img/login.jpg}" width="72" height="72">
            <h1 class="h3 mb-3 font-weight-normal">请登录</h1>
            <input type="text" class="form-control"
           th:placeholder="用户名" required="" autofocus="">
            <input type="password" class="form-control"
           th:placeholder="密码" required="">
            <div class="checkbox mb-3">
                <label>
                    <input type="checkbox" value="remember-me"> 记住我
                </label>
            </div>
            <button class="btn btn-lg btn-primary btn-block" type="submit">登录</button>
            <p class="mt-5 mb-3 text-muted">© <span th:text="${currentYear}">2018</span>-<span th:text="${currentYear}+1">2019</span></p>
        </form>
    </body>
</html>

5、效果测试

启动项目进行测试,在浏览器上访问http://localhost:8080/toLoginPage,在页面底部动态显示了当前日期2019-2020,而不是文件中的静态数字2018-2019

六、Thymeleaf国际化页面

1、编写多语言国际化文件以及配置文件

springboot 默认识别的语言配置文件为resources下的messages.properties、messages_语言代码_国家代码.properties。

这里我们使用自定义的语言配置文件,格式:文件前缀名. properties、文件前缀名_语言代码_国家代码.properties,并放在resources下的i18n文件夹下:

login.properties、login_zh_CN.properties

login.tip=请登录
login.username=用户名
login.password=密码
login.rememberme=记住我
login.button=登录

login_en_US.properties

login.tip=Please sign in
login.username=Username
login.password=Password
login.rememberme=Remember me
login.button=Login

2、编写配置文件

由于是自定义语言配置文件,所以要配置国际化文件基础名

spring.messages.basename=i18n.login

3、定制区域信息解析器

由于我们是根据点击页面的超链接形成的请求参数手动切换语言,所以需要定制区域信息解析器。默认是根据请求头的accept-language的语言信息来选择对应的语言配置文件完成自动切换语言

建子包config,自定义区域信息解析器配置类

@Configuration
public class MyLocalResolver implements LocaleResolver {
    // 自定义区域解析方式
    @Override
    public Locale resolveLocale(HttpServletRequest httpServletRequest) {
        // 获取页面手动切换传递的语言参数l
        String l = httpServletRequest.getParameter("l");
        // 获取请求头自动传递的语言参数Accept-Language
        String header = httpServletRequest.getHeader("Accept-Language");
        Locale locale=null;
        // 如果手动切换参数不为空,就根据手动参数进行语言切换,否则默认根据请求头信息切换
        if(!StringUtils.isEmpty(l)){
            String[] split = l.split("_");
            locale=new Locale(split[0],split[1]);
        }else {
            // Accept-Language: en-US,en;q=0.9,zh-CN;q=0.8,zh;q=0.7
            String[] splits = header.split(",");
            String[] split = splits[0].split("-");
            locale=new Locale(split[0],split[1]);
        }
        return locale;
    }

    @Override
    public void setLocale(HttpServletRequest httpServletRequest, @Nullable
            HttpServletResponse httpServletResponse, @Nullable Locale locale) {

    }

    // 将自定义的MyLocalResovel类重新注册为一个类型LocaleResolver的Bean组件,能覆盖默认的解析器
    @Bean
    public LocaleResolver localeResolver(){
        return new MyLocalResolve();
    }
}

4、页面国际化使用

用户登录页面login.html结合Thymeleaf模板引擎实现国际化功能,核心代码如下

​
<h1 class="h3 mb-3 font-weight-normal" th:text="#{login.tip}">请登录</h1>
<input type="text" class="form-control"
                  th:placeholder="#{login.username}" required="" autofocus="">

<input type="password" class="form-control"
                  th:placeholder="#{login.password}" required="">

<div class="checkbox mb-3">
    <label>
        <input type="checkbox" value="remember-me">[[#{login.rememberme}]]
    </label>
</div>

<button class="btn btn-lg btn-primary btn-block" type="submit"
                               th:text="#{login.button}">登录</button>

<p class="mt-5 mb-3 text-muted">© <span th:text="${currentYear}">2018</span>

                                  -<span th:text="${currentYear}+1">2019</span></p>

<a class="btn btn-sm" th:href="@{/toLoginPage(l='zh_CN')}">中文</a>

<a class="btn btn-sm" th:href="@{/toLoginPage(l='en_US')}">English</a>

<!--[[#{login.rememberme}]]行内表达式  用于标签外部数据的展示-->

​

5.整合效果测试

①启动项目进行效果测试,在浏览器上访问http://localhost:8080/toLoginPage

乱码:设置属性文件的编码为utf-8

②以火狐浏览器为例,设置语言为美国英语

这时再去访问登录页面时,就变成英文显示了

③如果点击页面的English,也会以英文显示

定制应用程序错误页面

作业:

springboot整合redis和thymeleaf,在浏览器端显示张有才的信息

  • 4
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值