springboot视图-Thymeleaf 技术

发布于:2025-06-06 ⋅ 阅读:(28) ⋅ 点赞:(0)

视图

页面视图

ModelAndView 是 Spring MVC 中的一个类,用于封装模型数据和视图信息,以便将数据传递给视图模板并渲染页面。它结合了模型数据(Model)和视图信息(View),是 Spring MVC 控制器返回值的一种常见形式。

  1. ModelAndView 的基本用法

ModelAndView 包含两部分:

  • 模型(Model):用于存储传递给视图的数据,通常是一个 Map,键是属性名,值是属性值。
  • 视图(View):用于指定视图的名称或视图解析器的逻辑名称。

示例代码

以下是一个简单的控制器方法,使用 ModelAndView 返回视图和模型数据:

java

复制

import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.servlet.ModelAndView;

@Controller
public class HomeController {

    @GetMapping("/")
    public ModelAndView home() {
        // 创建 ModelAndView 对象
        ModelAndView modelAndView = new ModelAndView();

        // 添加模型数据
        modelAndView.addObject("message", "Hello, Spring MVC!");
        modelAndView.addObject("timestamp", new java.util.Date());

        // 设置视图名称
        modelAndView.setViewName("index");

        return modelAndView;
    }
}

在这个例子中:

  • modelAndView.addObject("message", "Hello, Spring MVC!"); 将一个名为 message 的属性添加到模型中,值为 "Hello, Spring MVC!"
  • modelAndView.setViewName("index"); 指定了视图的名称为 index,Spring MVC 会根据视图解析器的配置找到对应的视图文件(例如 index.htmlindex.jsp)。
  1. 视图解析器

为了使 ModelAndView 能够正确解析视图名称,你需要配置一个视图解析器。Spring Boot 默认使用 Thymeleaf 作为视图模板引擎,但你也可以配置其他视图解析器,如 JSP 或 Freemarker。

默认的 Thymeleaf 视图解析器

如果你使用的是 Thymeleaf,默认情况下,视图文件应该放在 src/main/resources/templates 目录下。例如,index.html 文件的内容可能如下:

HTML

预览

复制

<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
<head>
    <meta charset="UTF-8">
    <title>首页</title>
</head>
<body>
    <h1 th:text="${message}"></h1>
    <p>当前时间:<span th:text="${timestamp}"></span></p>
</body>
</html>

json视图

  • 与之前的一样

。。。

Thymeleaf技术

Thymeleaf 是一个表现层的模板引擎, 一般被使用在 Web 环境中,它可以处理 HTML, XML、 JS 等文档,简单来说,它可以将 JSP 作为 Java Web 应用的表现层,有能力展示与处理数据。Thyme leaf 可以让表现层的界面节点与程序逻辑被共享,这样的设计, 可以让界面设计人员、业务人员与技术人员都参与到项目开发

中。这样,同一个模板文件,既可以使用浏览器直接打开,也可以放到服务器中用来显示数据,并且样式之间基本上不会存在差异,因此界面设计人员与程序设计人员可以使用同一个模板文件,来查看静态与动态数据的效果。

Thymeleaf 作为视图展示模型数据,用于和用户交互操作。JSP 的代替技术。比较适合做管理系统,是一种易于学习,掌握的。我们通过几个示例掌握 Thymeleaf 基础应用

Thymeleaf 是一种现代的模板引擎,用于在 Java 应用程序中生成 HTML、XML、JS、CSS 等内容。它支持服务器端模板渲染,同时也可以在浏览器中直接预览模板。以下是一些常见的 Thymeleaf 用法:

变量表达式

  • 语法th:text="${...}"th:object="${...}"

  • 用途:从模型中获取变量值并显示到页面上。

  • 示例

    HTML

    预览

    复制

    <p th:text="${message}"></p>
    

image-20250604000949089

package com.example.demo1.controller;

import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.GetMapping;

/**
 * @Author: yanyu666_508200729@qq.com
 * @Date 2025/6/4 0:03
 * @description: Thymeleaf表达式
 */
@Controller
public class Demo1 {
    @GetMapping("/demo1")
    public String getDemo1(Model model){
        model.addAttribute("name","yanyu");
        model.addAttribute("addr","东莞");


        return "demo1";
    }



}

image-20250604001038216

image-20250604001045535

Thymeleaf的命名空间

  • 注意

在使用 Thymeleaf 时,xmlns:th="http://www.thymeleaf.org" 是一个非常重要的声明,它用于定义 Thymeleaf 的命名空间。这个声明是必要的,因为它告诉浏览器和模板引擎如何解析和处理模板中的 Thymeleaf 属性。

是否可以省略?

不可以省略。如果不声明 xmlns:th,浏览器和模板引擎将无法识别 Thymeleaf 的属性(如 th:textth:each 等),从而导致模板无法正确解析和渲染。

在上面的案例中,虽然没有报错,最好也不要去省略

示例

以下是一个完整的 HTML 模板示例,展示了如何正确声明 xmlns:th

HTML

预览

复制

<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
<head>
    <title>Thymeleaf Example</title>
</head>
<body>
    <h1 th:text="${message}">Default Message</h1>
    <table>
        <thead>
            <tr>
                <th th:text="#{msgs.headers.name}">Name</th>
                <th th:text="#{msgs.headers.price}">Price</th>
            </tr>
        </thead>
        <tbody>
            <tr th:each="prod: ${allProducts}">
                <td th:text="${prod.name}">Oranges</td>
                <td th:text="${#numbers.formatDecimal(prod.price, 1, 2)}">0.99</td>
            </tr>
        </tbody>
    </table>
</body>
</html>

解释

  • xmlns:th="http://www.thymeleaf.org":声明 Thymeleaf 的命名空间。
  • th:text="${message}":Thymeleaf 属性,用于动态显示变量 message 的值。
  • th:each="prod: ${allProducts}":Thymeleaf 属性,用于遍历集合 allProducts

如果省略会怎样?

如果不声明 xmlns:th,浏览器会将 th:textth:each 等属性视为普通的 HTML 属性,而不是 Thymeleaf 的动态属性。这将导致模板无法正确解析和渲染,例如:

HTML

预览

复制

<!DOCTYPE html>
<html>
<head>
    <title>Thymeleaf Example</title>
</head>
<body>
    <h1 th:text="${message}">Default Message</h1>
    <table>
        <thead>
            <tr>
                <th th:text="#{msgs.headers.name}">Name</th>
                <th th:text="#{msgs.headers.price}">Price</th>
            </tr>
        </thead>
        <tbody>
            <tr th:each="prod: ${allProducts}">
                <td th:text="${prod.name}">Oranges</td>
                <td th:text="${#numbers.formatDecimal(prod.price, 1, 2)}">0.99</td>
            </tr>
        </tbody>
    </table>
</body>
</html>

在这种情况下,页面上会直接显示 th:text="${message}" 等属性,而不是动态内容。

总结

xmlns:th="http://www.thymeleaf.org" 是必须的,它确保 Thymeleaf 属性能够被正确解析和处理。省略这个声明会导致模板无法正确渲染动态内容。

链接表达式

  • 语法th:href="@{...}"th:src="@{...}"

  • 用途:生成动态链接或资源路径。

  • 示例

    HTML

    预览

    复制

    <a th:href="@{http://www.baidu.com}">连接到百度</a> <br/>
    <img th:src="@{/images/logo.png}" alt="Logo">
    
<!DOCTYPE html>
<html lang="en" xmlns:text="http://www.thymeleaf.org">
<head>
    <meta charset="UTF-8">
    <title>读取表达式</title>
</head>
<body>
<div th:text="${name}"></div>
<div th:text="${addr}"></div>
<!--连接到网址-->
<a th:href="@{http://www.baidu.com}">百度</a>
<br>
<a th:href="@{demo2.html}">连接本地资源(无参数)</a>


</body>
</html>
  • 连接互联网资源

image-20250604002527080

image-20250604002533095

  • 连接本地资源

无参数

image-20250604003335833

package com.example.demo1.controller;

import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.GetMapping;

/**
 * @Author: yanyu666_508200729@qq.com
 * @Date 2025/6/4 0:03
 * @description: Thymeleaf表达式
 */
@Controller
public class Demo1 {
    @GetMapping("/demo1")
    public String getDemo1(Model model){
        model.addAttribute("name","yanyu");
        model.addAttribute("addr","东莞");


        return "demo1";
    }
    @GetMapping("/link")
    public String getDemo2(Model model,String name,String age){
        model.addAttribute("name",name);
        model.addAttribute("age",age);
        return "demo2";
    }



}

有参数

<!DOCTYPE html>
<html lang="en" xmlns:text="http://www.thymeleaf.org">
<head>
    <meta charset="UTF-8">
    <title>读取表达式</title>
</head>
<body>
<div th:text="${name}"></div>
<div th:text="${addr}"></div>
<!--连接到网址-->
<a th:href="@{http://www.baidu.com}">百度</a>
<br>
<!--不传递参数-->
<a th:href="@{/link}">连接本地资源(无参数)</a>
<!--传递参数   参数名字  与  对应的控制器一致-->
<a th:href="@{/link(name=烟雨,age=20)}">连接本地资源(有参数)</a>


</body>
</html>
package com.example.demo1.controller;

import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.GetMapping;

/**
 * @Author: yanyu666_508200729@qq.com
 * @Date 2025/6/4 0:03
 * @description: Thymeleaf表达式
 */
@Controller
public class Demo1 {
    @GetMapping("/demo1")
    public String getDemo1(Model model){
        model.addAttribute("name","yanyu");
        model.addAttribute("addr","东莞");


        return "demo1";
    }
    @GetMapping("/link")
    public String getDemo2(Model model,String name,String age){
        model.addAttribute("name",name);
        model.addAttribute("age",age);
        return "demo2";
    }



}

image-20250604003734615

image-20250604003909190

条件表达式

  • if/unless:根据条件判断是否渲染某个元素。

    • 语法th:if="${...}"th:unless="${...}"

    • 示例

      HTML

      预览

      复制

      来自于 模型的 对象,进行判断,不为空,才会执行

      <div th:if="${user != null}">
          <p>Welcome, <span th:text="${user.name}"></span>!</p>
      </div>
      <div th:unless="${user != null}">
          <p>Please log in.</p>
      </div>
      
      

th:each

th:each 是 Thymeleaf 中用于循环遍历集合(如列表、数组等)的表达式。它允许你对集合中的每个元素进行迭代,并在每次迭代中生成相应的 HTML 元素。以下是对 th:each 的详细介绍,包括其语法、用法和一些高级特性。

基本语法

HTML

预览

复制

<div th:each="variable : ${collection}">
    <!-- 循环体 -->
</div>
  • variable:每次迭代时,当前元素的变量名。
  • ${collection}:需要遍历的集合对象(如 ListSet、数组等)。

基本用法

假设你有一个用户列表 List<User>,每个用户有 nameemail 属性,你可以使用 th:each 来遍历并显示每个用户的信息。

示例代码

HTML

预览

复制

<table>
    <thead>
        <tr>
            <th>Name</th>
            <th>Email</th>
        </tr>
    </thead>
    <tbody>
        <tr th:each="user : ${users}">
            <td th:text="${user.name}"></td>
            <td th:text="${user.email}"></td>
        </tr>
    </tbody>
</table>

输出结果

如果 users 集合中有以下数据:

java

复制

[
    {name="Alice", email="alice@example.com"},
    {name="Bob", email="bob@example.com"}
]

生成的 HTML 将是:

HTML

预览

复制

<table>
    <thead>
        <tr>
            <th>Name</th>
            <th>Email</th>
        </tr>
    </thead>
    <tbody>
        <tr>
            <td>Alice</td>
            <td>alice@example.com</td>
        </tr>
        <tr>
            <td>Bob</td>
            <td>bob@example.com</td>
        </tr>
    </tbody>
</table>

案例

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>首页</title>
</head>
<body>
<a href="/demo1">表达式</a>
<br>
<a href="/demo2">遍历集合</a>

</body>
</html>
package com.example.demo1.vo;

import java.util.Objects;

/**
 * @Author: yanyu666_508200729@qq.com
 * @Date 2025/6/4 0:55
 * @description:
 */
public class User {
    String name;
    String age;

    @Override
    public String toString() {
        return "User{" +
                "name='" + name + '\'' +
                ", age='" + age + '\'' +
                '}';
    }

    @Override
    public boolean equals(Object o) {
        if (this == o) return true;
        if (o == null || getClass() != o.getClass()) return false;
        User user = (User) o;
        return Objects.equals(name, user.name) && Objects.equals(age, user.age);
    }

    @Override
    public int hashCode() {
        return Objects.hash(name, age);
    }

    public String getName() {
        return name;
    }

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

    public String getAge() {
        return age;
    }

    public void setAge(String age) {
        this.age = age;
    }

    public User(String name, String age) {
        this.name = name;
        this.age = age;
    }

    public User() {
    }
}

package com.example.demo1.controller;

import com.example.demo1.vo.User;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.GetMapping;

import java.util.Arrays;
import java.util.List;

/**
 * @Author: yanyu666_508200729@qq.com
 * @Date 2025/6/4 0:28
 * @description:
 */
@Controller
public class Demo2 {

    @GetMapping("/demo2")
    public String getDemo2(Model model){
/*Arrays.asList 是 Java 中的一个非常实用的方法,用于将数组快速转换
为一个固定大小的 List。它属于 java.util.Arrays 类,通常用于创建一个
简单的列表,而无需显式地初始化一个 ArrayList 或其他类型的 List。
* */
        List<User> users = Arrays.asList(
                new User("yanyu1","20"),
                new User("yanyu2","22")
        );
        model.addAttribute("users",users);
//        将  集合添加到模型
        return "user";
    }




}

<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head>
    <meta charset="UTF-8">
    <title>用户列表</title>
</head>
<body>
    <table border="1px">
        <tr>
            <td>姓名</td>
            <td>年龄</td>
        </tr>
        <tr th:each="user:${users}">
<!--            以读取变量的形式读取集合
                拿到实体类的对象后,读取实体类的属性
-->
            <td th:text="${user.name}"></td>
            <td th:text="${user.age}"></td>

        </tr>
    </table>
</body>
</html>