基于SpringBoot+jQuery实现留言板功能

 更新时间:2026年01月22日 10:51:44   作者:yingjuxia.com  
本教程详细介绍了如何使用Spring Boot 3.x和jQuery实现一个完整的留言板系统,主要功能包括留言查看、提交、实时刷新和表单校验,感兴趣的可以了解一下

本教程将手把手教你使用 Spring Boot 3.x 作为后端 + jQuery 作为前端交互,实现一个简洁美观的留言板系统。功能包括:

  • 查看所有留言(分页可选)
  • 提交新留言(姓名 + 内容)
  • 实时刷新显示最新留言
  • 基本的表单校验

技术栈:Spring Boot(后端 REST API) + Thymeleaf(可选) + jQuery(Ajax 交互) + Bootstrap(美化)

项目结构概览

messageboard
├── src
│   ├── main
│   │   ├── java/com/example/messageboard
│   │   │   ├── MessageboardApplication.java
│   │   │   ├── entity/Message.java
│   │   │   ├── repository/MessageRepository.java
│   │   │   └── controller/MessageController.java
│   │   └── resources
│   │       ├── static/css/style.css
│   │       ├── static/js/main.js
│   │       └── templates/index.html
│   └── ...
└── pom.xml

步骤 1:创建 Spring Boot 项目

使用 https://start.spring.io/ 生成项目,添加依赖:

  • Spring Web
  • Spring Data JPA
  • H2 Database(嵌入式数据库,方便测试)
  • Thymeleaf(模板引擎)
  • Lombok(简化代码)

步骤 2:实体类与数据库配置

Message.java

package com.example.messageboard.entity;

import jakarta.persistence.*;
import lombok.Data;
import java.time.LocalDateTime;

@Entity
@Data
public class Message {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;

    private String name;

    @Column(columnDefinition = "TEXT")
    private String content;

    private LocalDateTime createTime = LocalDateTime.now();
}

application.yml(resources 下)

spring:
  datasource:
    url: jdbc:h2:mem:messageboard
    driver-class-name: org.h2.Driver
    username: sa
    password:
  h2:
    console:
      enabled: true  # 访问 http://localhost:8080/h2-console 查看数据
  jpa:
    hibernate:
      ddl-auto: update
    show-sql: true

步骤 3:Repository 接口

package com.example.messageboard.repository;

import com.example.messageboard.entity.Message;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.Query;
import java.util.List;

public interface MessageRepository extends JpaRepository<Message, Long> {

    @Query("SELECT m FROM Message m ORDER BY m.createTime DESC")
    List<Message> findAllOrderByCreateTimeDesc();
}

步骤 4:Controller 实现 REST API

package com.example.messageboard.controller;

import com.example.messageboard.entity.Message;
import com.example.messageboard.repository.MessageRepository;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.*;

import java.util.List;

@Controller
public class MessageController {

    @Autowired
    private MessageRepository messageRepository;

    // 主页(返回 Thymeleaf 模板)
    @GetMapping("/")
    public String index(Model model) {
        return "index";  // 返回 templates/index.html
    }

    // 获取所有留言(按时间倒序)
    @GetMapping("/api/messages")
    @ResponseBody
    public List<Message> getMessages() {
        return messageRepository.findAllOrderByCreateTimeDesc();
    }

    // 提交新留言
    @PostMapping("/api/messages")
    @ResponseBody
    public ResponseEntity<?> addMessage(@RequestBody Message message) {
        if (message.getName() == null || message.getName().trim().isEmpty() ||
            message.getContent() == null || message.getContent().trim().isEmpty()) {
            return ResponseEntity.badRequest().body("姓名和内容不能为空!");
        }
        messageRepository.save(message);
        return ResponseEntity.ok(message);
    }
}

步骤 5:前端页面(index.html)

放在 src/main/resources/templates/index.html

<!DOCTYPE html>
<html lang="zh-CN" xmlns:th="http://www.thymeleaf.org">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <title>留言板</title>
    <link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0/dist/css/bootstrap.min.css" rel="external nofollow"  rel="stylesheet">
    <link rel="stylesheet" th:href="@{/css/style.css}" rel="external nofollow" >
</head>
<body class="bg-light">
<div class="container py-5">
    <div class="row">
        <div class="col-lg-8 mx-auto">
            <div class="card shadow">
                <div class="card-header bg-primary text-white">
                    <h3 class="mb-0">留言板</h3>
                </div>
                <div class="card-body">
                    <!-- 留言表单 -->
                    <form id="messageForm">
                        <div class="mb-3">
                            <label class="form-label">姓名</label>
                            <input type="text" class="form-control" id="name" required>
                        </div>
                        <div class="mb-3">
                            <label class="form-label">留言内容</label>
                            <textarea class="form-control" id="content" rows="4" required></textarea>
                        </div>
                        <button type="submit" class="btn btn-primary">提交留言</button>
                    </form>

                    <hr>

                    <!-- 留言列表 -->
                    <h5 class="mt-4">所有留言</h5>
                    <div id="messageList" class="mt-3">
                        <!-- jQuery 动态加载 -->
                    </div>
                </div>
            </div>
        </div>
    </div>
</div>

<script src="https://cdn.jsdelivr.net/npm/jquery@3.7.1/dist/jquery.min.js"></script>
<script th:src="@{/js/main.js}"></script>
</body>
</html>

步骤 6:jQuery 实现前后端交互(main.js)

放在 src/main/resources/static/js/main.js

$(document).ready(function () {
    // 页面加载时获取留言
    loadMessages();

    // 提交表单
    $('#messageForm').submit(function (e) {
        e.preventDefault();

        const name = $('#name').val().trim();
        const content = $('#content').val().trim();

        if (!name || !content) {
            alert('姓名和内容不能为空!');
            return;
        }

        $.ajax({
            url: '/api/messages',
            type: 'POST',
            contentType: 'application/json',
            data: JSON.stringify({name: name, content: content}),
            success: function (newMessage) {
                $('#name').val('');
                $('#content').val('');
                // 新留言插入到最顶部
                prependMessage(newMessage);
                alert('留言成功!');
            },
            error: function () {
                alert('提交失败,请重试');
            }
        });
    });

    // 加载所有留言
    function loadMessages() {
        $.get('/api/messages', function (messages) {
            $('#messageList').empty();
            messages.forEach(message => {
                appendMessage(message);
            });
        });
    }

    // 添加一条留言到列表
    function appendMessage(message) {
        const time = new Date(message.createTime).toLocaleString();
        const html = `
            <div class="border rounded p-3 mb-3 bg-white">
                <div class="d-flex justify-content-between">
                    <strong>${escapeHtml(message.name)}</strong>
                    <small class="text-muted">${time}</small>
                </div>
                <p class="mt-2 mb-0">${escapeHtml(message.content)}</p>
            </div>
        `;
        $('#messageList').append(html);
    }

    // 新留言插入顶部
    function prependMessage(message) {
        const time = new Date(message.createTime).toLocaleString();
        const html = `
            <div class="border rounded p-3 mb-3 bg-white animate__animated animate__fadeIn">
                <div class="d-flex justify-content-between">
                    <strong>${escapeHtml(message.name)}</strong>
                    <small class="text-muted">${time}</small>
                </div>
                <p class="mt-2 mb-0">${escapeHtml(message.content)}</p>
            </div>
        `;
        $('#messageList').prepend(html);
    }

    // 防止 XSS 攻击
    function escapeHtml(text) {
        return $('<div>').text(text).html();
    }

    // 可选:每10秒自动刷新
    // setInterval(loadMessages, 10000);
});

步骤 7:可选美化样式(style.css)

body {
    min-height: 100vh;
}

.animate__fadeIn {
    animation: fadeIn 0.5s;
}

@keyframes fadeIn {
    from { opacity: 0; transform: translateY(-10px); }
    to { opacity: 1; transform: translateY(0); }
}

运行与测试

  1. 启动项目 → 访问 http://localhost:8080
  2. 输入姓名和内容 → 点击提交
  3. 新留言实时显示在顶部
  4. 刷新页面数据持久(H2 内存数据库,重启会丢失,可换 MySQL)

扩展建议

  • 换成 MySQL 持久化存储
  • 添加分页(Pageable)
  • 支持回复、删除(需登录)
  • 使用 Vue/React 替换 jQuery
  • 添加验证码防刷

这个留言板项目简单优雅,非常适合初学者练习 Spring Boot + 前端 Ajax 交互!

到此这篇关于基于SpringBoot+jQuery实现留言板功能的文章就介绍到这了,更多相关SpringBoot jQuery 留言板内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

您可能感兴趣的文章:

相关文章

  • JPA 使用criteria简单查询工具类方式

    JPA 使用criteria简单查询工具类方式

    这篇文章主要介绍了JPA 使用criteria简单查询工具类方式,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2021-12-12
  • SpringBoot3中Spring WebFlux SSE服务器发送事件的实现步骤

    SpringBoot3中Spring WebFlux SSE服务器发送事件的实现步骤

    本文介绍了如何使用SpringBoot3和响应式编程实现服务器发送事件(SSE),并讨论了其在实时数据推送场景中的优势,通过示例代码,展示了如何创建SSE控制器、客户端接收数据以及优化与扩展,感兴趣的朋友跟随小编一起看看吧
    2024-11-11
  • Java实现对比两个实体类字段变化的示例详解

    Java实现对比两个实体类字段变化的示例详解

    我们在工作中,可能会在日志中记录数据的变化情况或者在公共处理的数据增加一个日志页面,我们可以根据CompareUtils工具类比较数据前后发生了怎样的变化,下面我们就来看看具体实现吧
    2024-03-03
  • Java学习常用包(类)之java.util包详解

    Java学习常用包(类)之java.util包详解

    这篇文章主要介绍了Java学习常用包(类)之java.util包的相关资料,Java.util包是Java标准类库的重要组成部分,包含集合框架、日期时间类、事件模型、随机数生成器等实用工具类,集合框架提供了多种数据结构和算法,需要的朋友可以参考下
    2024-10-10
  • 详解Java中List的正确的删除方法

    详解Java中List的正确的删除方法

    这篇文章主要为大家详细介绍了Java中List的正确的删除方法,文中的示例代码讲解详细,对我们学习有一定帮助,需要的可以参考一下
    2022-05-05
  • Mybatis foreach用法解析--对于list和array

    Mybatis foreach用法解析--对于list和array

    这篇文章主要介绍了Mybatis foreach用法解析--对于list和array,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2022-03-03
  • Java中equals与==的用法和区别

    Java中equals与==的用法和区别

    这篇文章主要给大家介绍了关于Java中equals与==的用法和区别的相关资料,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2018-11-11
  • Spring OAuth2.0 单元测试解决方案

    Spring OAuth2.0 单元测试解决方案

    这篇文章主要介绍了Spring OAuth2.0 单元测试解决方案,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2020-10-10
  • SpringBoot+MyBatis+Redis实现分布式缓存

    SpringBoot+MyBatis+Redis实现分布式缓存

    本文主要介绍了SpringBoot+MyBatis+Redis实现分布式缓存,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2024-01-01
  • java 中序列化NotSerializableException问题解决办法

    java 中序列化NotSerializableException问题解决办法

    这篇文章主要介绍了java 中序列化NotSerializableException问题解决办法的相关资料,这里对序列化问题进行描述说明,并提供解决办法,希望能帮助到大家,需要的朋友可以参考下
    2017-08-08

最新评论