目录
目标
1.创建工程
2.构建目录工程结构
3.设置编码格式
4.查看Maven的配置
6.导入HTML和JS,配置tomcat
7.测试网站是否可以正常访问
8.编写业务代码
目标:
- 1.熟练掌握前端向后端提交数据
- 2.后端接收数据并校验
- 3.通过JAVA代码进行数据库操作
- 4.返回处理结果的响应
1.创建工程
2.构建目录工程结构
3.设置编码格式
4.查看Maven的配置
5.在pom.xml中导入依赖
<dependencies>
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>javax.servlet-api</artifactId>
<version>3.1.0</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>2.14.2</version>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>5.1.49</version>
</dependency>
</dependencies>
6.导入HTML和JS,配置tomcat
messagewall.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>
<style>
* {
padding: 0;
margin: 0;
box-sizing: border-box;
}
.container {
width: 400px;
margin: 0 auto;
}
.container h1 {
margin: 20px 0;
text-align: center;
}
.container .sub-title {
color: #666;
text-align: center;
font-size: 14px;
margin-bottom: 10px;
}
.container .row {
width: 100%;
height: 40px;
display: flex;
justify-content: center;
align-items: center;
}
.container span {
width: 80px;
}
.container input {
width: 200px;
height: 30px;
}
.container .row>button {
width: 280px;
height: 30px;
background-color: orange;
border: none;
color: white
}
.container .row>button:active {
background-color: #666;
}
.container .message {
padding: 20px;
text-align: center;
}
.message p {
height: 30px;
line-height: 30px;
}
</style>
<!-- 引入jQuery -->
<script src="./js/jquery-3.6.3.min.js"></script>
</head>
<body>
<div class="container">
<h1>表白墙</h1>
<p class="sub-title">输入后点击提交,会将内容显示在表格中</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 class="message">
<!-- <p><b>唐僧</b> 对 <b>悟空</b>说:<b>为师有点饿了.</b></p>
<p><b>唐僧</b> 对 <b>悟空</b>说:<b>为师有点饿了.</b></p>
<p><b>唐僧</b> 对 <b>悟空</b>说:<b>为师有点饿了.</b></p>
<p><b>唐僧</b> 对 <b>悟空</b>说:<b>为师有点饿了.</b></p> -->
</div>
</div>
</body>
<script>
// 1. 获取相关的元素
let submitBtnEl = document.querySelector('#submit');
let inputEls = document.querySelectorAll('input');
let messageEl = document.querySelector('.message');
// 绑定事件
submitBtnEl.onclick = function () {
// 2. 处理用户输入的内容
let sender = inputEls[0].value;
let receiver = inputEls[1].value;
let content = inputEls[2].value;
// 非空校验
if (sender == '' || receiver == "" || content == "") {
alert('请正确输入内容');
return;
}
// 3. 构造表白结果
let str = '<b>' + sender + '</b> 对 <b>' + receiver + '</b>说:<b>' + content + '.</b>'
// 4. 构建一个p标签
let messageRow = document.createElement('p');
messageRow.innerHTML = str;
// 4. 把结果加入到表白墙上
messageEl.appendChild(messageRow)
// 5. 清空输入框中的内容
inputEls.forEach(element => {
element.value = '';
});
// 处提交逻辑
// 1. 封装JSON对象
let postJson = {
"sender" : sender,
"receiver": receiver,
"content" : content
};
let jsonStr = JSON.stringify(postJson);
console.log(jsonStr);
// 2. 提交AJVA请求
$.ajax({
// 请求使用的方法
type: 'post',
// 请求的URL,注意不要加斜杠
url: 'message',
// 格式
contentType: 'application/json',
// 发送的数据
data: jsonStr,
// 成功时的回调
success : function(data) {
console.log(data);
}
})
};
// 发送请求获取已有留言
$.ajax({
// 请求使用的方法
type: 'get',
// 请求的URL,注意不要加斜杠
url: 'message',
// 回调
success: function (data) {
data.forEach(element => {
console.log(element);
// <p><b>唐僧</b> 对 <b>悟空</b>说:<b>为师有点饿了.</b></p>
// 1. 创建一个P标签
let pEl = document.createElement('p');
// 2. 构造内容
pEl.innerHTML = '<b>'+element.sender+'</b> 对 <b>'+element.receiver+'</b>说:<b>'+element.content+'.</b>'
// 3. 加入到父标签下
messageEl.appendChild(pEl);
});
// 结果是一个数组,遍历结果
// for (let index = 0; index < data.length; index++) {
// element = data[index];
// console.log(element);
// }
}
});
</script>
</html>
7.测试网站是否可以正常访问
8.编写业务代码
分析:
- 用户从前端提交数据 AJAX技术
- 服务器要接受用户的数据 通过Servlet实现
- 业务逻辑的处理
- 操作数据库 JDBC
- 获取数据库的结果,并为用户构造响应 JSON
在java目录下创建model包,包下创建类Message
public class Message {
private Long id; // 对应到数据中的主键
private String sender; // 发送者
private String receiver; // 接收者
private String content; // 留言内容
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public String getSender() {
return sender;
}
public void setSender(String sender) {
this.sender = sender;
}
public String getReceiver() {
return receiver;
}
public void setReceiver(String receiver) {
this.receiver = receiver;
}
public String getContent() {
return content;
}
public void setContent(String content) {
this.content = content;
}
}
在数据库中建表
在java目录下创建utils包,包下创建类DBUtil
import com.mysql.jdbc.jdbc2.optional.MysqlDataSource;
import javax.sql.DataSource;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
/**
* 单例模式的数据库连接类
* 作用是为了获取一个数据库连接
*
* @Author 比特就业课
*/
public class DBUtil {
// 声明一个数据源对象
private static DataSource dataSource = null;
// 定义数据库连接的参数
private static final String URL = "jdbc:mysql://localhost:3306/java78?characterEncoding=utf8&useSSL=false";
private static final String USER = "root";
private static final String PASSWORD = "123456";
// 在静态方法中初始化数据源对象
static {
MysqlDataSource mysqlDataSource = new MysqlDataSource();
mysqlDataSource.setURL(URL);
mysqlDataSource.setUser(USER);
mysqlDataSource.setPassword(PASSWORD);
dataSource = mysqlDataSource;
}
// 私有化构造方法
private DBUtil () {}
/**
* 获取数据库连接
* @return
* @throws SQLException
*/
public static Connection getConnection () throws SQLException {
// 通过数据源对象,获取数据库连接对象
return dataSource.getConnection();
}
public static void close (ResultSet resultSet, PreparedStatement statement, Connection connection) {
// 依次关闭并释放资源
if (resultSet != null) {
try {
resultSet.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
if (statement != null) {
try {
statement.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
if (connection != null) {
try {
connection.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
}
}
在src下 创建文件db.sql
在java目录下创建dao包,包下创建类MessageDao
import com.bitejiuyeke.model.Message;
import com.bitejiuyeke.utils.DBUtil;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;
/**
* @Author 比特就业课
*/
public class MessageDao {
/**
* 获取所有留言数据
*
* @return 留言集合
*/
public List<Message> selectAll () {
// 定义访问数据库的相关对象
Connection connection = null;
PreparedStatement statement = null;
ResultSet resultSet = null;
try {
// 1. 获取数据库连接
connection = DBUtil.getConnection();
// 2. 定义SQL语句
String sql = "select id, sender, receiver, content from message_wall order by id desc";
// 3. 预处理SQL
statement = connection.prepareStatement(sql);
// 4. 执行SQL并获取结果集
resultSet = statement.executeQuery();
// 5. 遍历结果集
List<Message> messageList = null;
while (resultSet.next()) {
// 如果List为空,则初始化
if (messageList == null) {
messageList = new ArrayList<>();
}
// 创建一个Message对象
Message message = new Message();
message.setId(resultSet.getLong(1));
message.setSender(resultSet.getString(2));
message.setReceiver(resultSet.getString(3));
message.setContent(resultSet.getString(4));
// 把对象加入List
messageList.add(message);
}
// 返回结果
return messageList;
} catch (SQLException e) {
e.printStackTrace();
} finally {
// 关闭连接并释放资源
DBUtil.close(resultSet, statement, connection);
}
return null;
}
/**
* 新增一条留言记录
* @param message 留言记录
* @return 受影响的行数
*/
public int insert(Message message) {
Connection connection = null;
PreparedStatement statement = null;
try {
connection = DBUtil.getConnection();
String sql = "insert into message_wall values (null, ?, ?, ?)";
statement = connection.prepareStatement(sql);
// 处理占位符
statement.setString(1, message.getSender());
statement.setString(2, message.getReceiver());
statement.setString(3, message.getContent());
// 执行SQL
int row = statement.executeUpdate();
return row;
} catch (SQLException e) {
e.printStackTrace();
} finally {
DBUtil.close(null, statement, connection);
}
return -1;
}
}
在根目录下创建类MessageServlet
import com.bitejiuyeke.dao.MessageDao;
import com.bitejiuyeke.model.Message;
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;
/**
* @Author 比特就业课
*/
@WebServlet("/message")
public class MessageServlet extends HttpServlet {
// 定义数据库访问类
private MessageDao messageDao = new MessageDao();
// json转换
private ObjectMapper objectMapper = new ObjectMapper();
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
// 定义编码格式
req.setCharacterEncoding("UTF-8");
resp.setContentType("application/json; charset=utf-8");
// 查询数据库中的留言列表
List<Message> messages = messageDao.selectAll();
// 判断结果是否为空
if (messages == null) {
// 避免返回的是一个"null"
messages = new ArrayList<>();
}
// 返结果转为json并返回
String jsonString = objectMapper.writeValueAsString(messages);
// 返回结果
resp.getWriter().write(jsonString);
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
// 定义编码格式
req.setCharacterEncoding("UTF-8");
resp.setContentType("application/json; charset=utf-8");
// 接收用户请求中的数据
Message message = objectMapper.readValue(req.getInputStream(), Message.class);
// 非空校验
if (message == null || message.getSender() == null || message.getSender().equals("")
|| message.getReceiver() == null || message.getReceiver().equals("")
|| message.getContent() == null || message.getContent().equals("")) {
// 返回一个错误的自定义状态码
resp.getWriter().write("{\"code\": -1}");
return;
}
// 调用DAO写入数据库
int row = messageDao.insert(message);
if (row <= 0) {
// 返回一个错误的自定义状态码
resp.getWriter().write("{\"code\": -1}");
return;
}
// 返回成功
resp.getWriter().write("{\"code\": 0}");
}
}
打开浏览器输入网址填入数据测试
在数据库中查看刚才的记录,完成