用Servlet实现一个简单的表白墙

news2024/11/24 2:49:56

1. 准备工作

创建项目,引入依赖......

将静态页面放到项目中(放在webapp目录下):


当前,这个表白墙页面,已经可以输入内容,点击提交之后也能显示内容,后续后端要做的工作即:

①存档

用户点提交的时候,把刚才输入的内容通过网络传输给服务器,由服务器保存这个数据.

②读档

后续有页面加载的时候,此时就通过网络,从服务器获取到之前保存好的内容.

都需要进行前后端交互接口的约定.

约定好,前端会给后端发起一个什么样的HTTP请求,后端返回什么样的HTTP响应.


html中的每个元素,同时都可以映射到js中的一个对象.(文档-对象模型)

通过对象的属性,就能获取到页面的内容.

修改对象的属性,也就能更新页面的内容.

2. 后端操作

非持久化保存数据: 

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

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


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

    private ObjectMapper objectMapper = new ObjectMapper();

    //此处把消息保存到内存中(一旦重启服务器,内存数据就没了)
    private List<Message> messageList = new ArrayList<>();    //更科学的方式,应该是保存到数据库中

    //用来实现存档操作
    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        //1.读取请求的body,转换成Java对象
        Message message = objectMapper.readValue(req.getInputStream(),Message.class);
        //2.得到message之后,把message保存到服务器中
        messageList.add(message);
        System.out.println("服务器收到message: "+ message );
        //3.返回响应(不太必要,主要是返回一个200 OK就行了,body可以没有)
        resp.setStatus(200);
        resp.getWriter().write("ok");
    }


    //用来实现读档操作
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        //把我们内存中的这些Message,组织成json格式,返回到响应中.
        String respJson = objectMapper.writeValueAsString(messageList);
        //告诉浏览器,返回的响应的body是一个json格式.
        resp.setContentType("application/json;charset=utf8");
        resp.getWriter().write(respJson);
    }
}

持久化保存数据:

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

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


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

    private ObjectMapper objectMapper = new ObjectMapper();

    //此处把消息保存到内存中(一旦重启服务器,内存数据就没了)
    //private List<Message> messageList = new ArrayList<>();    //更科学的方式,应该是保存到数据库中

    //用来实现存档操作
    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        //1.读取请求的body,转换成Java对象
        Message message = objectMapper.readValue(req.getInputStream(),Message.class);
        //2.得到message之后,把message保存到服务器中
        //messageList.add(message);
        try {
            save(message);
        } catch (SQLException e) {
            e.printStackTrace();
        }
        System.out.println("服务器收到message: "+ message );
        //3.返回响应(不太必要,主要是返回一个200 OK就行了,body可以没有)
        resp.setStatus(200);
        resp.getWriter().write("ok");
    }




    //用来实现读档操作
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        //把我们内存中的这些Message,组织成json格式,返回到响应中.
        List<Message> messageList = null;
        try {
            messageList = load();
        } catch (SQLException e) {
            e.printStackTrace();
        }

        String respJson = objectMapper.writeValueAsString(messageList);
        //告诉浏览器,返回的响应的body是一个json格式.
        resp.setContentType("application/json;charset=utf8");
        resp.getWriter().write(respJson);
    }

    //通过jdbc,往数据库中存一个数据.
    private void save(Message message) throws SQLException {
        //1.创建数据源
        DataSource dataSource = new MysqlDataSource();
        ((MysqlDataSource)dataSource).setUrl("jdbc:mysql://127.0.0.1:3306/java108?characterEncoding=utf8&useSSL=false");
        ((MysqlDataSource) dataSource).setUser("root");
        ((MysqlDataSource) dataSource).setPassword("808250");

        //2.建立连接
        Connection connection = dataSource.getConnection();
        //3.构造SQL
        String sql = "insert into message values(?,?,?)";
        PreparedStatement statement = connection.prepareStatement(sql);
        statement.setString(1,message.from);
        statement.setString(2,message.to);
        statement.setString(3,message.message);
        //4.执行SQL
        statement.executeUpdate();
        //5.释放资源,关闭连接
        statement.close();
        connection.close();

    }

    private List<Message> load() throws SQLException {
        //1.创建数据源
        DataSource dataSource = new MysqlDataSource();
        ((MysqlDataSource)dataSource).setUrl("jdbc:mysql://127.0.0.1:3306/java108?characterEncoding=utf8&useSSL=false");
        ((MysqlDataSource) dataSource).setUser("root");
        ((MysqlDataSource) dataSource).setPassword("808250");

        //2.建立连接
        Connection connection = dataSource.getConnection();
        //3.构造SQL
        String sql = "select * from message";
        PreparedStatement statement = connection.prepareStatement(sql);
        //4.执行SQL
        ResultSet resultSet = statement.executeQuery();
        //5.遍历结果集合
        List<Message> messageList = new ArrayList<>();
        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);
        }
        //6.关闭连接,释放资源
        resultSet.close();;
        statement.close();
        connection.close();
        return messageList;
    }
}

2.1 存档(非持久化保存数据) 

针对存档操作来说,前端发起一个HTTP请求.

此处约定使用json格式,把数据输出到后端.

让服务器返回一个HTTP响应. HTTP/1.1 200OK.


当前这个程序并不能在服务器重启之后保存数据,也就是把数据保存在了内存里,这样的设定并不科学.应该让数据持久化保存.

在刚才的代码基础上,引入数据库,来保存上述数据.

2.2 读档

前端页面加载的时候,需要从服务器拿到之前已经提交的数据.

响应的json应该是数组了,返回的数据会有多条.


2.3 用数据库-持久化保存数据

 2.3.1 引入数据库的依赖(驱动包)
<!-- https://mvnrepository.com/artifact/mysql/mysql-connector-java -->
<dependency>
    <groupId>mysql</groupId>
    <artifactId>mysql-connector-java</artifactId>
    <version>8.0.32</version>
</dependency>
2.3.2 创建数据库,创建数据表

2.3.3 编写代码 

JDBC操作数据库,完成这里的数据存和取.

3. 前端操作

3.1 "存档"请求

 


先让js代码发起"存档"请求.

需要前端和后端通过HTTP交互,使用ajax.

 


 

这个相对路径的基准路径,就是当前HTML所在的路径.

写了相对路径message,就相当于在message基础上,加上一层/messageWall

一般会优先写作相对路径的方式.

后续如果要修改context path就比较方便,对于代码影响比较小了.



用户点击提交按钮,触发js提交数据的代码.

1.ajax方法会根据输入的参数,构造出HTTP请求,发给服务器.

2.服务器就会执行到对应的doPost方法.

3.响应回来之后,执行刚才设置好的success回调函数.


 

回调函数,其实是有三个参数的.

success(result,status,xhr)

对于JS的函数来说,参数如果不用,可以不写.

这里的body是形参,名字无所谓,一个参数的时候,就表示响应的body.

这个操作是把收到的数据显示到浏览器的控制台上,而不是页面上.


3.2 "读档"请求


此时也需要把这个json字符串,反向转换回js对象数组.

但是,实际上,jquery自动帮我们做好了这里的解析操作.

此时,形参body,已经是js的对象数组了,不需要使用JSON.parse进行解析.


4. 修改代码后,重启服务器没反应

4.1 先抓包

通过抓包,就能先把问题确定出,是前端还是后端的问题.

如果抓包发现,ajax的HTTP请求就没发出来,大概率是前端的问题.

如果发出来了,并且内容符合要求,大概率是后端的问题.

4.2 关注前端代码(HTTP请求没发出来)

此时更需要关注的是,浏览器里的情况.(js代码都是被下载到浏览器中,并执行的)

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

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

相关文章

什么是EDM邮件推广营销?

电子邮件作为最古老的互联网沟通工具之一&#xff0c;凭借其无可比拟的直达性、个性化潜力与高投资回报率&#xff0c;始终占据着企业营销策略的核心地位。随着人工智能技术的革新应用&#xff0c;云衔科技以其前瞻视野与深厚技术底蕴&#xff0c;倾力打造了一站式智能EDM邮件营…

标定系列——预备知识-OpenCV中相机标定相关函数(十一)

标定系列——预备知识-OpenCV中相机标定相关函数&#xff08;十一&#xff09; 说明记录 说明 对相机标定过程中使用的函数进行记录 记录

Dual Relation Knowledge Distillation for Object Detection用于目标检测的双关系知识蒸馏

摘要 有两个关键点导致检测任务的蒸馏性能不佳。一是前景和背景特征严重不平衡&#xff0c;二是小对象缺乏足够的特征表示。为了解决上述问题&#xff0c;我们提出了一种新的知识蒸馏方法——双关系知识蒸馏&#xff08;DRKD&#xff09;&#xff0c;包括逐像素关系蒸馏和逐实…

鸿蒙Lottie动画-实现控制动画的播放、暂停、倍速播放、播放顺序

介绍 本示例展示了lottie对动画的操作功能。引入Lottie模块&#xff0c;实现控制动画的播放、暂停、倍速播放、播放顺序、播放到指定帧停止或从指定帧开始播放、侦听事件等功能&#xff0c;动画资源路径必须是json格式。 效果预览 使用说明&#xff1a; 进入页面默认开始201…

【Python刷题】将有序数组转换为二叉搜索树

问题描述 给你一个整数数组 nums &#xff0c;其中元素已经按 升序 排列&#xff0c;请你将其转换为一棵 平衡 二叉搜索树。 高度平衡的意思是&#xff1a;二叉树是一颗满足“每个结点的左右两个子树的高度差的绝对值不超过1”的二叉树。 示例 1&#xff1a; 输入&#xf…

MVC与三层架构理解

1. JSP的发展 早期只有Servlet&#xff0c;只能使用response输出标签数据&#xff0c;非常麻烦后来。JSP的出现&#xff0c;简化了 Servlet的开发。但是过度的使用JSP&#xff0c;在JSP中写大量的java代码&#xff0c;又前端的页面&#xff0c;造成难以维护&#xff0c;难于分…

pytorch-tpu/llama推理优化之input prompt bucketing

数据更新&#xff1a; python脚本&#xff08;注意分支&#xff09;&#xff1a; HLO图分析KV-Cache更新&#xff1a; KV-Cache作为HLO图的输入输出&#xff1a;bf16[1,2048,32,128]{3,2,1,0} 128x, 2x32x2 参考链接 notes for transformer introduction by an Italian t…

HUAWEI 华为交换机 配置 Eth-Trunk 接口流量本地优先转发示例(堆叠)

组网需求 说明 S5720I-10X-PWH-SI-AC 和 S5720I-6X-PWH-SI-AC 不支持此配置。 如 图 3-23 所示&#xff0c;为了增加设备的容量采用设备堆叠技术&#xff0c;将 Switch3 和 Switch4通过专用的堆叠电缆链接起来&#xff0c;对外呈现为一台逻辑交换机。为了实现设备间的备份、…

四、MySQL数据库基础(约束详解!)

一、约束 &#xff08;一&#xff09;约束概述 1.概念:约束是作用于表中字段上的规则&#xff0c;用于限制存储在表中的数据。 2.目的:保证数据库中数据的正确、有效性和完整性。 3。分类&#xff1a; 注意:约束是作用于表中字段上的&#xff0c;可以在创建表/修改表的时候添…

OpenHarmony实战开发-如何使用rating组件实现星级打分功能。

介绍 本篇Codelab将引导开发者使用rating组件实现星级打分功能。 相关概念 rating组件&#xff1a;评分条&#xff0c;可根据用户判断进行打分。 环境搭建 软件要求 DevEco Studio版本&#xff1a;DevEco Studio 3.1 Release及以上版本。OpenHarmony SDK版本&#xff1a;A…

vuepress-theme-hope 添加谷歌统计代码

最近做了个网站,从 cloudflare 来看访问量,过去 30 天访问量竟然有 1.32k 给我整懵逼了,我寻思不应该呀,毕竟这个网站内容还在慢慢补充中,也没告诉别人,怎么就这么多访问?搜索了下, cloudflare 还会把爬虫的请求也就算进来,所以数据相对来说就不是很准确 想到了把 Google An…

css酷炫边框

边框一 .leftClass {background: #000;/* -webkit-animation: twinkling 1s infinite ease-in-out; 1秒钟的开始结束都慢的无限次动画 */ } .leftClass::before {content: "";width: 104%;height: 102%;border-radius: 8px;background-image: linear-gradient(var(…

稀碎从零算法笔记Day36-LeetCode:H指数

有点绕的一个题&#xff0c;题目描述的有点奇怪&#xff08;可以看下英文&#xff1f;&#xff09; 题型&#xff1a;数组、模拟 链接&#xff1a;274. H 指数 - 力扣&#xff08;LeetCode&#xff09; 来源&#xff1a;LeetCode 题目描述 给你一个整数数组 citations &am…

如何查找局域网内连接设备的IP地址?

如何查找局域网内连接设备的IP地址? 第一种方法:通过CMD指令 在电脑开始菜单中找到运行,点击打开,输入CMD,然后回车,如下图所示, 如下图所示,输入ipconfig/all,然后回车, 如下图所示,此时会扫描出所有的连接设备的IP地址、MAC地址以及网关等信息, 这时候在cmd命令窗…

php反序列化漏洞——phar反序列化漏洞

一.什么是phar文件 类比java语言 JAR是开发Java程序一个应用&#xff0c;包括所有的可执行、可访问的文件&#xff0c;都打包进了一个JAR文件里使得部署过程十分简单。 PHAR("Php ARchive")是PHP里类似于JAR的一种打包文件 对于PHP 5.3 或更高版本&#xff0c;Ph…

前端常用代码整理— js,jquery篇(3)

目录 1.判断是否是json字符串 2.获取当前网址 3.将文本复制到剪贴板 4.获取一个月的天数 5.展平数组 6.要修改getRandomItem函数以返回数组中的随机两个元素&#xff0c;可以尝试以下代码 1.判断是否是json字符串 const isJson str > {try {JSON.parse(str);return …

STM32之HAL开发——QSPI协议介绍

QSPI协议 OSPI是Oueued SPl的简写&#xff0c;是Motorola公司推出的 SPI接口的扩展&#xff0c;比SPI应用更加广泛。在 SPI协议的基础上&#xff0c;Motorola公司对其功能进行了增强&#xff0c;增加了队列传输机制&#xff0c;推出了队列串行外围接口协议(即 OSPI协议)。OSPI…

微服务(基础篇-008-es、kibana安装)

目录 05-初识ES-安装es_哔哩哔哩_bilibilihttps://www.bilibili.com/video/BV1LQ4y127n4?p81&vd_source60a35a11f813c6dff0b76089e5e138cc 1.部署单点es 1.1.创建网络 1.2.加载镜像 1.3.运行 2.部署kibana 2.1.部署 2.2.DevTools 3.安装IK分词器 3.1.在线安装ik…

机器学习 - 手动实现 ReLU 和 Sigmoid

直接上代码 import torch import matplotlib.pyplot as pltA torch.arange(-10, 10, 1, dtypetorch.float(32)) def relu(x):return torch.maximum(torch.tensor(0), x) plt.plot(relu(A))结果如下&#xff1a; import torch import matplotlib.pyplot as pltA torch.aran…

基于架构的软件开发方法_1.概述和相关概念及术语

1.体系结构的设计方法概述 基于体系结构的软件设计&#xff08;Architecture-Based Software Design&#xff0c;ABSD&#xff09;方法。ABSD方法是由体系结构驱动的&#xff0c;即指由构成体系结构的商业、质量和功能需求的组合驱动的。 使用ABSD方法&#xff0c;设计活动可以…