最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

基于SpringBoot+jQuery實(shí)現(xiàn)留言板功能

 更新時(shí)間:2026年01月22日 10:51:44   作者:yingjuxia.com  
本教程詳細(xì)介紹了如何使用Spring Boot 3.x和jQuery實(shí)現(xiàn)一個(gè)完整的留言板系統(tǒng),主要功能包括留言查看、提交、實(shí)時(shí)刷新和表單校驗(yàn),感興趣的可以了解一下

本教程將手把手教你使用 Spring Boot 3.x 作為后端 + jQuery 作為前端交互,實(shí)現(xiàn)一個(gè)簡(jiǎn)潔美觀的留言板系統(tǒng)。功能包括:

  • 查看所有留言(分頁(yè)可選)
  • 提交新留言(姓名 + 內(nèi)容)
  • 實(shí)時(shí)刷新顯示最新留言
  • 基本的表單校驗(yàn)

技術(shù)棧:Spring Boot(后端 REST API) + Thymeleaf(可選) + jQuery(Ajax 交互) + Bootstrap(美化)

項(xiàng)目結(jié)構(gòu)概覽

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:創(chuàng)建 Spring Boot 項(xiàng)目

使用 https://start.spring.io/ 生成項(xiàng)目,添加依賴:

  • Spring Web
  • Spring Data JPA
  • H2 Database(嵌入式數(shù)據(jù)庫(kù),方便測(cè)試)
  • Thymeleaf(模板引擎)
  • Lombok(簡(jiǎn)化代碼)

步驟 2:實(shí)體類與數(shù)據(jù)庫(kù)配置

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  # 訪問(wèn) http://localhost:8080/h2-console 查看數(shù)據(jù)
  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 實(shí)現(xiàn) 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;

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

    // 獲取所有留言(按時(shí)間倒序)
    @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("姓名和內(nèi)容不能為空!");
        }
        messageRepository.save(message);
        return ResponseEntity.ok(message);
    }
}

步驟 5:前端頁(yè)面(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  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">留言內(nèi)容</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 動(dòng)態(tài)加載 -->
                    </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 實(shí)現(xiàn)前后端交互(main.js)

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

$(document).ready(function () {
    // 頁(yè)面加載時(shí)獲取留言
    loadMessages();

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

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

        if (!name || !content) {
            alert('姓名和內(nèi)容不能為空!');
            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('提交失敗,請(qǐng)重試');
            }
        });
    });

    // 加載所有留言
    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秒自動(dòng)刷新
    // 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); }
}

運(yùn)行與測(cè)試

  1. 啟動(dòng)項(xiàng)目 → 訪問(wèn) http://localhost:8080
  2. 輸入姓名和內(nèi)容 → 點(diǎn)擊提交
  3. 新留言實(shí)時(shí)顯示在頂部
  4. 刷新頁(yè)面數(shù)據(jù)持久(H2 內(nèi)存數(shù)據(jù)庫(kù),重啟會(huì)丟失,可換 MySQL)

擴(kuò)展建議

  • 換成 MySQL 持久化存儲(chǔ)
  • 添加分頁(yè)(Pageable)
  • 支持回復(fù)、刪除(需登錄)
  • 使用 Vue/React 替換 jQuery
  • 添加驗(yàn)證碼防刷

這個(gè)留言板項(xiàng)目簡(jiǎn)單優(yōu)雅,非常適合初學(xué)者練習(xí) Spring Boot + 前端 Ajax 交互!

到此這篇關(guān)于基于SpringBoot+jQuery實(shí)現(xiàn)留言板功能的文章就介紹到這了,更多相關(guān)SpringBoot jQuery 留言板內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

最新評(píng)論

武乡县| 洛浦县| 天等县| 杭州市| 哈巴河县| 普陀区| 浦北县| 禹州市| 巴彦淖尔市| 汉中市| 丘北县| 枞阳县| 延安市| 青铜峡市| 台前县| 富平县| 绵竹市| 兴隆县| 山阳县| 长子县| 汶川县| 兰考县| 满洲里市| 红桥区| 三亚市| 靖江市| 科技| 泸州市| 闵行区| 桑日县| 甘南县| 东城区| 石渠县| 论坛| 高州市| 上杭县| 皋兰县| 沙河市| 马鞍山市| 琼海市| 南江县|