提交信息后,就得到了下面的一行话
但是存在一些问题
在一个网站中,服务器起到的最主要的效果,就是 “存储数据”
因此服务器这边往往也就需要能够提供两种风格的接口。存数据 、取数据
二、实现前后端交互
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 看到之前在数据库插入的信息还保存着在,并且显示到浏览器上了
输入了一个新的数据
在数据库中 也能查到