基于Servlet建立表白墙网站

目录

一、设计思想

二、设计表白墙页面(前端--VSCode)

1、效果图

2、html部分(网页上有哪些内容)

3、css部分(页面内容的具体样式)

4、js部分(页面行为)

三、借助Servlet实现客户端与服务器交互

1、服务器的功能

2、客户端发送数据--服务器保存并做出响应

(1)客户端发送数据(json类型请求)

(2)服务器接收数据--保存数据并发送响应给客户端

3、客户端获取当前所有表白数据--服务端响应所有数据

(1)客户端发送请求(无请求正文)

(2)服务器接收请求--将保存的所有表白数据响应给客户端

4、客户端将收到的所有数据显示到页面

四、运行效果

五、问题改进

(1)引入mysql资源依赖

(2)建表

(3)获得数据源

(4)收到客户端的post请求保存数据

(5)收到客户端的get请求返回数据


一、设计思想

二、设计表白墙页面(前端--VSCode)

1、效果图

2、html部分(网页上有哪些内容)
<body>
    <div class="container">
        <h1>表白墙</h1>
        <p>输入内容后点击提交, 信息会显示到下方表格中</p>
        <div class="row">
            <span>谁: </span>
            <input type="text">
        </div>
        <div class="row">
            <span>对谁: </span>
            <input type="text">
        </div>
        <div class="row">
            <span>说: </span>
            <input type="text">
        </div>
        <div class="row">
            <button id="submit">提交</button>
        </div>
        <div class="row">
            xxx 对 xx 说 xxxx
        </div> 
    </div>

<div class="container"> 表示一个包含内容的区域;

<div class="row"> 表示一个包含行内容的区域;

3、css部分(页面内容的具体样式)
<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>
        /* * 通配符选择器, 是选中页面所有元素 */
        * {
            /* 消除浏览器的默认样式. */
            margin: 0;
            padding: 0;
            box-sizing: border-box;
        }

        .container {
            width: 600px;
            margin: 20px auto;
        }

        h1 {
            text-align: center;
        }

        p {
            text-align: center;
            color: #666;
            margin: 20px 0;
        }

        .row {
            /* 开启弹性布局 */
            display: flex;
            height: 40px;
            /* 水平方向居中 */
            justify-content: center;
            /* 垂直方向居中 */
            align-items: center;
        }

        .row span {
            width: 80px;
        }

        .row input {
            width: 200px;
            height: 30px;
        }

        .row button {
            width: 280px;
            height: 30px;
            color: white;
            background-color: orange;
            /* 去掉边框 */
            border: none;
            border-radius: 5px;
        }

        /* 点击的时候有个反馈 */
        .row button:active {
            background-color: grey;
        }
    </style>

</head>

选中某个标准,{}里描述这个标签应该具有什么样式。

4、js部分(页面行为)
<script>
        // 实现提交操作. 点击提交按钮, 就能够把用户输入的内容提交到页面上显示. 
        // 点击的时候, 获取到三个输入框中的文本内容
        // 创建一个新的 div.row 把内容构造到这个 div 中即可. 
        let containerDiv = document.querySelector('.container');
        let inputs = document.querySelectorAll('input');
        let button = document.querySelector('#submit');
        button.onclick = function() {
            // 1. 获取到三个输入框的内容
            let from = inputs[0].value;
            let to = inputs[1].value;
            let message = inputs[2].value;
            if (from == '' || to == '' || message == '') {
                return;
            }
            // 2. 构造新 div
            let rowDiv = document.createElement('div');
            rowDiv.className = 'row message';
            rowDiv.innerHTML = from + ' 对 ' + to + ' 说: ' + message;
            containerDiv.appendChild(rowDiv);
            // 3. 清空之前的输入框内容
            for (let input of inputs) {
                input.value = '';
            }
        }
</script>

通过js代码可以实现网页和用户以及网页和服务器的交互。(以上代码还未实现和服务器的交互)

三、借助Servlet实现客户端与服务器交互

1、服务器的功能

以上代码也可以实现表白墙的功能,但是发现未和服务器建立连接,数据保存在浏览器内存里,刷新浏览器数据就会消失,且该客户端也看不到上一个客户端的留言,所以就要和服务器进行交互。

服务器的功能:(1)页面加载的时候要获取到当前表白数据,由服务器响应发送;(2)客户端发送数据时,服务器要接受并保存数据。

2、客户端发送数据--服务器保存并做出响应
(1)客户端发送数据(json类型请求)

①规定请求为json类型,方法为post,请求正文样子:

{
  "from":from,
  "to":to,
  "message":message
}

在点击提交按钮后,发送数据给服务端,即在function函数里实现。需要引入第三方库:jquery库

②实现代码(VSCode--js语言)

// 4. 把用户填写的内容, 发送给服务器. 让服务器来保存. 
            //    $ 是 jquery 提供的全局变量. ajax 就是 $ 的一个方法. 
            //    ajax 的参数是一个 js 对象, 可以有很多属性
            let requestBody = {
                "from": from,   // from 变量里的值, 就是第一个输入框的内容, "张三"
                "to": to,       // to 变量的值, 就是第二个输入框的内容, "李四"
                "message": message  // message 变量的值, 就是第三个输入框的内容, "我喜欢你很久了"
            };
            // 上述 body 是一个 js 对象, 还需要转成 json 字符串. 
            let jsonRequest = JSON.stringify(requestBody);
            $.ajax({
                type: 'post',
                url: 'message',
                contentType: 'application/json; charset=utf8',
                data: jsonRequest,
                success: function(responseBody) {
                    // 这个回调就是收到响应之后要执行的代码了. 
                    // 前端使用 console.log 打印日志到控制台. (chrome 开发者工具的控制台)
                    console.log("responseBody: " + responseBody);
                }
            });
(2)服务器接收数据--保存数据并发送响应给客户端

①服务器需要把请求正文json字符串转为java对象,且把请求上传的数据增加到列表中,给客户端响应一个json字符串,响应正文为:

{
  "ok" : "true"
}

②实现代码(IDEA--java语言)

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.util.ArrayList;
import java.util.List;

class Request{  //请求正文json字符串转为java对象
    public String from;
    public String to;
    public String message;

    @Override
    public String toString() {
        return "Request{" +
                "from='" + from + '\'' +
                ", to='" + to + '\'' +
                ", message='" + message + '\'' +
                '}';
    }
}

class Response{
    public boolean ok;
}

@WebServlet("/message")
public class messageServlet extends HttpServlet{
    List<Request> list=new ArrayList<>();
    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        ObjectMapper objectMapper=new ObjectMapper();
        Request request=objectMapper.readValue(req.getInputStream(),Request.class); //转为java对象
        System.out.println("请求内容:"+request);
        list.add(request); //保存数据
        resp.setStatus(200); //响应返回一个状态码
        Response response=new Response(); //响应的java对象
        response.ok=true;
        String jsonResponse=objectMapper.writeValueAsString(response); //响应转为json字符串
        resp.setContentType("application/json;charset=utf8");
        resp.getWriter().write(jsonResponse);
    }
}
3、客户端获取当前所有表白数据--服务端响应所有数据
(1)客户端发送请求(无请求正文)

①请求方法为get方法,加载页面时发送该请求。

②实现代码(VSCode--js语言)

  // 直接在 script 里面写的 js 代码, 就是在页面加载时被执行到的. 
        // 发起一个 get 请求, 从服务器获取到数据
        // get 请求不需要 body, 也就不需要上述 data 和 contentType 属性了. 
        $.ajax({
            type:'get',
            url:'message',
            success:function(body){
                //这个回调就是收到响应之后要执行的代码了. 
                //客户端将收到的所有数据显示到页面
            }
        })

客户端收到响应后,显示数据的代码下一步实现。

(2)服务器接收请求--将保存的所有表白数据响应给客户端

①服务器需要将保存数据的数组转为json数组,将json数组响应给客户端,

②实现代码(IDEA--java语言)

 protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        ObjectMapper objectMapper=new ObjectMapper();
        resp.setStatus(200);  //响应返回一个状态码
        resp.setContentType("application/json;charset=utf8");
        String jsonResponse=objectMapper.writeValueAsString(list); //jackson支持把一个数组对象转为json数组
        resp.getWriter().write(jsonResponse);
    }
4、客户端将收到的所有数据显示到页面

①客户端将收到的所有表白数据显示在页面上,在success:function(body){}回调函数中实现;

②响应中header中带有:Content-Type:appliaction/json,jquery库就会自动把响应的json正文转为js对象。eg:resp.setContentType("application/json;charset=utf8");

若响应中header中没有:Content-Type:appliaction/json,客户端拿到响应后,在回调函数中就会调用body = JSON.parse(body) ;

③实现代码(VSCode--js语言)

success: function(body) {
                //这个回调就是收到响应之后要执行的代码了. 
                //客户端将收到的所有数据显示到页面
                // 由于响应中已经有 Content-Type: application/json 了, 就不需要使用 parse 方法手动转换了.  
                // body = JSON.parse(body);

                // 拿到 container 这个元素
                let containerDiv = document.querySelector('.container');
                // 处理服务器返回的响应数据. (json 格式的数组了)
                for (let i = 0; i < body.length; i++) {
                    // body 是一个数组, 此时 message 也就是 js 对象了. 
                    // 这个 message 对象里, 有三个属性, from, to, message
                    let message = body[i];

                    // 根据 message 对象构建 html 片段, 把这个片段给显示到网页上. 
                    // createElement 方法就能构造出一个 html 标签. 
                    // 此时就得到了 <div></div> 
                    let div = document.createElement('div');
                    // 还需要往里面设置一个 属性 , class="row" (设置这个属性, 是为了让 css 能够给这个元素设置一些样式)
                    // 此时就得到了 <div class="row"></div>
                    div.className = 'row';
                    // 给这个 div 里设置内容
                    // 此时就得到了 <div class="row">张三 对 李四 说: 我喜欢你很久了</div>
                    div.innerHTML = message.from + " 对 " + message.to + " 说: " + message.message;
                    // 把 div 添加到 containerDiv 的末尾
                    containerDiv.appendChild(div);
                }
            }

四、运行效果

需注意:需要将前端代码放在webapp包中(IDEA)

效果图

刷新或者重新打开页面,数据依旧存在。

五、问题改进

上述虽然实现了基于服务器的通信,但是若后台服务器停止运行,则所有的数据也都没有了,所以我们需要将数据存在数据库里,即使服务器停止运行了,再次重启时数据依然存在。

(1)引入mysql资源依赖

(2)建表

message表,里面有from、to、message属性。

create database if not exists message_wall charset utf8;
use message_wall;
-- 删表目的是为了, 防止之前数据库里有一样的表, 对咱们的代码产生干扰.
drop table if exists message;
create table message (`from` varchar(1024), `to` varchar(1024), message varchar(1024));

(3)获得数据源
private DataSource datasource=new MysqlDataSource(); //导入数据源 向上转型
    @Override
    //获取数据源--在HttpServlet被实例化后调用该方法
    public void init() throws ServletException {
        ((MysqlDataSource) datasource).setUrl("jdbc:mysql://127.0.0.1:3306/message_wall?characterEncoding=utf8&useSSL=false");
        ((MysqlDataSource) datasource).setUser("root");  //用户名
        ((MysqlDataSource) datasource).setPassword("272222"); //密码
    }
(4)收到客户端的post请求保存数据
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        ObjectMapper objectMapper=new ObjectMapper();
        Request request=objectMapper.readValue(req.getInputStream(),Request.class); //转为java对象
        System.out.println("请求内容:"+request);
        try {
            save(request);//保存数据
        } catch (SQLException e) {
            throw new RuntimeException(e);
        }
        resp.setStatus(200); //响应返回一个状态码
        Response response=new Response(); //响应的java对象
        response.ok=true;
        String jsonResponse=objectMapper.writeValueAsString(response); //响应转为json字符串
        resp.setContentType("application/json;charset=utf8");
        resp.getWriter().write(jsonResponse);
    }
 private void save(Request request) throws SQLException {
        //建立连接
        Connection connection=datasource.getConnection();
        //创建执行语句
        String sql="insert into message values(?,?,?)"; //?是通配符
        //转成服务器能看懂的语句 客户端已提前解析好,mysql直接运行
        PreparedStatement statement=connection.prepareStatement(sql);
        statement.setString(1,request.from);  //第一个问号内容
        statement.setString(2,request.to);    //第二个问号内容
        statement.setString(3,request.message);  //第三个问号内容
        //执行sql语句
        statement.executeUpdate();
        //回收资源
        statement.close();
        connection.close();
    }
(5)收到客户端的get请求返回数据
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        List<Request> list=null;
        ObjectMapper objectMapper=new ObjectMapper();
        resp.setStatus(200);  //响应返回一个状态码
        resp.setContentType("application/json;charset=utf8");
        try {
            list=load();
        } catch (SQLException e) {
            throw new RuntimeException(e);
        }
        String jsonResponse=objectMapper.writeValueAsString(list); //jackson支持把一个数组对象转为json数组
        resp.getWriter().write(jsonResponse);
    }
private List<Request> load() throws SQLException {
        //建立连接
        Connection connection=datasource.getConnection();
        //创建执行语句
        String sql="select * from message";
        //转成服务器能看懂的语句 客户端已提前解析好,mysql直接运行
        PreparedStatement statement=connection.prepareStatement(sql);
        //执行sql语句
        ResultSet resultSet=statement.executeQuery();
        //添加到返回数组
        List<Request> list1=new ArrayList<>();
        while (resultSet.next()){
            Request request=new Request();
            request.from=resultSet.getString("from");
            request.to=resultSet.getString("to");
            request.message=resultSet.getString("message");
            list1.add(request);
        }
        return list1;
    }

服务器重启后,数据依旧存在。

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

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

相关文章

攻防世界——Mysterious

运行就是一个要你输入的题型&#xff0c;这种题我们要么得到password&#xff0c;要么直接不管这个得到flag int __stdcall sub_401090(HWND hWnd, int a2, int a3, int a4) {int v4; // eaxchar Source[260]; // [esp50h] [ebp-310h] BYREF_BYTE Text[257]; // [esp154h] [eb…

4.postman批量运行及json、cvs文件运行

一、批量运行collection 1.各个接口设置信息已保存&#xff0c;在collection中点击run collection 2.编辑并运行集合 集合运行时&#xff0c;单独上传图片时报错。需修改postman设置 二、csv文件运行 可新建记事本&#xff0c;输入测试数据&#xff0c;后另存为新的文本文件&…

call_once 单例模式 Singleton / condition_variable 与其使用场景

一、call_once 单例模式 Singleton 大家可以先看这篇文章&#xff1a;https://zh.cppreference.com/w/cpp/thread/call_once /*std::call_oncevoid call_once( std::once_flag& flag, Callable&& f, Args&&... args ); */ #include <iostream> #i…

【算法与数据结构】474、LeetCode一和零

文章目录 一、题目二、解法三、完整代码 所有的LeetCode题解索引&#xff0c;可以看这篇文章——【算法和数据结构】LeetCode题解。 一、题目 二、解法 思路分析&#xff1a;本题要找strs数组的最大子集&#xff0c;这个子集最多含有 m m m个0和 n n n个1。本题也可以抽象成一个…

云仓酒庄的品牌雷盛红酒LEESON分享从事酒行业有前途吗?

化在全球都有着悠久的传承文化&#xff0c;每逢传统节日&#xff0c;新朋好友相聚庆贺&#xff0c;酒在好多场合都是不可或缺的选项。酒的消费群体也是十分庞大&#xff0c;有不少朋友问云仓酒庄&#xff0c;从事酒的行业能不能挣钱&#xff0c;有没有前途&#xff1f;回答好这…

【Qt之模型视图】1. 模型和视图架构

1. 模型/视图架构是什么及有什么用 MVC&#xff08;Model-View-Control&#xff09;是一种源自Smalltalk的设计模式&#xff0c;通常用于构建用户界面。 MVC由三种类型的对象组成。模型是应用对象&#xff0c;用来表示数据&#xff1b;视图是模型的用户界面&#xff0c;用来显…

Windows 拦截系统睡眠、休眠

前言 在前一篇文章中&#xff0c;我们分析了以编程方式拦截 Winlogon 相关回调过程的具体做法&#xff0c;我们给出了一种拦截 RPC 异步回调的新方法——通过过滤特征码&#xff0c;我们可以对很多系统热键以及跟电源有关的操作做出“提前”响应。但是我们给出的代码并不能真正…

代码随想录第十八天 513 找树左下角的值 112 路径之和 106 从中序与后序遍历序列构造二叉树

LeetCode 513 找树左下角的值 题目描述 给定一个二叉树的 根节点 root&#xff0c;请找出该二叉树的 最底层 最左边 节点的值。 假设二叉树中至少有一个节点。 示例 1: 输入: root [2,1,3] 输出: 1示例 2: 输入: [1,2,3,4,null,5,6,null,null,7] 输出: 7 思路 1.确定递…

matlab appdesigner系列-常用14-树(复选框)

之前系列常用9&#xff0c;为单个复选框。树&#xff0c;就是多个复选框形成的选项组 示例&#xff1a;列举湖北省的几个城市 湖北省 武汉 宜昌 襄阳 荆州 1&#xff09;将树&#xff08;复选框&#xff09;拖拽到画布上&#xff0c;方式1就是&#xff1a;文字可以在右侧…

课题学习(十九)----Allan方差:陀螺仪噪声分析

一、介绍 Allan方差是一种分析时域数据序列的方法&#xff0c;用于测量振荡器的频率稳定性。该方法还可用于确定系统中作为平均时间函数的本征噪声。该方法易于计算和理解&#xff0c;是目前最流行的识别和量化惯性传感器数据中存在的不同噪声项的方法之一。该方法的结果与适用…

131. 分割回文串 - 力扣(LeetCode)

问题描述 给你一个字符串 s&#xff0c;请你将 s 分割成一些子串&#xff0c;使每个子串都是 回文串 。返回 s 所有可能的分割方案。 回文串 是正着读和反着读都一样的字符串。 输入示例 s "aab"输出示例 [["a","a","b"],["…

PS滤镜插件:Adobe Camera Raw 16 for Mac中文激活版

Adobe Camera Raw是Adobe公司开发的一款用于处理数码相机RAW格式文件的软件插件。它可以在Adobe Photoshop、Adobe Bridge和Adobe Lightroom等软件中使用&#xff0c;用于调整RAW文件的曝光、白平衡、对比度、色彩饱和度、锐化等参数&#xff0c;从而得到更好的图像质量。 软件…

STM32之模数转换器(ADC)

一、模数转换器介绍 1、模数转换器简介 为什么使用模拟转换器&#xff1f;&#xff1f; 因为MCU只能识别01010101的数字信号&#xff0c;而外部物理信号均为模拟信号&#xff0c;如声音、光、电等&#xff0c;所以为了让计算机能够处理外部物理的信息&#xff0c;必须要通过…

增加CO气体报警、氢气报警以及烟雾报警

标题&#xff1a;增加CO气体报警、氢气报警以及烟雾报警。 内容&#xff1a;通过ADC采集通道&#xff0c;实现传感器电压的采集&#xff0c;通过对电压进行判断是否报警&#xff0c;&#xff08;理论上应该可以计算出气体浓度&#xff0c;通过气体浓度来判断是否报警&#xff…

入门分布式事务,2PC 3PC

分布式事务 什么是分布式一致性 在分布式系统中&#xff0c;为了保证数据的高可用&#xff0c;通常&#xff0c;我们会将数据保留多个副本(replica)&#xff0c;这些副本会放置在不同的物理的机器上。为了对用户提供正确的增\删\改\查等语义&#xff0c;我们需要保证这些放置…

VRRP协议负载分担

VRRP流量负载分担 VRRP负载分担与VRRP主备备份的基本原理和报文协商过程都是相同的。同样对于每一个VRRP备份组,都包含一个Master设备和若干Backup设备。与主备备份方式不同点在于:负载分担方式需要建立多个VRRP备份组,各备份组的Master设备可以不同;同一台VRRP设备可以加…

骑砍战团MOD开发(39)-RTS塔防保卫卡拉迪亚大陆

骑砍1战团mod开发-RTS塔防保卫卡拉迪亚大陆_哔哩哔哩bilibili_骑马与砍杀https://www.bilibili.com/video/BV1hw411E7bP/骑砍战团MOD开发(28)-骑砍联盟之RTS大规模军团竞技-CSDN博客文章浏览阅读369次&#xff0c;点赞11次&#xff0c;收藏7次。【代码】骑砍战团MOD开发(28)-骑…

SpringCloud Alibaba 深入源码 - Nacos 分级存储模型、支撑百万服务注册压力、解决并发读写问题(CopyOnWrite)

目录 一、SpringCloudAlibaba 源码分析 1.1、SpringCloud & SpringCloudAlibaba 常用组件 1.2、Nacos的服务注册表结构是怎样的&#xff1f; 1.2.1、Nacos的分级存储模型&#xff08;理论层&#xff09; 1.2.2、Nacos 源码启动&#xff08;准备工作&#xff09; 1.2.…

java steam 的使用

说steam 前看下kotlin的一个写法如果用java怎么写 fun main() {// 创建一个列表val fruits listOf("Apple", "Banana", "Cherry", "Date", "Elderberry")// 使用 Sequence 进行过滤和映射操作val uppercaseFruitLengths …

《机器学习》客户流失判断-python实现

客户流失判断 题目赛题描述数据说明赛题来源-DataCastle 问题描述解题思路Python实现读取数据并初步了解导入宏包读取数据查看数据类型检查缺失值描述性统计分析 可视化分析用户流失分析特征分析任期年数与客户流失的关系&#xff1a;服务类属性分析特征相关性分析 数据预处理类…
最新文章