表白墙程序

目录

一、页面代码部分

二、设计程序

二、实现 doPost​编辑

三、实现 doGet

四、前端代码部分

五、使用数据库存储数据


一、页面代码部分

在之前的一篇博客中,已经写过了表白墙的页面代码实现,这里就不再重复了

页面代码如下:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>表白墙</title>
</head>
<body>
    <div class="container">
        <h1>表白墙</h1>
        <p>输入后点击提交,会将信息显示在表格中</p>
        <div class="row">
            <span>谁:</span>
            <input type="text" class="edit">
        </div>
        <div class="row" >
            <span>对谁:</span>
            <input type="text" class="edit">
        </div>
        <div class="row">
            <span>说什么:</span>
            <input type="text" class="edit">
        </div>
        <div class="row">
            <input type="button" value="提 交" id="submit">
        </div>
        <script>
            let submitButton=document.querySelector('#submit');
            submitButton.onclick=function(){
                //1.先获取到编辑框的内容
                let edits=document.querySelectorAll('.edit');
                //依靠.value来获得其输入框的值
                let from=edits[0].value;
                let to=edits[1].value;
                let message=edits[2].value;
                console.log(from,to,message);
                //这里是对用户输入进行合法的校验,看用户输入是否合法
                if(from==''||to==' '||message==''){
                    return;
                }
                //2.根据内容,构造HTML元素(.row里面包含用户输入的话)
                //createElement:创建一个元素
                let row=document.createElement('div');
                row.className='row';
                row.innerHTML=from+'对'+to+'说:'+message;
                //3.把这个新的元素添加到DOM树上
                let container=document.querySelector('.container');
                container.appendChild(row);
                //4.清空原来的输入框
                for(let i=0;i<edits.length;i++){
                    edits[i].value='';
                }
            }
        </script>
        <style>
            /*去除浏览器默认样式:内边距,外边距,内边框和外边框不会撑大盒子*/
            *{
                margin:0;
                padding: 0;
                box-sizing: border-box;
            }
            /*margin:0 auto :意思是 中央居中*/
            .container{
                width: 400px;
                margin:0 auto;
            }
            /*padding:20px auto :h1标签:上下间距20*/
            h1{
               text-align:center;
                padding:20px auto;
            }
            p{
                text-align:center;
                color:#666;
                padding: 10px 0;
                font-size:14px;
            }
            /*display:flex:基于弹性布局
              justify-content:center:水平居中
              align-items:center:垂直居中
            */
            .row{
                height:50px ;
                display: flex;
                justify-content: center;
                align-items:center;
            }
            /*现在对于span和input的长度进行调整*/
            span{
                width:90px;
                font-size: 20px;
            }
            input{
                width:310px;
                height: 40px;
                font-size: 18px;
            }
            /*现在处理一下 提交 按钮
             首先,提交按钮宽度和父元素一样宽
             其次,设置字体颜色和背景颜色
             然后,border:none:作用:为了去除黑边框
                  border-radius:设置四个角角为圆矩形
                  font-size:设置 提交 字体的大小
            */

            #submit{
                width: 400px;
                color: white;
                background-color:orange;
                border:none;
                border-radius:5px;
                font-size: 18px;
            }
            /*点击 提交 按钮 就会改变其背景颜色*/
            #submit:active{
                background-color: black;
            }
        </style>
    </div>
</body>
</html>

二、设计程序

之前写的页面有两个非常严重的问题:

1、如果刷新页面 / 关闭页面 重开,之前输入的消息就不见了

2、如果一个机器上输入了数据,第二个机器是看不到的(这些数据都是在本地浏览器中)

解决思路:

让服务器来存储用户提交的数据,由服务器保存

当由新的浏览器打开页面的时候,再从服务器获取数据

此处服务器就可以用来存档和读档的操作

写 web 程序,务必要重点考虑前后端如何交互,也就是约定好前后端交互的数据格式

这个过程,称为 设计前后端交互接口

请求时什么样的,响应是什么样的,浏览器什么时候发送请求,浏览器按照什么格式来解析....

那么哪些环节涉及到前后端交互呢?

1、点击提交,浏览器把表白信息发送到服务器这里

2、页面加载,浏览器从服务器获取到表白信息

1、点击提交,浏览器把表白信息发送到服务器这里

2、页面加载,浏览器从服务器获取到表白信息

此处的约定,没有固定的强制要求,只要保证能够实现必要的需求即可,此处的目的是为了前后端可以对上号

注意:这里的路径得和之前约定的保持一致


二、实现 doPost

我们要先定义一个类,描述请求的 body 内容,方便 jackson 进行 json 解析

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

然后使用 List 来存储数据

 //使用 List 变量保存所有消息
    private List<Message> messagesList = new ArrayList<>();


    //向服务器提交数据
    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        ObjectMapper objectMapper = new ObjectMapper();
        //把 body 中的内容读取出来,解析成 message 对象
        Message message = objectMapper.readValue(req.getInputStream(),Message.class);
        //此处,通过一个简单粗暴的方式来完成保存
        messagesList.add(message);
        //此处的设定状态码可以省略,不设置,默认也是200
        resp.setStatus(200);
    }

doPost 做的事情,就是把解析的 message 往 List 里面添加


三、实现 doGet

另一方面,实现 doGet ,也就是把 List 的结果,返回给前端

响应数据,也是一个 json 数据

基于 objectMapper 的 writeValue 方法,就可以把 List <Message> 转换成 json 格式

这个方法,同时完成了把 java 对象,转换成 json 和把 json 字符串写到响应对象中

第一个参数是 Writer 对象,表示转成的 json 字符串,往哪个地方去写,第二个参数就是当前存储消息的 List ,意思是要把哪个对象转换成 json 

如果分成两步,就是这样写的:

    //从服务器获取数据
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        ObjectMapper objectMapper = new ObjectMapper();
        //显示告诉浏览器,数据是 json 格式,并且字符集是 utf8
        resp.setContentType("applicaion/json; charseet=utf8");
        objectMapper.writeValue(resp.getWriter(),messagesList);
    }

针对 doGet ,只是把 MessageList 给转换成 json 字符串,返回给浏览器

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

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

    //使用 List 变量保存所有消息
    private List<Message> messagesList = new ArrayList<>();


    //向服务器提交数据
    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        ObjectMapper objectMapper = new ObjectMapper();
        //把 body 中的内容读取出来,解析成 message 对象
        Message message = objectMapper.readValue(req.getInputStream(),Message.class);
        //此处,通过一个简单粗暴的方式来完成保存
        messagesList.add(message);
        //此处的设定状态码可以省略,不设置,默认也是200
        resp.setStatus(200);
    }

    //从服务器获取数据
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        ObjectMapper objectMapper = new ObjectMapper();
        //显示告诉浏览器,数据是 json 格式,并且字符集是 utf8
        resp.setContentType("applicaion/json; charset=utf8");
        //objectMapper.writeValue(resp.getWriter(),messagesList);

        //把 java 对象转换成 json 字符串
        String jsonResp = objectMapper.writeValueAsString(messagesList);
        //把字符串写回到响应 body 中
        resp.getWriter().write(jsonResp);
    }
}

写到这里,表白墙的后端就大功告成了,我们可以打开 postman 对代码进行测试

当前这只是给前端返回 json 字符串,要想成为键值对,还需要额外的代码


四、前端代码部分

接下来,我们来编写前端代码,也就是让页面能够发起上述请求,并解析响应

post 是点击提交按钮的时候发起,get 是页面加载的时候发起

这个代码是在定义一个 js 对象(类似于 json 的键值对)

key 其实是字符串,value 则是 js 中的变量/常量

js 中要求, 对象中的 key 务必是 字符串,所以这里的 "" 可以省略

当前 body 是个 js 对象,不是字符串,网络传输,只能串字符串,不能传对象

所以,我们需要把目前这个对象转成字符串

js 内置了转换 json 的库

                //4、[新增] 给服务器发起 post 请求,把上述数据提交到服务器
                let body = {
                    from :from,
                    to:to,
                    message:msg
                };
                strBody = JSON.stringify(body);
                console.log("strBody: " + strBody);
                $.ajax({
                    type:'post',
                    url:'message',
                    data:strBody, 
                    contentType:"application/json;charset=utf8",
                    success:function(body){
                        console,log("数据发布成功");
                    }
                });

接下来需要实现下 读档操作,让 ajax 发送 GET 请求

            //[新增] 在页面加载的时候,发送 GET 请求,从服务器获取到数据并添加到页面中
            $.ajax({
                type:'get',
                url:'message',
                success:function(body){
                    //此处拿到的 body 就是一个 js 的对象数组了
                    //本来服务器返回的是一个 json 格式的字符串,但是 jquery 的 ajax 可以自动识别,
                    //自动帮我们把 json 字符串转成 js 对象数组
                    //接下来,遍历这个数组,把元素取出来,并且构造到页面中即可
                    for(let message of body){
                        //针对每个元素构造一个 div
                        let row=document.createElement('div');
                        row.className='row';
                        row.innerHTML=message.from +'对'+message.to +'说:'+message.message;
                        containerDiv.appendChild(rowDiv);
                    }
                }
            });

五、使用数据库存储数据

当前我们的数据是在内存(变量) 中保存的,重启服务器就没了

要想持久化保存,就需要写入文件中(硬盘)

1、直接使用 流对象 写入文本文件

2、借助数据库

创建数据表

此处只有一个表:message(from ,to,message)

实现数据库操作:

//通过这个类,把数据库连接过程封装一下
//此处,把 DBUtil 作为一个工具类,提供 static 方法,供其它方法来调用
public class DBUtil {
    //静态成员是跟随类对象的,类对象在整个进程中,只有唯一一份
    //静态成员相当于也是唯一的实例(单例模式,饿汉模式)
    private static DataSource dataSource = new MysqlDataSource();

    static {
        //使用静态代码块,针对 dataSourse 进行初始化
        ((MysqlDataSource)dataSource).setUrl("jdbc:mysql://127.0.0.1:3306/java?charactorEncoding=utf8&useSSL=false");
        ((MysqlDataSource)dataSource).setUser("root");
        ((MysqlDataSource)dataSource).setPassword("123456");
    }

    //通过这个方法来建立连接
    public static Connection getConnection() throws SQLException {
        return dataSource.getConnection();
    }

    //通过这个方法来断开连接,释放资源
    public static void close(Connection connection, PreparedStatement statement, ResultSet resultSet)  {
       //此处的三个 try catch 分开写更好,避免前面的异常导致后面的代码无法执行
        if (resultSet != null){
            try {
                resultSet.close();
            } catch (SQLException e) {
                throw new RuntimeException(e);
            }
        }
        if (statement != null){
            try {
                statement.close();
            } catch (SQLException e) {
                throw new RuntimeException(e);
            }
        }
        if (connection != null){
            try {
                connection.close();
            } catch (SQLException e) {
                throw new RuntimeException(e);
            }
        }
    }
}

要插入的数据,是三个变量,要把这三个变量给填充到 Sql 中,就需要占位符

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

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

    //使用 List 变量保存所有消息
    //private List<Message> messagesList = new ArrayList<>();


    //向服务器提交数据
    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        ObjectMapper objectMapper = new ObjectMapper();
        //把 body 中的内容读取出来,解析成 message 对象
        Message message = objectMapper.readValue(req.getInputStream(),Message.class);
        //此处,通过一个简单粗暴的方式来完成保存
        //messagesList.add(message);
        save(message);
        //此处的设定状态码可以省略,不设置,默认也是200
        resp.setStatus(200);
    }

    //从服务器获取数据
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        ObjectMapper objectMapper = new ObjectMapper();
        //显示告诉浏览器,数据是 json 格式,并且字符集是 utf8
        resp.setContentType("applicaion/json; charset=utf8");
        //objectMapper.writeValue(resp.getWriter(),messagesList);

        //把 java 对象转换成 json 字符串
        List<Message> messagesList = load();
        String jsonResp = objectMapper.writeValueAsString(messagesList);
        //把字符串写回到响应 body 中
        resp.getWriter().write(jsonResp);
    }

    //提供一对方法
    //往数据库中存一条消息
    private void save(Message message) {
        //JDBC 操作
        //1、建立连接
        Connection connection = null;
        PreparedStatement statement = null;
        try {
            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) {
            throw new RuntimeException(e);
        }finally {
            //4、关闭连接
            DBUtil.close(connection,statement,null);
        }
    }

    //从数据库中取所有消息
    private List<Message> load(){
        List<Message> messageList = new ArrayList<>();
        PreparedStatement statement = null;
        Connection connection = null;
        ResultSet resultSet = null;
        try {
            //1、和数据库建立连接
             connection = DBUtil.getConnection();
            //2、构造 SQL
            String sql = "select *from message";
             statement = connection.prepareStatement(sql);
            //3、执行 SQL
             resultSet = statement.executeQuery();
            //4、遍历结果集合
            while (resultSet.next()){
                Message message = new Message();
                message.from = resultSet.getString("from");
                message.to = resultSet.getString("to");
                message.message = resultSet.getString("message");
                messageList.add(message);
            }
        }catch (SQLException e){
            e.printStackTrace();
        }finally {
            //5、需要释放资源,断开连接
            DBUtil.close(connection,statement,resultSet);
        }
        return messageList;
    }
}

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

【计算机组成 课程笔记】1.2 冯·诺伊曼结构

课程链接&#xff1a; 计算机组成_北京大学_中国大学MOOC(慕课) 1 - 2 - 102-冯诺依曼结构的要点&#xff08;13-59--&#xff09;_哔哩哔哩_bilibili 现代的计算机形态各异&#xff0c;但究其本质&#xff0c;几乎全部采用了冯诺依曼结构。要了解计算机&#xff0c;首先要知道…

华为数通方向HCIP-DataCom H12-821题库(拖拽题,知识点总结)

以下是我在现有题库中整理的需要重点关注的考点内容,如有遗漏小伙伴可以留言补充。

【仿牛客论坛java项目】第五章 Kafka,构建TB级异步消息系统:阻塞队列、Kafka入门、Spring整合Kafka、发送系统通知、显示系统通知

这里写自定义目录标题 一、阻塞队列简单的阻塞队列测试案例总结阻塞队列 二、Kafka入门1、基础知识Kafka术语消息队列实现方式两种 2、配置3、启动全部命令启动 zookeeper 服务器再启动 kafka 服务器创建Topic关闭 4、总结Kafka的特点Kafka的术语 三、 Spring整合Kafka导入依赖…

R语言绘图相关函数(含实例)

目录 plot:可用于创建多种类型的图形 dev.new():新建画板 hist&#xff1a;绘制直方图 dotchart&#xff1a;绘制点图的函数 pie:绘制饼图 pair&#xff1a;绘制散点图矩阵 boxplot&#xff1a;绘制箱线图 scatterplot3D&#xff1a; 绘制三维散点图 par&#xff1a;修…

CTFhub-文件上传-前端验证

burp 抓包 --> 重发--> 查看源代码 用 GodZilla 生成木马 文件名为 1.php.jsp 上传-->抓包-->改包 (删掉 .jpg) --> 点击 放行 木马文件位置为&#xff1a;http://challenge-f0531d0c27641130.sandbox.ctfhub.com:10800/upload/1.php 用 蚁剑连接 ctfhub{4743b…

【Go 基础篇】Go语言结构体实例的创建详解

在Go语言中&#xff0c;结构体是一种强大的数据类型&#xff0c;允许我们定义自己的复杂数据结构。通过结构体&#xff0c;我们可以将不同类型的数据字段组合成一个单一的实例&#xff0c;从而更好地组织和管理数据。然而&#xff0c;在创建结构体实例时&#xff0c;有一些注意…

百度抓取香港服务器抓取超时是什么情况?

​ 网络延迟导致抓取超时 网络延迟是指从发送请求到接收响应之间的时间延迟。如果网络延迟过高&#xff0c;服务器可能无法及时响应请求&#xff0c;导致超时。在香港服务器上抓取数据时&#xff0c;如果网络延迟过高&#xff0c;可能会出现抓取超时的情况。 服务器负载过高可能…

设计模式-原型模式详解

文章目录 前言理论基础1. 原型模式定义2. 原型模式角色3. 原型模式工作过程4. 原型模式的优缺点 实战应用1. 原型模式适用场景2. 原型模式实现步骤3. 原型模式与单例模式的区别 原型模式的变体1. 带有原型管理器的原型模式2. 懒汉式单例模式的原型模式实现3. 细粒度原型模式 总…

系统架构技能之设计模式-抽象工厂模式

一、上篇回顾 上篇我们主要讲述了简单工厂模式和工厂模式。并且分析了每种模式的应用场景和一些优缺点&#xff0c;我们现在来回顾一下&#xff1a; 简单工厂模式&#xff1a;一个工厂负责所有类型对象的创建&#xff0c;不支持无缝的新增新的类型对象的创建。 工厂模式&…

JVM面试核心点

一、JDK体系 二、JVM体系 三、JVM内存模型 public class Math {public static final int data 666;public static UserEntity user new UserEntity();public int compute() { // 一个方法对应一块栈帧内存区域int a 1;int b 2;int c (ab)*10;return c;}public static voi…

Angular安全专辑之三 —— 授权绕过,利用漏洞控制管理员账户

这篇文章是针对实际项目中所出现的问题所做的一个总结。简单来说&#xff0c;就是授权绕过问题&#xff0c;管理员帐户被错误的接管。 详细情况是这样的&#xff0c;我们的项目中通常都会有用户身份验证功能&#xff0c;不同的用户拥有不同的权限。相对来说管理员账户所对应的…

openGauss学习笔记-57 openGauss 高级特性-并行查询

文章目录 openGauss学习笔记-57 openGauss 高级特性-并行查询57.1 适用场景与限制57.2 资源对SMP性能的影响57.3 其他因素对SMP性能的影响57.4 配置步骤 openGauss学习笔记-57 openGauss 高级特性-并行查询 openGauss的SMP并行技术是一种利用计算机多核CPU架构来实现多线程并行…

2023-9-2 Prim算法求最小生成树

题目链接&#xff1a;Prim算法求最小生成树 #include <iostream> #include <cstring> #include <algorithm>using namespace std;const int N 510, INF 0x3f3f3f3f;int n, m; int g[N][N]; int dist[N]; bool st[N];int prim() {memset(dist, 0x3f, size…

Qt应用开发(基础篇)——进度对话框 QProgressDialog

一、前言 QProgressDialog类继承于QDialog&#xff0c;是Qt设计用来反馈进度的对话框。 对话框QDialog QProgressDialog提供了一个进度条&#xff0c;表示当前程序的某操作的执行进度&#xff0c;让用户知道操作依旧在激活状态&#xff0c;配合按钮&#xff0c;用户就可以随时终…

qt文件操作

对话框练习 #include "widget.h" #include "ui_widget.h"Widget::Widget(QWidget *parent): QWidget(parent), ui(new Ui::Widget) {ui->setupUi(this); }Widget::~Widget() {delete ui; }//字体按钮 void Widget::on_ztbtn_clicked() {//调用QFontDia…

stable diffusion实践操作-常见lora模型介绍

本文专门开一节写Lora相关的内容&#xff0c;在看之前&#xff0c;可以同步关注&#xff1a; stable diffusion实践操作 模型分两种&#xff0c;一种是sd大模型&#xff0c;一种是类似Lora的小模型 国内的是&#xff1a;https://www.liblibai.com 国外的是&#xff1a;https:/…

TiDB Serverless Branching:通过数据库分支简化应用开发流程

2023 年 7 月 10 日&#xff0c;TiDB Serverless 正式商用。这是一个完全托管的数据库服务平台&#xff08;DBaaS&#xff09;&#xff0c;提供灵活的集群配置和基于用量的付费模式。紧随其后&#xff0c;TiDB Serverless Branching 的测试版也发布了。 TiDB Serverless Branc…

代码随想录算法训练营第二十四天|理论基础 77. 组合

理论基础 其实在讲解二叉树的时候&#xff0c;就给大家介绍过回溯&#xff0c;这次正式开启回溯算法&#xff0c;大家可以先看视频&#xff0c;对回溯算法有一个整体的了解。 题目链接/文章讲解&#xff1a;代码随想录 视频讲解&#xff1a;带你学透回溯算法&#xff08;理论篇…

Unity Android 之 在Unity 中引入 OkHttp的操作注意(OKHttp4.xx- kotlin 的包)简单记录

Unity Android 之 在Unity 中引入 OkHttp的操作注意(OKHttp4.xx- kotlin 的包)简单记录 目录 Unity Android 之 在Unity 中引入 OkHttp的操作注意(OKHttp4.xx- kotlin 的包)简单记录 一、简单介绍 二、OKHttp 4.xx 的 SDK 封装 aar 给 Unity 的使用注意 三、附录 OKHttp 的…

【记录】USSOCOM Urban3D 数据集读取与处理

Urban3D数据集内容简介 Urban3D数据集图像为正摄RGB影像&#xff0c;分辨率为50cm。 从SpaceNet上使用aws下载数据&#xff0c;文件夹结构为&#xff1a; |- 01-Provisional_Train|- GT|- GT中包含GTC&#xff0c;GTI&#xff0c;GTL.tif文件&#xff0c;GTL为ground truth b…
最新文章