简单的网站-表白墙(前后端交互)

提交信息后,就得到了下面的一行话

但是存在一些问题

在一个网站中,服务器起到的最主要的效果,就是 “存储数据”

因此服务器这边往往也就需要能够提供两种风格的接口。存数据 、取数据

二、实现前后端交互

1)先规定此处请求和响应的细节

1.获取消息

网页加载的时候,给服务器发起一个Ajax的请求

请求:GET /message

响应:HTTP/1/1 200 OK

Content-Type:application/json

[

        {

                from:'张三',

                to:'李四',

                message:'我喜欢你很久了'

        },

  {

                from:'王五',

                to:'赵六',

                message:'我宣你~~~'

        }

]

2.提交信息

用户点击 提交 按钮的时候,Ajax给服务器发一个请求

目的是为了把用户在输入框输入的内容,发送给服务器

请求:POST /message

Content-Type:application/json

 {

                from:'张三',

                to:'李四',

                message:'我喜欢你很久了'

 }

响应:HTTP/1.1 200 OK

2)先编写提交信息~

1.先写前端代码,发送请求

2.再写后端代码,解析请求,构造响应

3.再写前端代码,解析响应。

准备工作

创建Maven项目 message_wall

创建文件夹以及web.xml并填上内容

 pom.xml也把依赖包导入

把写好的网页 放到 webapp目录里

tomcat这样一个项目 可以包含一些html,css,js这些内容都是在webapp 目录中的

创建smart tomcat 并运行

打开浏览器输入网址

先写前端代码,发送请求

找到网页的文件用vscode打开编写 ,使用 Ajax ,需要先引入jQuery这个库

在网页里搜索jquery cdn

复制script这个标签,拷贝到head标签里(引入jquery)

 前端发起一个 ajax 请求

这个代码在点击按钮的回调函数中,在点击之后被调用到

3)服务器读取上述请求,并计算出响应

 创建MessageServlet类,重写doPost方法

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 Message{//这里定义的类,要与前端 定义的格式 匹配public String from;public String to;public String message;@Overridepublic 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<>();@Overrideprotected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {//1.读取前端发来的数据,把这个数据保存到服务器这边Message message = objectMapper.readValue(req.getInputStream(),Message.class);System.out.println("请求中收到的message:" + message);//2.存储数据:最简单的办法,直接在内存中保存,可以使用一个集合类,把所有收到的message 都存到内存中//并非很合理的办法,因为一旦重启服务器,数据就丢失了//相比之下,把数据持久化存储到数据库中,更科学messageList.add(message);//3。返回一个响应resp.setStatus(200);resp.getWriter().write("ok");}
}

4)回到前端代码,处理服务器返回的响应 

这里后端返回的ok  就会到  前端这里的回调函数 中responseBody这里

重启smart tomcat ,打开浏览器 ,查看效果

用fiddler抓包看看

到这里已经实现,数据提交到服务器保存了,目前还需要能够把服务器的数据拿回到客户端页面上,并显示

但是我们在浏览器上能看到显示的数据啊,为啥还要从服务器拿消息?

1.当前页面上显示的数据,也是在浏览器中内存保存的。

一旦 刷新或者 重新打开,之前的内容就没了

2.最期望的是,其他的客户端打开页面也是有数据的

5)客户端收到响应,就需要针对响应数据进行解析处理

把响应中的信息,构造成页面元素,并显示出来(需要拼接出html片段)

现在刷新浏览器,原有的数据还能保存,不会消失了

新开浏览器之后,之前的数据也还是在的

6)整个逻辑梳理

三、存储到数据库中

由于刚才的后端代码实现是存储到浏览器内存中,当重新启动smart servlet后,原来的数据又会消失不见

1)把数据库引入到代码中(引入依赖)

选择版本5.1.47

2)建库建表

建库建表需要用到sql,都可以写到文件中。后续如果需要把表啥的往其他的机器上迁移,建表操作就会比较方便

在main目录里创建一个sql文件(文件名可以随便起,db.sql)

将这段代码复制到mysql里,创建好库和表

并插入两条数据

3)编写数据库代码

JDBC

import com.fasterxml.jackson.databind.ObjectMapper;
import com.mysql.jdbc.jdbc2.optional.MysqlDataSource;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 javax.sql.DataSource;
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;@Overridepublic 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<>();//创建数据库的 数据源private DataSource dataSource = new MysqlDataSource();@Overridepublic void init() throws ServletException {//1.初始化数据源((MysqlDataSource)dataSource).setURL("jdbc:mysql://127.0.0.1:3306/message_wall?characterEncoding=utf8&useSSL=false");((MysqlDataSource)dataSource).setUser("root");//设置数据库的用户((MysqlDataSource)dataSource).setPassword("123456");//设置数据库用户密码}@Overrideprotected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {//1.读取前端发来的数据,把这个数据保存到服务器这边Message message = objectMapper.readValue(req.getInputStream(),Message.class);System.out.println("请求中收到的message:" + message);//2.存储数据:最简单的办法,//方法1:直接在内存中保存,可以使用一个集合类,把所有收到的message 都存到内存中//并非很合理的办法,因为一旦重启服务器,数据就丢失了//相比之下,把数据持久化存储到数据库中,更科学//messageList.add(message);//引入数据库后,这个内存临时保存的数据也可以不要了// TODO 插入数据库//方法2:引入数据库(最可靠)try {save(message);} catch (SQLException e) {throw new RuntimeException(e);}//3.返回一个响应resp.setStatus(200);resp.getWriter().write("ok");//对应前端的 回调函数 中的 responseBody
//        resp.setContentType("application/json; charset=utf8");//对应前端的 json格式
//        resp.getWriter().write("{ok:true}");}@Overrideprotected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {//通过这个方法来处理当前获取消息的列表的get请求,不需要解析参数,直接返回resp.setStatus(200);resp.setContentType("application/json; charset=utf8");//TODO 从数据库查询List<Message> messageList = null;try {messageList = load();} catch (SQLException e) {throw new RuntimeException(e);}String respJson = objectMapper.writeValueAsString(messageList);//将message这个存储的表的内容,转换成json字符串resp.getWriter().write(respJson);//返回响应}private void save(Message message) throws SQLException {//通过这个方法 把message 插入到数据库中
//        //1.创建数据源
//        DataSource dataSource = new MysqlDataSource();
//        ((MysqlDataSource)dataSource).setURL("jdbc:mysql://127.0.0.1:3306/message_wall?characterEncoding=utf8&useSSL=false");
//        ((MysqlDataSource)dataSource).setUser("root");//设置数据库的用户
//        ((MysqlDataSource)dataSource).setPassword("123456");//设置数据库用户密码//2.建立连接(connection是java.sql里的对象)Connection connection = dataSource.getConnection();//需要抛出异常//3.构造sqlString sql = "insert into message values(?,?,?)";//?是占位符PreparedStatement statement = connection.prepareStatement(sql);//构造sql语句对象statement.setString(1, message.from);//第一个占位符?替换成fromstatement.setString(2, message.to);//第二个占位符?替换成tostatement.setString(3, message.message);//第三个占位符?替换成message//4,执行sqlstatement.executeUpdate();//5.回收资源statement.close();connection.close();}private List<Message> load() throws SQLException {//通过这个方法从数据库读取到message//1.创建数据源(init方法里写了)//2.建立连接Connection connection = dataSource.getConnection();//3.构造sqlString sql = "select * from message";//查询这个表的sql语句PreparedStatement statement = connection.prepareStatement(sql);//将这个sql语句构造成一个sql语句对象//4.执行sql语句,放入到result集合里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.回收资源connection.close();statement.close();resultSet.close();//7.返回messageListreturn messageList;}
}

重启smart tomcat 看到之前在数据库插入的信息还保存着在,并且显示到浏览器上了

输入了一个新的数据

在数据库中 也能查到

 

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

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

2024最新面试跳槽,软件测试面试题的整理与解析

今天接着来说说测试工程师面试比较高频的面试题&#xff0c;大家可以通过面试题内的一些解析再结合自己的真实工作经验来进行答题思路的提取、整理。 硬背答案虽可&#xff0c;但容易翻车哦。能够举一反三才是重点&#xff01; 1&#xff1a;请介绍一下UI自动化测试中三种时间等…

ESP32 S3音频开发

1. 音频硬件框架 Codec&#xff1a;音频编解码芯片&#xff0c;一种低功耗单声道音频编解码器&#xff0c;包含单通道 ADC、单通道 DAC、低噪声前置放大器、耳机驱动器、数字音效、模拟混音和增益功能。它通过 I2S 和 I2C 总线与 ESP32-S3-WROOM-1 模组连接&#xff0c;以提供独…

【Web】DASCTF2022.07赋能赛 题解

目录 Ez to getflag Harddisk 绝对防御 Newser Ez to getflag 进来有两个功能&#xff0c;一个查看&#xff0c;一个上传 图片查看功能可以任意文件读 upload.php <?phperror_reporting(0);session_start();require_once(class.php);$upload new Upload();$upload…

最新版idea 合并分支方法

前言 以下是最新版的idea2024&#xff0c;如果有人找不到按键可能是因为版本不同。 操作步骤 看右小角我的分支是submit&#xff0c;现在我要将test合并到我的submit分支上 找到test分支&#xff0c;选择update&#xff0c;这一步会拉取相应分支内容等同于pull 选择merge 选…

SQL系统函数知识点梳理(Oracle)

这里写目录标题 函数系统函数转换函数to_date()to_char()将数值转换成字符格式 添加货币符号将日期转换成字符 其他不常用的转换函数 字符型函数连接函数大小写转换函数大写转换小写转换首字母大写&#xff0c;其余的小写 替换函数去除空格函数截取函数填充函数获取字符长度函数…

【Sql Server】锁表如何解锁,模拟会话事务方式锁定一个表然后进行解锁

大家好&#xff0c;我是全栈小5&#xff0c;欢迎来到《小5讲堂》。 这是《Sql Server》系列文章&#xff0c;每篇文章将以博主理解的角度展开讲解。 温馨提示&#xff1a;博主能力有限&#xff0c;理解水平有限&#xff0c;若有不对之处望指正&#xff01; 目录 前言创建表模拟…

图灵奖得主AviWigderson:随机性与AI深度融合,引领计算科学新篇章

近日&#xff0c;理论计算机科学领域的杰出代表Avi Wigderson教授荣获了享有“计算机界诺贝尔奖”美誉的图灵奖&#xff0c;以表彰他对计算中随机性和伪随机性研究的杰出贡献。这一荣誉不仅彰显了Wigderson教授在计算理论领域的卓越成就&#xff0c;也为当前热门的AI和深度学习…

Dubbo面试回答简单版

一、dubbo特性 超时重试机制地址缓存多版本负载均衡&#xff1a;随机、权重轮询、最少活跃调用、一致性哈希集群容错&#xff1a;失败重试、快速失败、失败安全、失败自动恢复、并行调用、广播服务降级&#xff1a;异常时返回mock 集群容错 FailOver 失败重试&#xff0c;读…

Linux——守护进程

在这篇文章中我介绍了关于tcp网络套接字&#xff0c;关于网络套接字编程的问题我会再次讲述一点东西&#xff0c;然后介绍关于守护进程的知识。 1. 关于网络套接字编程的一些问题 在进行套接字编程时我们一定是得先有套接字&#xff0c;并且我们在使用socket的一些接口时&…

阳哥推荐的人力RPO蓝海项目怎么做才会赚钱吗?

近年来&#xff0c;随着互联网的快速发展&#xff0c;人力资源行业也迎来了新的变革。抖音上的阳哥推荐的人力RPO(招聘流程外包)蓝海项目&#xff0c;因其高效、便捷的特点受到了广泛关注。那么&#xff0c;这个项目究竟怎么做才能赚钱呢? 首先&#xff0c;我们需要了解人力RP…

aws云靶场和一些杂记

aws靶场 在AWS靶场中&#xff0c;存在三个安全问题&#xff1a;1) 一个S3存储桶政策配置错误&#xff0c;允许公共访问&#xff0c;通过访问特定域名可获取flag。2) SQS消息队列的政策没有限制角色&#xff0c;允许发送和接收消息&#xff0c;通过aws sqs命令行工具的receive-…

超光速传输:有源DWDM的无限可能✊

&#x1f5fa;&#x1f5fa;随着5G时代的到来&#xff0c;支持更高数据速率、较低延迟和更大传输容量的网络设施大量铺设&#xff0c;满足了人们对高质量通信的现有要求。然而&#xff0c;传统光网络中通常每个业务通过多根光纤进行传输&#xff0c;大大降低了传输效率。为了解…

cesium JulianDate和北京时间转换

关于cesium中时间可参考&#xff1a; cesium Clock JulianDate 日照分析 修改当前时间为北京时间-CSDN博客 有几个概念需要了解一下。 1、GMT、UTC GMT是前世界标准时&#xff0c;UTC是现世界标准时&#xff0c;UTC 比 GMT更精准&#xff0c;不需要精确到秒的情况下&#xf…

太阳能智能语音卡口:环保与智能的完美结合/恒峰智慧科技

随着科技的飞速发展&#xff0c;我们的生活正在经历前所未有的变革。在这场变革中&#xff0c;太阳能智能语音卡口以其独特的魅力&#xff0c;成为环保与智能的完美结合&#xff0c;为我们的生活带来了更多的便捷和环保。 太阳能智能语音卡口&#xff0c;顾名思义&#xff0c;是…

【每日刷题】技巧合集-LC136、LC169

1. LC136.只出现一次的数字 题目链接 解法一&#xff1a; 先给数字排序&#xff0c;如果num[i]与nums[i-1]或nums[i1]都不一致&#xff0c;则返回nums[i]。 class Solution {public int singleNumber(int[] nums) {if (nums.length 1){return nums[0];}Arrays.sort(nums);fo…

基于LabVIEW的CAN通信系统开发案例

基于LabVIEW的CAN通信系统开发案例 介绍了基于LabVIEW开发的CAN通信系统&#xff0c;该系统主要用于汽车行业的数据监控与分析。通过对CAN通信协议的有效应用&#xff0c;实现了车辆控制系统的高效信息交换与实时数据处理&#xff0c;从而提升了车辆性能的检测与优化能力。 项…

Nginx内存池相关源码剖析(一)总览

剖析nginx的内存池源码&#xff0c;讲解原理实现以及该内存池设计的应用场景 介绍 Nginx内存池是Nginx为了优化内存管理而引入的一种机制。在Nginx中&#xff0c;每个层级&#xff08;如模板、TCP连接、HTTP请求等&#xff09;都会创建一个内存池进行内存管理。当这些层级的…

手动实现简易版RPC(下)

手动实现简易版RPC(下) 前言 什么是RPC&#xff1f;它的原理是什么&#xff1f;它有什么特点&#xff1f;如果让你实现一个RPC框架&#xff0c;你会如何是实现&#xff1f;带着这些问题&#xff0c;开始今天的学习。 接上一篇博客 手动实现简易版RPC&#xff08;上&#xff…

【YOLOv9】完胜V8的SOTA模型Yolov9(论文阅读笔记)

官方论文地址&#xff1a; 论文地址点击即可跳转 官方代码地址&#xff1a; GitCode - 开发者的代码家园 官方代码地址点击即可跳转 1 总述 当输入数据经过各层的特征提取和变换的时候&#xff0c;都会丢失一定的信息。针对这一问题&#xff1a; 论文中提出的可编程梯度信息…

MATLAB实现遗传算法优化BP神经网络预测数值(GABP)

遗传算法&#xff08;Genetic Algorithm, GA&#xff09;和反向传播&#xff08;Back Propagation, BP&#xff09;神经网络是两种强大的算法&#xff0c;分别用于优化和机器学习。将遗传算法与BP神经网络结合&#xff0c;可以利用遗传算法的全局搜索能力来优化BP神经网络的初始…