文章目录
- 前言
- 一、需求分析
- 1.表白墙页面设计
- 2.表白墙功能
- 二、实现
- 1.客户端
- 2.服务器端
- 3.连接数据库
前言
前面前端部分写过一个表白墙页面,但是它不能存储提交信息,为了能够让它在提交信息后可以保存其信息,页面刷新后信息依然存在,这里通过使用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("提交成功");
}
});
(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();
2.服务器端
服务器端主要是响应客户端发来的一个post请求,get请求。
post请求通过重写HttpServlet中的doPost()方法,将请求数据保存到数据库中(save()方法);
get请求通过重写HttpServlet中的doGet()方法,从数据库中获取数据(load()方法),将其数据返回给浏览器。
代码如下(示例):
//ObjectMapper为Jackson的核心技术,可以调用它的方法
public ObjectMapper objectMapper = new ObjectMapper();
//使用集合保存提交信息
//public ArrayList<Message> messageList = new ArrayList<Message>();
//获取一个页面(含有提交信息)
@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());
}
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;
}
}
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();
}
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;
}