• 表白墙(web版)



    前言

    前面前端部分写过一个表白墙页面,但是它不能存储提交信息,为了能够让它在提交信息后可以保存其信息,页面刷新后信息依然存在,这里通过使用js、servlet和mysql将其实现为一个web版的表白墙。


    一、需求分析

    1.表白墙页面设计

    表白墙的页面如下图所示,记录谁对谁说了什么。
    在这里插入图片描述

    2.表白墙功能

    (1)页面刷新的时候,用户提交的数据仍然存在;
    (2)服务器重新启动,用户提交的数据仍然存在。
    在这里插入图片描述

    二、实现

    代码部署如下图中的红框部分。
    在这里插入图片描述

    1.客户端

    表白墙页面的前端代码之前博客也写到过,这里只需要在添加两处内容就可以。
    (1)在表白墙页面输入信息,点击提交按钮,通过点击事件浏览器向服务器发送一个post请求,将用户输入的信息发给服务器。

    代码如下(示例):
    在button.onclick中添加上以下代码,将用户输入信息提交给服务器。
    其中data是放在body中的内容,stringify会将对象转为Json格式的字符串,和ObjectMapper中的writeValueAsString()类似。
    success是回响函数,向服务器发送请求成功,则会执行该函数。

                //4.点击提交按钮,会给服务器发送 post 请求
                let data = {
                    from: from,
                    to: to,
                    message: message
                }
                $.ajax({
                    type: 'post',
                    url: 'messageWall',
                    //stringify 将对象转为JSON格式的字符串
                    //放body的内容
                    data: JSON.stringify(data),
                    contentType: "application/json; charset=utf-8",
                    success: function(body) {
                        console.log("提交成功");
                    }
                });
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17

    (2)在页面刷新的时候或者服务器重启的时候,表白墙页面(浏览器)从服务器那通过get请求获取到以前用户输入过的信息。

    代码如下(示例):
    该函数的功能是从服务器中获取数据,将获取的数据插入到页面中。
    需要注意的是:success回响函数中,jquery在满足(contentType="application/json"和body是json数组)两个条件下自动把json数组转为对象数组。

            let div = document.querySelector('.container');
            //获取服务器数据
            function getMessage() {
                $.ajax({
                    type: 'get',
                    url: 'messageWall',
                    success: function(body) {
                        // body是响应的body的内容(Json数组)
                        //jquery 在同时满足contentType是application/json 和 body是json数组 的情况下 
                        //会自动把 json数组 转成 json对象数组
                        for(let i=0;i<body.length;i++) {
                            let message = body[i];
                            //将body中的每一数组中的每一个对象添加到页面上
                            let row = document.createElement('div');
                            row.className = "row";
                            row.innerHTML = message.from + "对" + message.to + "说" + message.message;
                            div.appendChild(row);
                        }
                    }
                });
            }
            getMessage();
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22

    2.服务器端

    服务器端主要是响应客户端发来的一个post请求,get请求。
    post请求通过重写HttpServlet中的doPost()方法,将请求数据保存到数据库中(save()方法);
    get请求通过重写HttpServlet中的doGet()方法,从数据库中获取数据(load()方法),将其数据返回给浏览器。

    代码如下(示例):

    	//ObjectMapper为Jackson的核心技术,可以调用它的方法
        public ObjectMapper objectMapper = new ObjectMapper();
        //使用集合保存提交信息
        //public ArrayList messageList = new ArrayList();
    
        //获取一个页面(含有提交信息)
        @Override
        protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
            //显示设置浏览器的响应格式,不需要让浏览器猜测
            resp.setContentType("application/json; charset=utf-8");
            //将对象信息转为json字符串写入响应返回给浏览器
            //获取数据库中的数据
            List<Message> messageList = null;
            try {
                messageList = load();
            } catch (SQLException e) {
                e.printStackTrace();
            }
            resp.getWriter().write(objectMapper.writeValueAsString(messageList));
        }
    
        //保存用户提交信息到服务器端
        @Override
        protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
            //将请求中的字符串转为对象
            Message message = objectMapper.readValue(req.getInputStream(),Message.class);
            //保存到数组中
            //messageList.add(message);
            //保存到数据库中
            try {
                save(message);
            } catch (SQLException e) {
                e.printStackTrace();
            }
            //设置响应状态
            resp.setStatus(200);
            //打印提交成功信息
            System.out.println("提交数据成功:"+message.getFrom()+"对"+message.getTo()+"说"+message.getMessage());
        }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40

    3.连接数据库

    save():主要是将请求数据放在数据库中。
    load():主要是将从数据库中获取数据。
    主要有以下步骤:
    1.获取数据源;
    2.与数据库(mysql)建立连接;
    3.构造SQL语句;
    4.执行SQL语句;
    5.关闭资源。
    由于连接数据库只需要操作一次,所以将其封装为一个单例模式(只有一个实例),采用饿汉方式涉及线程不安全,则采用synchronized保证线程安全。
    连接数据库(示例):

    //由于进行存储和读取数据时数据库只需要连接一次,则将其封装为单例模式(只有一个实例)
    public class DBUtil {
        //数据源
        private static volatile DataSource dataSource = null;
        //构造方法设为私有的,程序员在使用的时候,不小心进行new的时候会有报错提醒
        private DBUtil() {}
    
        public static DataSource getDataSource() {
            //单列模式的饿汉模式会出现线程不安全情况,这里通过使用两个if一个锁保证线程安全
            //第一个if判断是为了提高效率
            if(dataSource == null) {
                synchronized (DBUtil.class) {
                    if (dataSource == null) {
                        dataSource = new MysqlDataSource();
                        ((MysqlDataSource)dataSource).setURL("jdbc:mysql://127.0.0.1:3306/java105?characterEncoding=utf8&useSSL=false");
                        //数据库用户名和密码
                        ((MysqlDataSource)dataSource).setUser("root");
                        ((MysqlDataSource)dataSource).setPassword("xxxxxx");
                    }
                }
            }
            return dataSource;
        }
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25

    save()(示例):

        //保存用户提交信息到数据库
        private void save(Message message) throws SQLException {
            //1.获取数据源
            DataSource dataSource = DBUtil.getDataSource();
            //2.建立连接
            Connection connection = dataSource.getConnection();
    
            //3.构造SQL
            String sql = "insert into message values(?,?,?)";
            PreparedStatement statement = connection.prepareStatement(sql);
            statement.setString(1,message.getFrom());
            statement.setString(2,message.getTo());
            statement.setString(3,message.getMessage());
    
            //4.执行SQL
            int ret = statement.executeUpdate();
            System.out.println("ret = " + ret);
    
            //5.关闭资源
            statement.close();
            connection.close();
        }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22

    load()(示例):

        //获取数据库中的数据
        private List<Message> load() throws SQLException {
            //1.获取数据源
            DataSource dataSource = DBUtil.getDataSource();
            //2.建立连接
            Connection connection = dataSource.getConnection();
    
            //3.构造SQL
            String sql = "select * from message";
            PreparedStatement statement = connection.prepareStatement(sql);
    
            //4.执行SQL,并将查询结果返回
            List<Message> listMessage = new ArrayList<>();
            ResultSet resultSet = statement.executeQuery();
            while (resultSet.next()) {
                Message message = new Message();
                message.setFrom(resultSet.getString("from"));
                message.setTo(resultSet.getString("to"));
                message.setMessage(resultSet.getString("message"));
                listMessage.add(message);
            }
            return listMessage;
        }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23

  • 相关阅读:
    部署redis的读写分离架构(包含节点间认证口令)
    【华为机试真题 JAVA】最大花费金额-100
    如何解决Maven依赖冲突?
    1.openpyxl 打开工作簿
    nSoftware IPWorks IoT 2022 Java 22.0.8 Crack
    计算机毕业设计Java无人智慧药柜系统设计(源码+系统+mysql数据库+Lw文档)
    Spring的重试机制-SpringRetry
    21天打卡挑战学习MySQL——《监控神器Zabbix部署》第三周 第九篇
    简单实用的数据可视化案例
    systemctlm-cosim-demo环境搭建
  • 原文地址:https://blog.csdn.net/qq_45283185/article/details/127978678