表白墙网站练习【前端+后端+数据库】

news2025/7/21 10:43:09

表白墙网站练习【前端+后端+数据库】

开发该表白墙(简单网站)的基本步骤:
1.约定前后端交互接口
2.开发服务器代码

  1. 编写Servlet能够处理前端发来的请求
  2. 编写数据库代码,来获取/存储关键数据

3.开发客户端代码

  1. 基于ajax能够构造请求以解析响应
  2. 能够响应用户的操作(点击提交按钮之后,触发服务器发送请求的行为)

MVC

Model(操作数据存取的逻辑) View(给用户展示的界面) Controller(控制器,处理请求之后的关键逻辑)

【view->controller->model】

具体效果

由于主要代码是控制后端,前端界面美化就没有很详细的搞。
在这里插入图片描述
通过输入三条信息,然后展示在当前界面,通过后端连接数据库实现刷新该页面,或者重启服务器,用户之前输入的内容不消失的功能。
在这里插入图片描述
刷新、重启服务器刷新之后
在这里插入图片描述
可以通过MySQL查询存入数据库的信息
在这里插入图片描述

具体代码实现

项目目录结构【Maven】

在这里插入图片描述

源代码

DBUtil

在这里插入图片描述

import com.mysql.jdbc.jdbc2.optional.MysqlDataSource;

import javax.sql.DataSource;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;

public class DBUtil {
    private static final String URL="jdbc:mysql://127.0.0.1:3306/sunyuhang?characterEncoding=utf8&useSSL=false";
    private static final String USERNAME = "root";
    private static final String PASSWORD ="111111";

    private volatile static DataSource dataSource = null;

    private static DataSource getDataSource(){
        if (dataSource == null){
            synchronized (DBUtil.class) {
                if (dataSource == null) {
                    dataSource = new MysqlDataSource();
                    ((MysqlDataSource) dataSource).setUrl(URL);
                    ((MysqlDataSource) dataSource).setUser(USERNAME);
                    ((MysqlDataSource) dataSource).setPassword(PASSWORD);
                }
            }
        }
        return dataSource;
    }
    public static Connection getConnection() throws SQLException{
        return getDataSource().getConnection();
    }
    public static void close(Connection connection, PreparedStatement statement, ResultSet resultSet){
        if (resultSet != null){
            try {
                resultSet.close();
            } catch (SQLException e) {
                e.printStackTrace();
            }
        }
        if (statement !=null){
            try {
                statement.close();
            } catch (SQLException e) {
                e.printStackTrace();
            }
        }
        if (connection!=null){
            try {
                connection.close();
            } catch (SQLException e) {
                e.printStackTrace();
            }
        }
    }
}

massageServlet


import com.fasterxml.jackson.databind.ObjectMapper;

import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;

class Message{
    public String from;
    public String to;
    public String message;
}

@WebServlet("/message")
public class massageServlet extends HttpServlet {


    private ObjectMapper objectMapper = new ObjectMapper();
    //改成数据库就不需要这个变量了
    // private List<Message> messages  = new ArrayList<>();


    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        //处理提交消息请求
        Message  message = objectMapper.readValue(req.getInputStream(),Message.class);
        //最简单的方法就是保存到内存中
        //messages.add(message);

        //告知页面 返回的数据是 json  格式
        //有了这样的声明 jQuery Ajax  就会自动帮我们把字符串转换成 js 对象
        //没有的话 jQuery ajax 就会当成普通字符串来处理
        save(message);
        resp.setContentType("application/json;charset=utf8");
        resp.getWriter().write("{\"ok\":true}");
    }

    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        //获取消息列表  只要把消息列表中的内容整个返回给客户端即可
        List<Message> messages = load();
        String jsonString = objectMapper.writeValueAsString(messages);
        System.out.println("jsonString:"+jsonString);
        resp.setContentType("application/json;charset=utf8");
        resp.getWriter().write(jsonString);
    }


    private void save(Message message){
        //把一条消息保存到数据库中
        Connection connection= null;
        PreparedStatement statement = null;

        try {
            //1.和数据库建立连接
            connection = DBUtil.getConnection();
            //2.构造 SQL
            String sql = "insert into message values(?,?,?)";
            statement = connection.prepareStatement(sql);
            statement.setString(1,message.from);
            statement.setString(2,message.to);
            statement.setString(3,message.message);
            //3.执行SQL
            statement.executeUpdate();

        } catch (SQLException e) {
            e.printStackTrace();
        }finally {
            DBUtil.close(connection, statement,null);
        }
    }
    private List<Message> load(){
        //从数据库中获取到所有的消息
        List<Message> messages = new ArrayList<>();


        Connection connection = null;
        PreparedStatement statement = null;
        ResultSet resultSet = null;
        try {
            connection = DBUtil.getConnection();
            String sql = "select * from message";
            statement = connection.prepareStatement(sql);
            resultSet = statement.executeQuery();
            while (resultSet.next()){
                Message message = new Message();
                message.from = resultSet.getString("from");
                message.to = resultSet.getString("to");
                message.message = resultSet.getString("message");
                messages.add(message);
            }

        } catch (SQLException e) {
            e.printStackTrace();
        }finally {
            DBUtil.close(connection,statement,resultSet);
        }


        return messages;
    }
}

message_wall.html

将输入的数据按照json格式构造post请求
在这里插入图片描述
在这里插入图片描述

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>表白墙</title>
    <style>
        * {
            padding: 0;
            margin: 0;
            box-sizing: border-box;
        }

        .container {
            width: 800px;
            margin: 10px auto;
        }

        .container h2 {
            text-align: center;
            margin: 30px 0px;
        }

        .row {
            height: 50px;
            display: flex;
            justify-content: center;
            margin-top: 5px;
            line-height: 50px;
        }

        .row span {
            height: 50px;
            width: 100px;
            line-height: 50px;
        }

        .row input {
            height: 50px;
            width: 300px;
            line-height: 50px;
        }

        .row button {
            width: 400px;
            height: 50px;
            color: white;
            background-color: orange;
            border: none;
            border-radius: 10px;
        }

        .row button:active {
            background-color: grey;
        }
    </style>
</head>
<body>
<!-- 这是一个顶层容器, 放其他元素 -->
<div class="container">
    <h2>表白墙</h2>
    <div class="row">
        <span></span>
        <input type="text" id="from">
    </div>

    <div class="row">
        <span>对谁</span>
        <input type="text" id="to">
    </div>

    <div class="row">
        <span>说什么</span>
        <input type="text" id="message">
    </div>

    <div class="row">
        <button>提交</button>
    </div>
</div>

<script src="https://code.jquery.com/jquery-3.6.1.min.js"></script>
<script>
    let container = document.querySelector('.container');
    let fromInput = document.querySelector('#from');
    let toInput = document.querySelector('#to');
    let messageInput = document.querySelector('#message');
    let button = document.querySelector('button');
    button.onclick = function() {
        // 1. 把用户输入的内容获取到.
        let from = fromInput.value;
        let to = toInput.value;
        let message = messageInput.value;
        if (from == '' || to == '' || message == '') {
            return;
        }
        // 2. 构造一个 div, 把这个 div 插入到 .container 的末尾
        let newDiv = document.createElement('div');
        newDiv.className = 'row';
        newDiv.innerHTML = from + " 对 " + to + " 说: " + message;
        // 3. 把 div 挂在 container 里面
        container.appendChild(newDiv);
        // 4. 把之前的输入框内容进行清空
        fromInput.value = '';
        toInput.value = '';
        messageInput.value = '';

        // 5. [新的步骤] 需要把刚才输入框里取到的数据, 构造成 POST 请求, 交给后端服务器!
        let messageJson = {
            "from": from,
            "to": to,
            "message": message
        };
        $.ajax({
            type: 'post',
            // 相对路径的写法
            url: 'message',
            contentType: 'application/json;charset=utf8',
            // 绝对路径的写法
            // url: '/MessageWall/message',
            data: JSON.stringify(messageJson),
            success: function(body) {
                alert("提交成功!");
            },
            error: function() {
                // 会在服务器返回的状态码不是 2xx 的时候触发这个 error.
                alert("提交失败!");
            }
        });
    }

    // 这个函数在页面加载的时候调用. 通过这个函数从服务器获取到当前的消息列表.
    // 并且显示到页面上.
    function load() {
        $.ajax({
            type: 'get',
            url: 'message',
            success: function(body) {
                // 此处得到的 body 已经是一个 js 对象的数组了.
                // ajax 自动帮我们进行类型转换了.
                // 本来服务器返回的是 JSON 格式的字符串, ajax 会自动的根据 Content-Type 为 application/json
                // 对响应的 body 进行解析, 解析成 js 对象.
                // 遍历数组的元素, 把内容构造到页面上.
                let container = document.querySelector('.container');
                for (let message of body) {
                    let newDiv = document.createElement('div');
                    newDiv.className = 'row';
                    newDiv.innerHTML = message.from + " 对 " + message.to + " 说 " + message.message;
                    container.appendChild(newDiv);
                }
            }
        })
    }

    // 函数调用写在这里, 就表示在页面加载的时候来进行执行.
    load();

</script>
</body>
</html>

web.xml【固定格式不必细究】

<!DOCTYPE web-app PUBLIC
        "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN"
        "http://java.sun.com/dtd/web-app_2_3.dtd" >

<web-app>
    <display-name>Archetype Created Web Application</display-name>
</web-app>

pom.xml【通过maven中央仓库依赖导入】

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <groupId>org.example</groupId>
    <artifactId>20221116Message_wall</artifactId>
    <version>1.0-SNAPSHOT</version>

    <properties>
        <maven.compiler.source>8</maven.compiler.source>
        <maven.compiler.target>8</maven.compiler.target>
    </properties>
    <!--    借助maven引入tomcat-->
    <!--    jdk8-->
    <!--    tomcat 8.5-->
    <!--    servlet 3.1-->
    <dependencies>
        <!-- https://mvnrepository.com/artifact/mysql/mysql-connector-java -->
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <version>5.1.47</version>
        </dependency>


        <!-- https://mvnrepository.com/artifact/com.fasterxml.jackson.core/jackson-databind -->
        <dependency>
            <groupId>com.fasterxml.jackson.core</groupId>
            <artifactId>jackson-databind</artifactId>
            <version>2.12.6.1</version>
        </dependency>
        <!-- https://mvnrepository.com/artifact/javax.servlet/javax.servlet-api -->
        <dependency>
            <groupId>javax.servlet</groupId>
            <artifactId>javax.servlet-api</artifactId>
            <version>3.1.0</version>
            <scope>provided</scope>
        </dependency>
    </dependencies>

</project>

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/17119.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

一体化Ethercat通信伺服电机在汇川H5U PLC上的应用案例介绍(上)

内容介绍了一体化低压伺服Ethercat通信的电机在汇川H5UPLC上的使用&#xff0c;本篇主要讲解环境的搭建以及使用AutoShop软件的在线调试功能&#xff0c;简单控制电机位置、速度模式运行&#xff1b; 一、系统构成 本系统主要构成是电脑&#xff0c;H5U-1614MTD-A8&#xff0c;…

家长杂志家长杂志社家长编辑部2022年第30期目录

卷首语 读懂童心,营造乐学趣学好场景 本刊编辑部; 1 本刊视线_关注《家长》投稿&#xff1a;cn7kantougao163.com 留守儿童学习动力不足的成因与激发策略 蔡斌林; 4-6 农村留守儿童加强心理健康教育的策略 张芸; 7-9 本刊视线_学校体育 中学体育线上线下教学融…

【Struts2框架】idea快速搭建struts2框架

文章目录什么是SSH框架&#xff1f;Struts2框架1、struts2的环境搭建1.1 创建web项目&#xff08;maven&#xff09;&#xff0c;导入struts2核心jar包1.2 配置web.xml&#xff08;过滤器&#xff09;&#xff0c;是struts2的入口&#xff0c;先进入1.3 创建核心配置文件struts…

STM32 Bootloader开发记录 3 固件签名校验

STM32 Bootloader开发记录 3 固件签名校验 文章目录STM32 Bootloader开发记录 3 固件签名校验1. 移植mbedtls1.1 编译mbedtls1.2 修复rsa_sign的一个bug1.3 测试RSA1.3.1 **RSA加解密&#xff1a;**1.3.2 **RSA签名验签&#xff1a;**1.3.3 **生成秘钥对**1.4 移植到STM321.4.1…

NFV中:DPDK与SR-IOV应用场景及性能对比

DPDK与SR-IOV两者目前主要用于提高IDC&#xff08;数据中心&#xff09;中的网络数据包的加速。但是在NFV&#xff08;网络功能虚拟化&#xff09;场景下DPDK与SR-IOV各自的使用场景是怎样的&#xff1f;以及各自的优缺点&#xff1f; 本文主要通过从以下几点来阐述这个问题&a…

视觉SLAM十四讲(高翔版本),ch4章节部分笔记

目标&#xff1a;理解slam的框架以及它的理论知识。供以后自己查阅。 这一章主要非常重要&#xff0c;也是理解后续优化的基础&#xff0c;它是将旋转矩阵和平移向量&#xff0c;转化为李代数的形式进行优化&#xff0c;因为它有很多好处。好处如下&#xff1a; 意思就是采用…

Linux硬盘垃圾清理心得

最近有台系统盘才10G的服务器咔咔报警&#xff0c;一共才10G的空间&#xff0c;运维还设置了80%的报警阈值&#xff0c;实在难顶。为了清理硬盘里的垃圾&#xff0c;敲了不少命令&#xff0c;怕以后忘了&#xff0c;记录一下。 首先输入df -h查看一下硬盘空间占用情况&#xf…

呼叫中心中间件(mod_cti基于FreeSWITCH)-通话记录(CDR)接口

支持把FreeSWITCH的通话记录写入mysql,sqlserver,oracle等数据库&#xff0c;也可以写入redis的list&#xff0c;或者PUBLISH到redis的channel,方便业务程序实时获取通话记录。 使用说明 如果一个通话是A呼叫B&#xff0c;那么就有2个通话记录&#xff0c;一个叫aleg,一个叫b…

Vue3 - 全局指令(详细教程)

前言 咱们在真实项目开发中&#xff0c;其实有很多指令都是通用的。我们绝对不可能去每个页面都定义一次&#xff0c;这样不仅写起来困难&#xff0c;维护起来更是困难&#xff0c;你想一下&#xff0c;假设稍微变点逻辑&#xff0c;你就需要翻阅好几个文件去改。 其实用法和局…

家用吸尘器的总体结构设计

目 录 摘 要 i Abstract ii 1 引言 1 2 家用吸尘器的历史及发展 2 2.1 家用吸尘器的历史 2 2.2 业界的发展情况 3 3 家用吸尘器的分类 5 3.1 卧式&#xff08;Canister&#xff09; 5 3.2 立式&#xff08;Upright&#xff09; 5 3.3 手持式 &#xff08;Handy&#xff09; 6 3…

ON1 NoNoise AI 2023:AI智能摄影降噪工具

ON1 NoNoise AI 2023中文版是一款强大的AI智能摄影降噪工具&#xff01;使用 AI 驱动的 NoNoise AI 快速去除噪点并获得照片中最清晰的细节。 更快地获得绝对最佳结果&#xff01; ON1 NoNoise 比其他领先的图像去噪产品快十倍&#xff0c;结果会让您大吃一惊&#xff01; 基于…

HI3516DV300 图像输入

HI3516DV300 图像输入 易百纳的一个开发板&#xff0c;以及GC2053的摄像头。 硬件 海思 海思sensor接口如下&#xff0c;用的是差分信号&#xff0c;共4对数据线&#xff08;或者说4条lane&#xff09;&#xff0c;两对差分时钟。 连接器 海思核心板和扩展板之间通过板件连…

小啊呜产品读书笔记001:《邱岳的产品手记-06》11讲 如何借鉴灵感 12讲 产品案例分析:LabRdr的设计实验

小啊呜产品读书笔记001&#xff1a;《邱岳的产品手记-06》11讲 如何借鉴灵感 & 12讲 产品案例分析&#xff1a;LabRdr的设计实验一、今日阅读计划二、泛读&知识摘录1、11讲 如何借鉴灵感&#xff1f;2、12讲 产品案例分析&#xff1a;LabRdr的设计实验三、头脑风暴叮嘟…

【计算机毕业设计】外卖点餐源码

一、系统截图&#xff08;需要演示视频可以私聊&#xff09; 摘 要 民以食为天&#xff0c;外卖点餐系统餐饮业一直是与人们日常生活息息相关的产业。传统的电话外卖点餐或者到店消费已经不能适应市场发展的需求。随着网络的迅速崛起&#xff0c;互联网日益成为提供信息的最佳…

电话机器人详解,电销机器人获客的正确姿势是什么?

电话机器人详解&#xff0c;电销机器人获客的正确姿势是什么&#xff1f; 相信很多没接触过电话机器人的人都会好奇。 首先是预设Q&A问答主流程 通过关键词辅助指导&#xff0c;终端在与客户互动时&#xff0c;会智能地获取相应的关键词库&#xff0c;逐一回答客户的问题…

ISACA证书维持| 内附QA

Q如何维持证书 A证书的维持主要由两部分组成&#xff0c;即维持费以及CPE&#xff08;继续职业教育&#xff09;学时。ISACA会在每个日历年的第三季度以电子邮件及印刷版的方式向所有持证人员发送次年费用清单通知。年度维护费支付可在 https://www.isaca.org/renewals 上在线…

完全背包问题的解决方法______闫氏 DP 分析法

完全背包问题的解决方法&#xff1a; 闫氏 DP\ DPDP 分析法: 通过集合划分&#xff0c;我们可以得到第 i\ ii 个物品有两种状态&#xff1a;  1.选 1−T\ 1 - T1−T 个&#xff0c;最优解为前 i−1\ i− 1i−1 个物品的所有选择中&#xff0c;还能选取当前 k\ kk 个第i\ ii 个…

模式识别与机器学习 第一章:绪论

一、基础概念 样本: 所研究对象的单个个体、实例。样本集: 若干样本的集合。类或类别: 在所有样本上定义的一个子集&#xff0c;处于同一类的样本具有相似的性质&#xff0c;即具有相同的模式。特征: 用于表征样本的观测&#xff0c;也称属性。通常是数值表示的某些量化特征&a…

基于帧间差分法的视频目标检测研究-含Matlab代码

⭕⭕ 目 录 ⭕⭕✳️ 一、引言✳️ 二、帧间差分算法原理✳️ 三、视频目标检测系统✳️ 四、参考文献✳️ 五、Matlab代码获取✳️ 一、引言 随着科技的发展、社会的进步、人民生活水平的提高&#xff0c;团体和个人的安防意识都在不断增强&#xff0c;视频监控系统也就得到了…

深入浅出 C++ 11 右值引用

彻底搞清楚&#xff1a;右值引用/移动语义/拷贝省略/通用引用/完美转发 —— 以最短的篇幅&#xff0c;介绍常见误解&#xff08;什么时候要用 move&#xff1f;什么时候不能 move&#xff1f;为什么 move 失败&#xff1f;&#xff09;和基础知识&#xff08;为什么右值引用变…