目录
1.猜数字
这里只是用JS实现了一下逻辑,没有用CSS修改样式
<!DOCTYPE html>
<html lang="en">
<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>
</head>
<body>
<button id="resetBtn">重新开始一局游戏</button> <br>
<span>要猜的数字:</span>
<input type="text">
<button id="guessBtn">猜</button> <br>
<span>已经猜的次数:</span> <span id="guessCount">0</span> <br>
<span>结果:</span> <span id="result"></span>
<script>
//1. 先拿到上面的元素
let resetBtn = document.querySelector('#resetBtn');
let input = document.querySelector('input');
let guessBtn = document.querySelector('#guessBtn');
let resultSpan = document.querySelector('#result');
let guessCountSpan = document.querySelector('#guessCount');
//2. 生成一个 1-100 的随机整数,然后向下取整
let toGuess = Math.floor(Math.random() * 100) + 1;
console.log(toGuess);
//Math.random得到的是[0,1)的整数
//3. 实现点击 猜 按钮的逻辑
guessBtn.onclick = function() {
//1. 读取到 input 中输入的内容,并转为整数
if (input.value == '') {
return;
}
let curNum = parseInt(input.value);
//2. 判定大小关系,并给出提示
if(curNum < toGuess) {
resultSpan.innerHTML = '低了';
resultSpan.style.color = 'red';
} else if (curNum > toGuess) {
resultSpan.innerHTML = '高了';
resultSpan.style.color = 'red';
} else {
resultSpan.innerHTML = '猜对了';
resultSpan.style.color = 'green';
}
//3. 更新 猜 的次数
let guessCount = parseInt(guessCountSpan.innerHTML);
guessCount += 1;
guessCountSpan.innerHTML = guessCount;
}
//4. 实现 reset 操作的逻辑(开始新的游戏)
resetBtn.onclick = function() {
//让页面刷新
//location(操作页面链接) 和 document(操作页面内容) 是并列关系的对象
//loacation 用来控制页面的链接/地址.通过reload操作就可以刷新页面
location.reload();
}
</script>
</body>
</html>
2. 表白墙
<!DOCTYPE html>
<html lang="en">
<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>
</head>
<body>
<style>
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
.container {
width: 100%;
}
h3 {
text-align: center;
padding: 30px 0;
font-size: 24px;
}
p {
text-align: center;
color: #666;
padding: 10px 0;
}
.row {
width: 400px;
height: 50px;
margin: 0 auto;
display: flex;
justify-content: center;
align-items: center;
}
.row span {
width: 80px;
font-size: 20px;
}
.row input {
width: 300px;
height: 40px;
line-height: 40px;
font-size: 20px;
text-indent: 0.5em;
/* 去掉输入框的轮廓线 */
outline: none;
}
.row #submit {
width: 380px;
height: 40px;
font-size: 20px;
line-height: 40px;
margin: 0 auto;
color: white;
background-color: orange;
/* 去掉边框 */
border: none;
border-radius: 5px;
}
/* 伪类选择器表示按下使出现变化 */
.row #submit:active {
background-color: gray;
}
</style>
<div class="container">
<h3>表白墙</h3>
<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>
<script>
// 当用户点击 submit, 就会获取到 input 中的内容,从而把内容构成一个div,插入到页面末尾
let submitBtn = document.querySelector('#submit');
submitBtn.onclick = function() {
//1. 获取到 3 个 input 中的内容
let inputs = document.querySelectorAll('input');
let from = inputs[0].value;
let to = inputs[1].value;
let msg = inputs[2].value;
if(from == '' || to == '' || msg == '') {
//用户还没填写完,暂时先不提交数据
return;
}
//2.生成一个新的div,内容就是input中的内容,把这个新的div加到页面中
let div = document.createElement('div');
div.innerHTML = from + ' 对 ' + to + ' 说: ' + msg;
div.className = 'row';
let container = document.querySelector('.container');
container.appendChild(div);
//3. 清空之前输入框的内容
for(let i = 0; i < inputs.length; i++) {
inputs[i].value = '';
}
}
</script>
</body>
</html>
3. 服务器版的表白墙
前面拿前端代码写的表白墙,提交的数据,如果网页一刷新就没有了
现在需要让保存的数据能够在服务器这边保存,就可以保证即使关闭页面,数据也不会丢失
(1) 先分析一下需求
(2) 还需要分析清楚请求和响应的细节,请求是什么样的,响应什么样的
针对发送数据给服务器:
请求: POST /message HTTP/1.1
Content-Type: application/json; charset=utf8
{ “form”: “小强子”, “to”: “小黑子”, “message”: “你在狗叫什么” }
//这个就是把当前具体传输的数据给表示出来
响应: HTTP/1.1 200 OK
从服务器获取到已经保存的数据
请求: GET /message
响应: HTTP/1.1 200 OK
Content-Type: application/json; charset=utf8
{
{ “form”: “小强子”, “to”: “小黑子”, “message”: “你在狗叫什么” }
{ “form”: “小强子”, “to”: “小黑子”, “message”: “你在狗叫什么” }
{ “form”: “小强子”, “to”: “小黑子”, “message”: “你在狗叫什么” }
}
Message 类
public class Message {
private String from;
private String to;
private String message;
public String getFrom() {
return from;
}
public void setFrom(String from) {
this.from = from;
}
public String getTo() {
return to;
}
public void setTo(String to) {
this.to = to;
}
public String getMessage() {
return message;
}
public void setMessage(String message) {
this.message = message;
}
}
MessageServlet 类
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;
/**
* Created with IntelliJ IDEA.
* Description:
* User: 28463
* Date: 2022—11—21
* Time: 17:51
*/
@WebServlet("/message")
public class MessageServlet extends HttpServlet {
//这个对象在多个方法中都需要使用
private ObjectMapper objectMapper = new ObjectMapper();
private List<Message> messagesList = new ArrayList<>();
//负责让页面获取到数据
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
//显示声明当前的响应数据格式,不要让客户端去"猜"
resp.setContentType("application/json; charset=utf8");
//这一行代码,把messageList 转成 json 字符串, 并且返回给页面就行了
resp.getWriter().write(objectMapper.writeValueAsString(messagesList));
}
//提交数据
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
//获取到 body 中的数据并解析
Message message = objectMapper.readValue(req.getInputStream(), Message.class);
// 把这个 message 保存一下,保存在内存中
messagesList.add(message);
resp.setStatus(200);
System.out.println("提交数据成功: from=" + message.getFrom() + ", to=" +
message.getTo() + ", message=" + message.getMessage());
}
}
表白墙.html
<!DOCTYPE html>
<html lang="en">
<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>
</head>
<body>
<style>
.container {
width: 400px;
/* margin 外边距. 第一个数字上下外边距, 第二个数字表示水平外边距. 如果水平设置成 auto 表示元素就水平居中~~ */
margin: 0 auto;
}
h1 {
text-align: center;
}
p {
text-align: center;
color: #666;
}
.row {
height: 40px;
display: flex;
/* 水平居中 */
justify-content: center;
/* 垂直居中 */
align-items: center;
}
.row span {
width: 100px;
}
.row input {
width: 200px;
height: 30px;
}
.row button {
width: 306px;
height: 40px;
color: white;
background: orange;
border: none;
}
.row button:active {
background-color: #666;
}
</style>
<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>提交</button>
</div>
</div>
<script src="http://libs.baidu.com/jquery/2.0.0/jquery.min.js"></script>
<script>
let container = document.querySelector('.container');
let button = document.querySelector('button');
button.onclick = function() {
// 1. 获取到输入框的内容
let inputs = document.querySelectorAll('input');
let from = inputs[0].value;
let to = inputs[1].value;
let message = inputs[2].value;
if (from == '' || to == '' || message == '') {
alert('当前输入框内容为空!');
return;
}
console.log(from + ", " + to + ", " + message);
// 2. 能够构造出新的 div, 用来保存用户提交的内容
let rowDiv = document.createElement('div');
rowDiv.className = 'row';
rowDiv.innerHTML = from + " 对 " + to + " 说: " + message;
container.appendChild(rowDiv);
// 3. 提交完之后, 清空输入框的内容
for (let i = 0; i < inputs.length; i++) {
inputs[i].value = '';
}
let data = {
from: from,
to: to,
message: message
};
// 4. 点击发送按钮, 给服务器发个 post 请求.
$.ajax({
type: 'post',
url: 'message',
// url: '/java105/message',
// 这里放的是 body 的内容
data: JSON.stringify(data),
contentType: "application/json; charset=utf8",
success: function(body) {
console.log("提交数据成功");
}
});
}
// 直接写在 script 标签里的代码, 都是在页面加载的时候执行的.
// 来获取服务器的数据
function getMessages() {
$.ajax({
type: 'get' ,
url: 'message',
success: function(body) {
// body 就是响应的 body 内容, json 数组.
// jquery 非常智能的帮我们把 json 数组给解析成了 js 对象数组
// 但是有个前提条件, 就是响应的 Content-Type 得是 application/json
let container = document.querySelector('.container');
for (let i = 0; i < body.length; i++) {
let message = body[i];
// 根据这个元素构造一个 div.row, 来容纳数据
// <div class="row">
// 黑猫 对 白猫 说: 喵
// </div>
let row = document.createElement('div');
row.className = 'row';
row.innerHTML = message.from + " 对 " + message.to + " 说: " + message.message;
container.appendChild(row);
}
}
});
}
getMessages();
</script>
</body>
</html>
运行程序
整个程序,有两个环节涉及到前后端交互
1. 点击提交的时候,把当前输入框的内容发送给服务器
2. 页面加载的时候,从服务器获取到数据的列表
1. 点击提交的时候,把当前输入框的内容发送给服务器
客户端在按钮的 onclick 中,构造 ajax,发个 post请求
2. 页面加载的时候,从服务器获取到数据的列表
4. 将表白墙的数据在数据库中持久化保存
这就需要用到数据库的JDBC了
先设计数据库表结构,表中有什么
message 表 (from, to, message)
加入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;
/**
* Created with IntelliJ IDEA.
* Description:
* User: 28463
* Date: 2022—11—21
* Time: 17:51
*/
@WebServlet("/message")
public class MessageServlet extends HttpServlet {
//这个对象在多个方法中都需要使用
private ObjectMapper objectMapper = new ObjectMapper();
// private List<Message> messagesList = new ArrayList<>();
//负责让页面获取到数据
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
//显示声明当前的响应数据格式,不要让客户端去"猜"
resp.setContentType("application/json; charset=utf8");
//这一行代码,把messageList 转成 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 {
//获取到 body 中的数据并解析
Message message = objectMapper.readValue(req.getInputStream(), Message.class);
// 把这个 message 保存一下,保存在内存中
// messagesList.add(message);
try {
save(message);
} catch (SQLException e) {
e.printStackTrace();
}
resp.setStatus(200);
System.out.println("提交数据成功: from=" + message.getFrom() + ", to=" +
message.getTo() + ", message=" + message.getMessage());
}
private List<Message> load() throws SQLException {
//从数据库查看数据
// 把数据保存到数据库中
//1. 先有一个数据源
DataSource dataSource = new MysqlDataSource();
((MysqlDataSource)dataSource).setURL("jdbc:mysql://127.0.0.1:3306/java11?characterEncoding=utf8&useSSL=false");
((MysqlDataSource)dataSource).setUser("root");
((MysqlDataSource)dataSource).setPassword("111111");
//2. 建立连接
Connection connection = dataSource.getConnection();
//3.构造 SQL
String sql = "select * from message";
PreparedStatement statement = connection.prepareStatement(sql);
//4. 执行sql进行插入操作
ResultSet resultSet = statement.executeQuery();
//6. 遍历结果集合
List<Message> messageList = new ArrayList<>();
while (resultSet.next()) {
Message message = new Message();
message.setFrom(resultSet.getString("from"));
message.setTo(resultSet.getString("to"));
message.setMessage(resultSet.getString("message"));
messageList.add(message);
}
//6. 关闭连接
statement.close();
connection.close();
return messageList;
}
private void save(Message message) throws SQLException {
// 把数据保存到数据库中
//1. 先有一个数据源
DataSource dataSource = new MysqlDataSource();
((MysqlDataSource)dataSource).setURL("jdbc:mysql://127.0.0.1:3306/java11?characterEncoding=utf8&useSSL=false");
((MysqlDataSource)dataSource).setUser("root");
((MysqlDataSource)dataSource).setPassword("111111");
//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();
}
}
重新运行程序,添加数据
可以看到idea日志打印成功
在MySql中查询刚刚插入的数据,可以看到插入成功了
5. 使用单例模式表示DataSource
前面在这两个方法中写了两个DataSource,并且都一模一样,这样写不好,所以最好的办法就是把这两个DataSource只写一份,使用单例模式表示出来
单例模式有两种一种是饿汉模式,一种是懒汉模式
最好写懒汉模式,因为饿汉是在类加载的时候就创建,而懒汉是在第一次使用的时候才创建,懒汉模式的效率是更高的
并且还需要考虑的是,Servlet代码中,是否有 多线程的安全问题?
Servlet写的是一个服务器,在同一时刻,可能要处理多个客户端的请求
当多个客户端同时发来请求时,服务器就要同时处理多个请求,Tomcat内部也正是使用了多线程方式,所以要注意加锁的问题
写一个单例模式,把DataSource放进去
import com.mysql.jdbc.jdbc2.optional.MysqlDataSource;
import javax.sql.DataSource;
/**
* Created with IntelliJ IDEA.
* Description:
* User: 28463
* Date: 2022—11—23
* Time: 15:57
*/
//使用这个类来封装DataSource
public class DBUtil {
private static volatile DataSource dataSource = null;
public static DataSource getDataSource() {
if(dataSource == null) {
synchronized (DBUtil.class) {
if(dataSource == null) {
dataSource = new MysqlDataSource();
((MysqlDataSource)dataSource).setURL("jdbc:mysql://127.0.0.1:3306/java11?characterEncoding=utf8&useSSL=false");
((MysqlDataSource)dataSource).setUser("root");
((MysqlDataSource)dataSource).setPassword("111111");
}
}
}
return dataSource;
}
private DBUtil() {
}
}
然后修改MessageServlet中的代码
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;
/**
* Created with IntelliJ IDEA.
* Description:
* User: 28463
* Date: 2022—11—21
* Time: 17:51
*/
@WebServlet("/message")
public class MessageServlet extends HttpServlet {
//这个对象在多个方法中都需要使用
private ObjectMapper objectMapper = new ObjectMapper();
// private List<Message> messagesList = new ArrayList<>();
//负责让页面获取到数据
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
//显示声明当前的响应数据格式,不要让客户端去"猜"
resp.setContentType("application/json; charset=utf8");
//这一行代码,把messageList 转成 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 {
//获取到 body 中的数据并解析
Message message = objectMapper.readValue(req.getInputStream(), Message.class);
// 把这个 message 保存一下,保存在内存中
// messagesList.add(message);
try {
save(message);
} catch (SQLException e) {
e.printStackTrace();
}
resp.setStatus(200);
System.out.println("提交数据成功: from=" + message.getFrom() + ", to=" +
message.getTo() + ", message=" + message.getMessage());
}
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进行插入操作
ResultSet resultSet = statement.executeQuery();
//6. 遍历结果集合
List<Message> messageList = new ArrayList<>();
while (resultSet.next()) {
Message message = new Message();
message.setFrom(resultSet.getString("from"));
message.setTo(resultSet.getString("to"));
message.setMessage(resultSet.getString("message"));
messageList.add(message);
}
//6. 关闭连接
statement.close();
connection.close();
return messageList;
}
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();
}
}
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。
文章由极客之音整理,本文链接:https://www.bmabk.com/index.php/post/87329.html