SpringBoot整合Layui与Thymeleaf实战

Layui + Thymeleaf + Spring Boot 整合示例

下面是一个完整的用户管理系统示例,展示了三者的整合使用:

项目结构

复制代码
src/
├── main/
│   ├── java/
│   │   └── com/example/demo/
│   │       ├── controller/UserController.java
│   │       ├── entity/User.java
│   │       ├── repository/UserRepository.java
│   │       └── DemoApplication.java
│   ├── resources/
│   │   ├── static/
│   │   │   ├── layui/          # Layui框架文件
│   │   │   └── css/style.css   # 自定义样式
│   │   ├── templates/
│   │   │   └── user/
│   │   │       ├── list.html   # 用户列表页面
│   │   │       └── form.html   # 用户表单页面
│   │   └── application.properties

核心代码实现

1. 实体类 (User.java)
复制代码
public class User {
    private Long id;
    private String username;
    private String email;
    private Integer age;
    private Integer status; // 状态:0-禁用,1-启用
    
    // getters & setters
}
2. 控制器 (UserController.java)
复制代码
@Controller
@RequestMapping("/user")
public class UserController {
    
    // 模拟数据存储
    private static final Map<Long, User> userMap = new ConcurrentHashMap<>();
    
    /**
     * 用户列表页
     */
    @GetMapping("/list")
    public String list(Model model) {
        model.addAttribute("userList", new ArrayList<>(userMap.values()));
        return "user/list";
    }
    
    /**
     * 添加用户页
     */
    @GetMapping("/form")
    public String form(Model model) {
        model.addAttribute("user", new User()); // 表单绑定对象
        return "user/form";
    }
    
    /**
     * 保存用户 (POST请求处理)
     */
    @PostMapping("/save")
    @ResponseBody
    public Map<String, Object> saveUser(@RequestBody User user) {
        // 生成ID(模拟持久化)
        if(user.getId() == null) {
            user.setId(System.currentTimeMillis());
        }
        userMap.put(user.getId(), user);
        
        // Layui要求的返回格式
        return Map.of("code", 0, "msg", "保存成功");
    }
    
    /**
     * 删除用户
     */
    @PostMapping("/delete")
    @ResponseBody
    public Map<String, Object> deleteUser(Long id) {
        userMap.remove(id);
        return Map.of("code", 0, "msg", "删除成功");
    }
}
3. 用户列表页 (list.html)
复制代码
<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
<head>
    <meta charset="utf-8">
    <title>用户管理</title>
    <!-- 引入Layui CSS -->
    <link th:href="@{/layui/css/layui.css}" rel="stylesheet">
    <style>
        .layui-table-cell {
            height: auto; /* 表格高度自适应 */
        }
    </style>
</head>
<body>
    <!-- 内容区域 -->
    <div class="layui-container" style="padding: 20px;">
        <blockquote class="layui-elem-quote">用户列表</blockquote>
        
        <!-- 工具栏 -->
        <div class="layui-row">
            <button class="layui-btn layui-btn-sm" id="addBtn">
                <i class="layui-icon">&#xe608;</i> 添加用户
            </button>
        </div>
        
        <!-- 表格 -->
        <table id="userTable" class="layui-table">
            <thead>
                <tr>
                    <th>ID</th>
                    <th>用户名</th>
                    <th>邮箱</th>
                    <th>年龄</th>
                    <th>状态</th>
                    <th>操作</th>
                </tr>
            </thead>
            <tbody>
                <!-- Thymeleaf循环渲染用户数据 -->
                <tr th:each="user : ${userList}">
                    <td th:text="${user.id}">1</td>
                    <td th:text="${user.username}">admin</td>
                    <td th:text="${user.email}">admin@example.com</td>
                    <td th:text="${user.age}">25</td>
                    <td>
                        <span th:if="${user.status == 1}" class="layui-badge layui-bg-green">启用</span>
                        <span th:if="${user.status == 0}" class="layui-badge layui-bg-gray">禁用</span>
                    </td>
                    <td>
                        <button class="layui-btn layui-btn-xs" th:onclick="|editUser(${user.id})|">
                            <i class="layui-icon">&#xe642;</i>编辑
                        </button>
                        <button class="layui-btn layui-btn-xs layui-btn-danger" 
                                th:onclick="|deleteUser(${user.id})|">
                            <i class="layui-icon">&#xe640;</i>删除
                        </button>
                    </td>
                </tr>
            </tbody>
        </table>
    </div>

    <!-- 引入Layui JS -->
    <script th:src="@{/layui/layui.js}"></script>
    <script>
        // 初始化Layui模块
        layui.use(['layer', 'form'], function() {
            var layer = layui.layer;
            var form = layui.form;
            
            // 添加用户按钮事件
            document.getElementById('addBtn').addEventListener('click', function() {
                layer.open({
                    type: 2,
                    title: '添加用户',
                    content: '/user/form',
                    area: ['600px', '500px'],
                    end: function() {
                        location.reload(); // 关闭后刷新页面
                    }
                });
            });
        });
        
        // 编辑用户
        function editUser(id) {
            layer.open({
                type: 2,
                title: '编辑用户',
                content: '/user/form?id=' + id,
                area: ['600px', '500px'],
                end: function() {
                    location.reload();
                }
            });
        }
        
        // 删除用户
        function deleteUser(id) {
            layer.confirm('确定删除该用户吗?', function(index) {
                // 发送AJAX请求到后台
                $.ajax({
                    url: '/user/delete',
                    type: 'POST',
                    data: {id: id},
                    success: function(res) {
                        if(res.code === 0) {
                            layer.msg('删除成功');
                            setTimeout(function() {
                                location.reload();
                            }, 1500);
                        }
                    }
                });
                layer.close(index);
            });
        }
    </script>
</body>
</html>
4. 用户表单页 (form.html)
复制代码
<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
<head>
    <meta charset="utf-8">
    <title>用户表单</title>
    <link th:href="@{/layui/css/layui.css}" rel="stylesheet">
</head>
<body style="padding: 20px;">
    <!-- 使用th:object绑定表单对象 -->
    <form class="layui-form" th:object="${user}" id="userForm">
        <!-- 隐藏域存储用户ID -->
        <input type="hidden" th:field="*{id}" name="id">
        
        <div class="layui-form-item">
            <label class="layui-form-label">用户名</label>
            <div class="layui-input-block">
                <!-- th:field自动绑定属性 -->
                <input type="text" th:field="*{username}" name="username" 
                       lay-verify="required" placeholder="请输入用户名" 
                       class="layui-input">
            </div>
        </div>
        
        <div class="layui-form-item">
            <label class="layui-form-label">邮箱</label>
            <div class="layui-input-block">
                <input type="text" th:field="*{email}" name="email" 
                       lay-verify="email" placeholder="请输入邮箱" 
                       class="layui-input">
            </div>
        </div>
        
        <div class="layui-form-item">
            <label class="layui-form-label">年龄</label>
            <div class="layui-input-block">
                <input type="number" th:field="*{age}" name="age" 
                       placeholder="请输入年龄" class="layui-input">
            </div>
        </div>
        
        <div class="layui-form-item">
            <label class="layui-form-label">状态</label>
            <div class="layui-input-block">
                <!-- 单选按钮组 -->
                <input type="radio" th:field="*{status}" name="status" 
                       value="1" title="启用" checked>
                <input type="radio" th:field="*{status}" name="status" 
                       value="0" title="禁用">
            </div>
        </div>
        
        <div class="layui-form-item">
            <div class="layui-input-block">
                <button class="layui-btn" lay-submit lay-filter="formDemo">立即提交</button>
                <button type="reset" class="layui-btn layui-btn-primary">重置</button>
            </div>
        </div>
    </form>

    <script th:src="@{/layui/layui.js}"></script>
    <script>
        layui.use(['layer', 'form', 'jquery'], function() {
            var form = layui.form;
            var $ = layui.$;
            
            // 表单渲染(必须调用)
            form.render();
            
            // 表单提交监听
            form.on('submit(formDemo)', function(data) {
                // 使用AJAX提交表单
                $.ajax({
                    url: '/user/save',
                    type: 'POST',
                    contentType: 'application/json', // 使用JSON格式
                    data: JSON.stringify(data.field), // 表单数据
                    success: function(res) {
                        if(res.code === 0) {
                            // 提交成功,关闭当前弹层
                            var index = parent.layer.getFrameIndex(window.name);
                            parent.layer.msg('保存成功');
                            parent.layer.close(index);
                        }
                    }
                });
                return false; // 阻止表单默认提交
            });
        });
    </script>
</body>
</html>

主要技术整合点说明

1. Thymeleaf与Spring Boot整合
  • 模板定位 :Spring Boot自动配置Thymeleaf,模板文件放在resources/templates/
  • 模型传递 :控制器通过Model对象向模板传递数据
  • 数据绑定 :使用th:object="${user}"绑定表单对象,th:field="*{property}"绑定具体属性
2. Layui功能集成
  • 模块化加载layui.use(['layer', 'form'], function(){})
  • 组件使用
    • layer:弹层组件(confirm, open, msg)
    • form:表单渲染和验证
    • table:数据表格(示例中直接使用HTML表格)
  • 样式规范 :使用Layui的CSS类(layui-btn, layui-table等)
3. 前后端交互
  • AJAX请求

    复制代码
    $.ajax({
      url: '/user/save',
      type: 'POST',
      contentType: 'application/json',
      data: JSON.stringify(data),
      success: function(res) { /* 处理响应 */ }
    });
  • 统一响应格式 :控制器返回{code: 0, msg: "success"}格式

  • RESTful风格 :使用@GetMapping/@PostMapping区分操作类型

运行效果

  1. 访问 /user/list 显示用户列表
  2. 点击"添加用户"弹出表单窗口
  3. 提交表单后通过AJAX保存数据
  4. 编辑/删除操作使用Layui弹层确认
  5. 所有操作无需页面刷新,局部更新

项目部署与配置

  1. application.properties 添加:

    关闭模板缓存(开发时使用)

    spring.thymeleaf.cache=false

    静态资源路径

    spring.mvc.static-path-pattern=/static/**

    端口设置

    server.port=8080

  2. 添加Layui前端库:

  • 从官网下载Layui:
  • 解压到resources/static/layui/目录

最佳实践建议

  1. 安全处理​:

    • 添加CSRF防护
    • 表单数据后端验证
  2. 性能优化​:

    • 分页加载数据(Layui table分页)
    • 静态资源缓存
  3. 代码组织​:

    • 将JavaScript拆分为独立文件
    • 使用Thymeleaf碎片模板
  4. 错误处理​:

    • 统一异常处理
    • AJAX错误回调处理
  5. 响应式设计​:

    • 使用Layui的栅格系统
    • 添加移动端适配

这个示例展示了Layui+Thymeleaf+Spring Boot的基础整合模式,可以作为后台管理系统开发的起点。实际项目中可根据需求扩展更多功能模块。