当前位置:   article > 正文

Spring MVC集成Thymeleaf实现前后端分离:简化视图层开发_如何实现springmvc前后端分离

如何实现springmvc前后端分离

一、引言

1. 前后端分离的意义

前后端分离是Web开发中的一种重要架构模式。它将前端和后端的开发分离,使得前端专注于UI设计和展示逻辑,而后端则专注于业务逻辑实现。这种架构模式带来的好处包括:

  • 增强开发效率
  • 满足多终端设备的适配需求
  • 提高前后端代码的可维护性

2. Thymeleaf的简介

Thymeleaf是一种流行的Java服务器端模板引擎。它可以将HTML模板和动态数据进行结合,生成最终的HTML页面。相比于其他模板引擎,Thymeleaf有许多优点,如:

  • 强大的表达式能力
  • 丰富的内嵌模板功能
  • 良好的可读性和易维护性

3. Spring MVC与Thymeleaf的集成方式

Spring MVC是一种常用的Java Web框架,它也支持使用Thymeleaf进行前后端分离开发。Spring MVC提供了Spring Boot等辅助工具,可以方便地集成Thymeleaf,同时利用Spring MVC的模型-视图-控制器(MVC)架构模式,可以更加清晰地组织代码。

二、前后端分离的实现方式

1. 前后端分离的概念

前后端分离是一种架构模式,它将前端和后端的开发分离,前端负责UI的设计和界面交互,后端负责业务逻辑实现和数据处理。前后端分离能够提高团队的开发效率和代码的可维护性,也能更好地满足多终端设备的适配需求。

2. 前后端分离的优势

前后端分离的优势主要体现在以下几个方面:

  • 提高开发效率
  • 提高代码重用率与可维护性
  • 将横跨前后端的任务分解,方便团队协作
  • 更好地应对多终端设备的适配需求

3. 前端框架的选择

前端框架的选择主要考虑以下几个因素:

  • 目标浏览器类型和设备特性
  • 开发团队技术栈与技能水平
  • 开源社区资料和使用广泛程度
  • 框架生态和功能扩展

此外还需要考虑框架的成熟度和稳定性等因素。

三、Thymeleaf的简介

1. Thymeleaf的优势

Thymeleaf是一个流行的模板引擎优点如下:

  • 支持HTML、XML、JavaScript、CSS等多种文件类型
  • 可以在浏览器中预览和缓存模板
  • 支持模板布局和抽象,方便复用
  • 强大的表达式能力和逻辑处理能力
  • 易于集成Spring MVC等框架,使用方便

2. Thymeleaf的语法

Thymeleaf的语法包括一系列属性和标签其中最常用的有th:text、th:if、th:each等。例如,下面是一个使用Thymeleaf渲染用户列表的代码:

<table>
    <tr th:each="user : ${users}">
        <td th:text="${user.id}"></td>
        <td th:text="${user.name}"></td>
        <td th:text="${user.age}"></td>
    </tr>
</table>
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7

该代码中th:each表示遍历users列表,每次将列表中的元素赋值给user变量。在tr标签中使用了user变量,输出了用户的id、name和age信息。

3. Thymeleaf的模板渲染方式

Thymeleaf的模板渲染方式包括两种:模板缓存和模板实时解析。前者适用于生产环境,可以提高模板加载速度,后者适用于开发环境,可以方便地进行调试和修改。

下面是一个使用Thymeleaf的控制器代码示例其中使用了模板缓存的方式:

@Controller
public class UserController {

    @Autowired
    private UserService userService;

    @GetMapping("/users")
    public String list(Model model) {
        List<User> users = userService.findAll();
        model.addAttribute("users", users);
        return "user/list"; // 返回模板名称
    }
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13

在UserController中使用了UserService查询了用户列表,将数据添加到Model中,然后返回模板名称。

四、Spring MVC 与 Thymeleaf 的集成方式

1. Spring MVC 与 Thymeleaf 的环境搭建

首先需要确保已安装好 Java 和 Maven 等必要的开发环境。

接下来需要在项目中引入 Spring Boot 和 Thymeleaf 相关的依赖库。可以在 pom.xml 文件中添加如下代码:

<dependencies>
    <!-- ... 其他依赖 ... -->
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-thymeleaf</artifactId>
    </dependency>
</dependencies>
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7

这样项目就会自动下载并添加 Spring Boot 和 Thymeleaf 的依赖库。

2. Thymeleaf 的配置方式

在 Spring Boot 项目中Thymeleaf 是默认集成的,无需进行额外的配置。如果需要自定义 Thymeleaf 的配置,可以在 application.properties 中添加相关配置项,例如:

spring.thymeleaf.cache=false      # 禁用模板缓存
spring.thymeleaf.encoding=UTF-8  # 设置编码为 UTF-8
  • 1
  • 2

3. Thymeleaf 的使用方法

  • 在 Spring MVC 中使用 Thymeleaf

Thymeleaf 与 Spring MVC 是天然相互兼容的。通过在控制器方法上添加注解 @GetMapping、@PostMapping 等,Spring MVC 可以自动将其返回值渲染成 Thymeleaf 模板。

例如,我们定义了一个 UserController其中的 list 方法返回用户对象列表,并指示 Spring MVC 使用 Thymeleaf 渲染模板:

@Controller
public class UserController {

    @Autowired
    private UserService userService;

    @GetMapping("/users")
    public String list(Model model) {
        List<User> users = userService.getUsers();
        model.addAttribute("users", users);
        return "user/list"; // 使用模板名称作为返回结果
    }
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13

通过在模板文件中使用 Thymeleaf 的表达式可以将 Java 对象的数据渲染到 HTML 页面上。例如下面的用户列表模板中,利用 Thymeleaf 的循环语句和表达式,生成了一个用户列表:

<table>
  <thead>
    <tr>
      <th>编号</th>
      <th>姓名</th>
      <th>操作</th>
    </tr>
  </thead>
  <tbody>
    <!-- 在<tbody>标签中使用Thymeleaf的each语句输出用户列表 -->
    <tr th:each="user : ${users}">
      <!-- 输出用户编号 -->
      <td th:text="${user.id}"></td>
      <!-- 输出用户姓名 -->
      <td th:text="${user.name}"></td>
      <!-- 输出用户操作 -->
      <td>
        <a th:href="@{'/users/'+${user.id}+'/edit'}">编辑</a>
        <a th:href="@{'/users/'+${user.id}+'/delete'}">删除</a>
      </td>
    </tr>
  </tbody>
</table>
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • Thymeleaf 的内置对象

在 Thymeleaf 中有一些预定义的对象常用于处理常规任务,如设置变量、执行算术和比较操作等。

以下是常用的预定义对象:

对象名描述
#object当前对象(通常是迭代对象)
#strings字符串操作
#lists列表操作
#sets集合操作
#arrays数组操作
#dates日期和时间操作
#calendars日历操作
#numbers数学运算
#bools布尔值运算
#messages文本国际化(i18n)
#method调用方法
#fields访问对象的字段
#selections选择列表
#aggregates聚合操作
#authentication认证和授权操作
#authorization授权操作
#sessionSession 操作
#servletContextServlet 上下文操作
#requestHTTP 请求操作
#responseHTTP 响应操作
#httpServletRequestHttpServletRequest
#httpSessionHttpSession
#servletContextServletContext
#requestParametersHTTP 请求参数(即变量,如 ?name=Thymeleaf)
#requestParametersMapHTTP 请求参数的 Map 对象
#sessionVariablesSession 属性
#requestURI请求 URI(不包含查询参数)
#requestURL请求 URL(不包括 Scheme 和 Authority)
#baseURI基础 URI(相对于当前请求的上下文路径)
#locale当前区域设置
#dates日期和时间操作
#temporals日期、时间和Temporals操作
#calendars日历操作
#files处理文件上传
  • 在 Thymeleaf 中使用 Ajax 和 Thymeleaf 的集成方式

利用 AJAX 和 Thymeleaf 实现数据的增量渲染是非常常见的需求。

在 Thymeleaf 中利用 Thymeleaf 的内置属性 th:onclick、th:attr 等属性,可以轻松构建 Ajax 请求,并将其与后端进行数据交互。

例如下面的代码演示了如何利用 Thymeleaf 的 onclick 属性,实现按钮点击时向后端发送 Ajax 请求,并将返回值渲染到 HTML 页面上:

<button type="button"
  th:onclick="'$.get('/ajax/person/'+${person.id}, function(data){$(\'#person-view\').html(data)})'">
  查看详细信息
</button>

<!-- 页面上某处的容器,用于显示返回数据 -->
<div id="person-view"></div>
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7

其中,${person.id} 是当前前端的上下文环境中传递的值。此外需要使用 jQuery 或其他 JavaScript 库来发送 Ajax 请求。

五、视图层开发的简化

在 Web 开发中视图层是用户与系统直接交互的界面,必须具备清晰、友好的页面布局、强大、易用的交互功能。今天,我将为大家介绍如何使用 Thymeleaf 来简化视图层的开发。

1. Thymeleaf 的模板布局

在使用 Thymeleaf 进行页面开发时为了提高代码的复用性和减少冗余代码,我们可以使用 Thymeleaf 的布局语法来定义页面的模板。

首先需要在布局文件中定义公共的 HTML 结构,然后在需要使用的页面中使用特殊的标签引入布局。

例如,我们可以在 layout.html 文件中定义公共的 HTML 结构:

<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
<head>
    <meta charset="UTF-8">
    <title th:text="${title}"></title>
</head>
<body>
    <div th:fragment="nav">
        <!-- 定义公共的导航栏 -->
    </div>
    
    <!-- 页面主要内容 -->
    <div th:fragment="content">
        <p>这里是页面的主要内容。</p>
    </div>
    
    <!-- 公共的页脚部分 -->
    <div th:fragment="footer">
        &copy; 2022 My Website
    </div>
</body>
</html>
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22

然后在需要使用该布局的页面中通过 layout:decorate 标签引入布局:

<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org"
      xmlns:layout="http://www.ultraq.net.nz/thymeleaf/layout">
<head>
    <meta charset="UTF-8">
    <title>首页</title>
    <!-- 引入布局文件 -->
    <layout:decorate layout:decorator="layout">
        <!-- 定义标题 -->
        <layout:fragment name="title">
            首页
        </layout:fragment>
    
        <!-- 引入导航栏 -->
        <layout:fragment name="nav" th:replace="fragments/nav :: nav"/>
    
        <!-- 定义首页内容 -->
        <layout:fragment name="content">
            <h1>Hello World!</h1>
        </layout:fragment>
    
        <!-- 引入页脚 -->
        <layout:fragment name="footer" th:replace="fragments/footer :: footer"/>
    </layout:decorate>
</head>
<body>
    
</body>
</html>
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29

其中,layout:decorate 标签通过 layout:decorator 属性指定布局文件的路径,而 layout:fragment 标签则通过 name 属性指定所要填充的区域。

2. Thymeleaf 的复用模板片段

在 Web 应用程序中需要对页面的不同部分进行复用,例如页头、页脚、导航栏等

在 Thymeleaf 中可以通过 th:replaceth:insert 属性来引用其它模板片段,实现代码的复用。

例如,我们可以在 nav.html 文件中定义一个公共的导航栏:

<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
<head>
    <meta charset="utf-8">
    <title>导航栏</title>
</head>
<body>
    <div th:fragment="nav">
        <nav>
            <a href="/">首页</a>
            <a href="/about">关于我们</a>
            <a href="/contact">联系我们</a>
        </nav>
    </div>
</body>
</html>
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16

然后在需要使用导航栏的页面中可以通过 th:replaceth:insert 属性来引用该模板片段:

<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
<head>
    <meta charset="utf-8">
    <title>首页</title>
</head>
<body>
    <header th:replace="fragments/nav :: nav"></header>
    <h1>Hello World!</h1>
</body>
</html>
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11

如果需要在页面中动态生成导航内容可以通过 th:each 做到:

<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
<head>
    <meta charset="utf-8">
    <title>首页</title>
</head>
<body>
    <header th:replace="fragments/nav :: nav">
        <nav>
            <a th:each="page : ${pages}" th:href="@{${page.url}}">
                <span th:text="${page.name}"></span>
            </a>
        </nav>
    </header>
    <!-- 页面主要内容 -->
    <div th:text="${content}"></div>
    <!-- 引入页脚 -->
    <div th:replace="footer :: footer"></div>
</body>
</html>
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20

3. Thymeleaf 的表单验证

在表单数据提交时一般需要对表单数据进行验证,以保证数据的准确性。

在 Thymeleaf 中可以通过 th:fieldth:error 属性来实现表单数据的验证。

例如,我们可以在表单中添加 th:field 属性来指定表单元素的名称和类型,并在下方添加 th:error 属性来显示错误信息:

<!-- HTML 表单元素 -->
<form method="POST" action="/users" th:object="${user}">
    <input type="text" th:field="*{username}" placeholder="用户名">
    <input type="password" th:field="*{password}" placeholder="密码">
    <input type="password" th:field="*{confirmPassword}" placeholder="确认密码">
    <button type="submit">注册</button>
    <!-- 显示错误信息 -->
    <p th:if="${#fields.hasErrors('username')}" th:errors="*{username}"></p>
    <p th:if="${#fields.hasErrors('password')}" th:errors="*{password}"></p>
    <p th:if="${#fields.hasErrors('confirmPassword')}" th:errors="*{confirmPassword}"></p>
</form>
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11

其中,th:object 属性指定了表单数据绑定的对象,而 *{fieldName} 语法则表示指定该表单元素的名称和类型。

在控制器中可以使用 @ValidBindingResult 注解对表单数据进行验证:

@PostMapping("/users")
public String register(@Valid @ModelAttribute User user, BindingResult result) {
    if (result.hasErrors()) {
        return "user/register";
    }
    userService.saveUser(user);
    return "redirect:/";
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8

4. Thymeleaf 的国际化配置

国际化是指在不同的语言环境下,选择合适的语言资源来实现文本翻译、本地化等功能。在 Thymeleaf 中,可以通过 th:text 属性和 Properties 文件实现国际化。

在模板中可以使用 th:text 属性来指定一个表达式和默认值。例如:

<p th:text="#{welcome.message}">欢迎使用我们的系统!</p>
  • 1

其中#{...} 表示表达式,${...} 表示变量。

然后在 messages.properties 文件中,定义所需的语言资源:

welcome.message=Welcome to our system!
  • 1

当系统当前的 Locale 与 “messages.properties” 文件中的 Locale 相同时,th:text 属性将显示对应的语言资源。如果当前 Locale 没有匹配的语言资源,则显示默认值 “欢迎使用我们的系统!”。

如果需要支持多语言可以创建不同的国际化文件。例如,针对英文和中文分别定义 messages_en.propertiesmessages_zh.properties

# messages_en.properties
welcome.message=Welcome to our system!

# messages_zh.properties
welcome.message=欢迎使用我们的系统!
  • 1
  • 2
  • 3
  • 4
  • 5

这样在不同的语言环境中使用页面时,Thymeleaf 会自动选择适合的语言资源。

六、Thymeleaf在前后端分离开发中的实践

随着前端技术的不断发展和不断涌现出来的前端框架,越来越多的开发者开始采用前后端分离的开发模式。前后端分离有很多显著的优势,比如可以提高开发效率、降低耦合度、方便团队合作等等。那么,在前后端分离开发中,如何使用 Thymeleaf 进行渲染呢?

1 前后端分离的细节问题

从前到后整个项目的开发过程中充满了细节问题,所以在前后端分离开发中,开发者必须更加关注这些细节问题,以确保整个项目顺利地进行。

下面列出一些前后端分离开发中的细节问题及其解决方案:

1.1 跨域问题

由于前后端分离的结构,前端和后端服务器可能不在同一个域名下,因此可能会涉及到跨域问题。解决跨域问题可以在后端代码中添加跨域配置,或者使用前端框架内置的跨域解决方案。

1.2 前端模板的组织与管理

在前后端分离开发中,前端通常采用MVVM架构模式。此时,HTML页面仅作为静态的模板来进行编写和管理,而动态数据由前端通过Ajax请求获取。因此,前端需要选择一个合适的模板引擎,比如 Vue、AngularJS、React 等等,来进行模板的管理与渲染。

1.3 RESTful API的设计

在前后端分离开发中前端需要通过 RESTful API 来与后端进行数据交互。因此RESTful API 的设计必须合理,要符合规范,具有可读性和可维护性。

1.4 数据传输格式的选择

在前后端分离开发中前端需要通过RESTful API来获取数据,因此数据传输格式的选择非常重要。通常情况下可以选择 JSON 或 XML 格式进行数据的传输。

2 Thymeleaf的开发注意事项

Thymeleaf 是一款优秀的模板引擎可以方便快捷地进行 HTML 页面的渲染,也可以轻松地与 Spring 框架集成。在使用 Thymeleaf 进行前后端分离开发时,需要注意以下几点:

2.1 定义 HTML 页面

在前后端分离开发中HTML 页面仅作为静态的模板来进行编写和管理,而动态数据则由前端框架通过 Ajax 异步获取。因此在编写 HTML 页面时,需要特别注意页面的结构和布局,以便于前端框架进行数据的插入和渲染。

2.2 使用 Thymeleaf 的语法

在 HTML 页面中可以使用 Thymeleaf 的语法,比如表达式语言、迭代器等来动态渲染页面。例如:

<tr th:each="user : ${users}">
    <td th:text="${user.id}"></td>
    <td th:text="${user.username}"></td>
    <td th:text="${user.nickname}"></td>
    <td><a th:href="@{/users/{id}/edit(id=${user.id})}">编辑</a></td>
    <td><a th:href="@{/users/{id}/delete(id=${user.id})}">删除</a></td>
</tr>
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7

2.3 与 Ajax 请求配合使用

在前后端分离开发中前端通常采用 Ajax 技术来与后端进行数据交互。使用 Thymeleaf 时可以将 Ajax 请求的返回结果渲染到指定的 HTML 块中。例如:

<div id="result"></div>

<script>
    $.ajax({
        url: '/user',
        success: function (data) {
            $('#result').html(data);
        }
    });
</script>
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10

2.4 跳转页面与状态码

在前后端分离开发中,跳转页面和响应状态码通常由前端框架来处理。因此在使用 Thymeleaf 进行页面跳转和状态码返回时,需要与前端框架配合,以保证前端界面正确地进行渲染和跳转。

3 开发中的常见问题及解决方案

在前后端分离开发中有些问题常常会困扰着开发者,下面介绍几个比较常见的问题及解决方案。

3.1 页面渲染缓慢

页面渲染缓慢的原因通常是由于前端框架渲染过多的 DOM 元素,导致浏览器的性能下降。为了解决这个问题,可以通过以下几种方式进行优化:

  • 精简页面代码,避免嵌套过深和过多的元素;
  • 使用组件化的设计,将页面拆分成多个小组件;
  • 使用 Ajax 异步加载数据,在合适的时机进行渲染。

3.2 跨域访问数据失败

当前端和后端服务器不在同一个域名下时,可能会涉及到跨域问题。为了解决这个问题可以通过以下几种方式进行实现:

  • 在后端代码中添加跨域配置;
  • 在前端代码中使用 JSONP 或 CORS;
  • 将前端和后端服务器部署在同一个域名下。

3.3 Ajax 获取数据失败

当使用 Ajax 向后端服务器请求数据时,可能会遇到获取数据失败的情况。这可能是因为请求参数错误、请求路径错误等原因导致的。为了解决这个问题,可以按照以下步骤进行调试:

  • 检查请求参数是否正确;
  • 检查请求路径是否正确;
  • 检查后端代码是否正确;
  • 如果还是无法解决,可以使用调试工具对请求进行调试。

七、小结回顾

在前后端分离开发中开发者需要更加注重细节问题,例如跨域问题、前端模板的组织与管理、RESTful API的设计、数据传输格式的选择等等。同时Thymeleaf 是一款非常好用的模板引擎,可以方便快捷地进行 HTML 页面的渲染。在使用 Thymeleaf 进行前后端分离开发时,需要注意一些开发细节,例如定义 HTML 页面、使用 Thymeleaf 的语法、与 Ajax 请求配合使用、跳转页面与状态码。此外,在开发过程中经常会遇到跨域、Ajax获取数据失败和页面渲染缓慢等问题,开发者需要学会解决这些问题,保证项目的顺利进行。

希望以上内容可以帮助您更好地理解前后端分离开发及Thymeleaf的使用。

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/繁依Fanyi0/article/detail/374453
推荐阅读
相关标签
  

闽ICP备14008679号