目录
前言
我们在解释servlet的主要是解释三个Servelt基础的api,分别是,HttpServlet,HttpServletRequest,HttpServletResponse,我将在下面逐一展开介绍.
一.HttpServlet
方法名称 | 调用时机 |
---|---|
init | 在 HttpServlet 实例化之后被调用一次 |
destory | 在 HttpServlet 实例不再使用的时候调用一次 |
service | 收到 HTTP 请求的时候调用 |
doGet | 收到 GET 请求的时候调用(由 service 方法调用) |
doPost | 收到 POST 请求的时候调用(由 service 方法调用) |
doPut/doDelete/doOptions/… | 收到其他请求的时候调用(由 service 方法调用) |
我通过一个代码例子,来说明这些api的使用
@WebServlet("/hello")
public class Main extends HttpServlet {
@Override
public void init() throws ServletException {
// 可以在这里重写 init 方法
// 插入一些咱们自己的 "初始化" 相关的逻辑.
System.out.println("init");
}
@Override
public void destroy() {
// 经常有同学拼写成 destory (俺以前也经常写错)
System.out.println("destroy");
}
@Override
protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
System.out.println("service");
super.service(req, resp);
}
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
// 把数据显示到服务器控制台
System.out.println("hello world");
// 把数据写回给浏览器
resp.getWriter().write("hello java");
}
}
这里我发了多次请求,初始化方法,只会执行一次
我如果发起get请求,service方法就会在控制台答应,其他方法就不会被调用.
这里也引出了Servelt的生命周期执行过程.
二.HttpServletRequest
当 Tomcat 通过 Socket API 读取 HTTP 请求(字符串), 并且按照 HTTP 协议的格式把字符串解析成HttpServletRequest 对象.
下面是这个api的核心方法.
方法 | 描述 |
---|---|
String getProtocol() | 返回请求协议的名称和版本。 |
String getMethod() | 返回请求的 HTTP 方法的名称,例如,GET、POST 或 PUT。 |
String getRequestURI() | 从协议名称直到 HTTP 请求的第一行的查询字符串中,返回该请 |
求的 URL 的一部分。 | |
String getContextPath() | 返回指示请求上下文的请求 URI 部分。 |
String getQueryString() | 返回包含在路径后的请求 URL 中的查询字符串。 |
Enumeration getParameterNames() | 返回一个 String 对象的枚举,包含在该请求中包含的参数的名称。 |
String getParameter(String name) | 以字符串形式返回请求参数的值,或者如果参数不存在则返回 null。 |
String[] getParameterValues(String name) | 返回一个字符串对象的数组,包含所有给定的请求参数的值,如果参数不存在则返回 null。 |
Enumeration getHeaderNames() | 返回一个枚举,包含在该请求中包含的所有的头名。 |
String getHeader(String name) | 以字符串形式返回指定的请求头的值。 |
String getCharacterEncoding() | 返回请求主体中使用的字符编码的名称。 |
String getContentType() | 返回请求主体的 MIME 类型,如果不知道类型则返回 null。 |
int getContentLength() | 以字节为单位返回请求主体的长度,并提供输入流,或者如果长度未知则返回 -1。 |
InputStream getInputStream() | 用于读取请求的 body 内容. 返回一个 InputStream 对象. |
根据上面的代码,我们就地举一个例子,来说明一下.先来看看我们请求的打印.
@WebServlet("/showRequest")
public class ShowRequest extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException, IOException {
StringBuilder result = new StringBuilder();
result.append(req.getProtocol());
result.append("<br>");
result.append(req.getMethod());
result.append("<br>");
result.append(req.getRequestURI());
result.append("<br>");
result.append(req.getQueryString());
result.append("<br>");
result.append(req.getContextPath());
result.append("<br>");
result.append("=========================<br>");
Enumeration<String> headerNames = req.getHeaderNames();
while (headerNames.hasMoreElements()) {
String headerName = headerNames.nextElement();
String headerValue = req.getHeader(headerName);
result.append(headerName + ": " + headerValue + "<br>");
}
// 在响应中设置上 body 的类型. 方便浏览器进行解析
resp.setContentType("text/html;charset=utf8");
resp.getWriter().write(result.toString());
}
}
具体的获取信息如下:
其实在上面解释的api中,经常使用的是getParameter,这个方法是最常用的.
因为基本上前端给后端传递数据,是非常常见的需求,所以我们经常就要获取数据.一般获取数据有三种方式.
1)通过query string 传递
发送请求的格式如下:
http://localhost:8080/helloservelt2/getParameter?studentId=10&classId=20
@WebServlet("/getParameter")
public class GetParameterServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
//预期浏览器会发送一个请求,这个请求会自动携带参数/
//借助rep里的getParameter 方法就能拿到query string 中的键值对内容了
// getParameter 拿到的是String类型的结果.
String studentId=req.getParameter("studentId");
String classId=req.getParameter("classId");
resp.setContentType("text/html;charset=utf-8");
resp.getWriter().write("学生id ="+studentId +"班级id ="+classId);
}
}
运行结果如下:
2)通过body (form)
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
String studentId=req.getParameter("studentId");
String classId=req.getParameter("classId");
resp.setContentType("text/html;charset=utf-8");
resp.getWriter().write("学生id ="+studentId +"班级id ="+classId);
}
3)通过body (json)
在通过json格式传参之前,我们首先要去引一个包
用来处理json的第三方库,有很多,我们这里用的是jackson
要在pom.xml引入以下
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>2.14.2</version>
</dependency>
这样就可以处理json数据了.
构造请求
具体代码处理
class User {
public String username;
public String password;
}
@WebServlet("/json")
public class JsonServlet extends HttpServlet {
// 使用 jackson, 最核心的对象就是 ObjectMapper
// 通过这个对象, 就可以把 json 字符串解析成 java 对象; 也可以把一个 java 对象转成一个 json 格式字符串.
private ObjectMapper objectMapper = new ObjectMapper();
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
// 通过 post 请求的 body 传递过来一个 json 格式的字符串.
User user = objectMapper.readValue(req.getInputStream(), User.class);
System.out.println("username=" + user.username + ", password=" + user.password);
resp.getWriter().write("ok");
}
}
三.HttpServletResponse
HttpServletResponse表示一个HTTP响应
下面我列出一些核心方法.
方法 | 描述 |
---|---|
void setStatus(int sc) | 为该响应设置状态码。 |
void setHeader(String name,String value) | 设置一个带有给定的名称和值的 header. 如果 name 已经存在,则覆盖旧的值. |
void addHeader(String name, String value) | 添加一个带有给定的名称和值的 header. 如果 name 已经存在,不覆盖旧的值, 并列添加新的键值对 |
void setContentType(String type) | 设置被发送到客户端的响应的内容类型。 |
void setCharacterEncoding(String charset) | 设置被发送到客户端的响应的字符编码(MIME 字符集)例如,UTF-8。 |
void sendRedirect(String location) | 使用指定的重定向位置 URL 发送临时重定向响应到客户端。 |
PrintWriter getWriter() | 用于往 body 中写入文本格式数据. |
OutputStream getOutputStream() | 用于往 body 中写入二进制格式数据. |
具体的例子代码入下:
@WebServlet("/status")
public class StatusServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
resp.setStatus(404);
resp.setContentType("text/html; charset=utf8");
resp.getWriter().write("返回 404 响应!");
}
}
@WebServlet("/redirect")
public class RedirectServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
resp.setStatus(302);
resp.setHeader("Location", "https://www.sogou.com");
//这一行是上面俩个的综合,有时候,我们基于方便的原则,我们会使用下面这种方式
// resp.sendRedirect("https://www.sogou.com");
}
}
上面这个会跳转到搜狗页面
@WebServlet("/refresh")
public class RefreshServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
// 每隔 1s 自动刷新一次.
resp.setHeader("Refresh", "1");
resp.getWriter().write("time=" + System.currentTimeMillis());
}
}
每隔一秒钟,自动刷新一次.
四.表白墙实例
4.1 准备工作
1.创建maven项目
2.构建如下的项目目录
3. 调整 pom.xml
加入下面几个依赖
servlet依赖,jakson依赖,mysql依赖
<dependencies>
<!-- https://mvnrepository.com/artifact/javax.servlet/javax.servlet-api -->
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>javax.servlet-api</artifactId>
<version>3.1.0</version>
<scope>provided</scope>
</dependency>
<!-- https://mvnrepository.com/artifact/com.fasterxml.jackson.core/jackson-databind -->
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>2.14.2</version>
</dependency>
<!-- https://mvnrepository.com/artifact/mysql/mysql-connector-java -->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>5.1.49</version>
</dependency>
</dependencies>
4.把准备的好的表白墙html拷贝在目录下面
4.2 约定前后端交互接口
约定前后端交互结构是什么意思呢?其实就是写web程序务必重点考虑前后端如何交互,约定好前后端交互的数据格式.我们就拿表白墙这个界面来说吧.
我们要解决以下几个问题.
请求是什么样的
响应是什么样的
浏览器啥时候发这个请求
浏览器按照啥样的格式来解析
第一步
当然我们仔细分析过这个表白墙程序之后,我们就得出以下俩个动作.
1.点击提交,浏览器把表白信息发到服务器
2.页面加载,浏览器从服务器获取表白信息
第二步
1.点击提交,浏览器把表白信息发到服务器,约定格式如下:
2.页面加载,浏览器从服务器获取表白信息约定如下:
注意:我们后面的操作,都是根据这个约定来的,大家一定不要掉以轻心.
4.3 实现服务器端代码
根据上述的约定实现后端服务器代码.
代码如下:
private List<Message> messageList=new ArrayList<>();
//向服务器提交数据
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
//
ObjectMapper objectMapper=new ObjectMapper();
//把body的信息读取出来,解析成了message对象
Message message=objectMapper.readValue(req.getInputStream(),Message.class);
//此时先通过简单粗暴的方式进行保存
messageList.add(message);
//此时设定状态码
resp.setStatus(200);
}
根据上述的约定,生成服务器代码
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
//响应数据也是一个json格式
//基于objectMapper的writeValue方法.就可以完成转换
resp.setContentType("application/json; charset=utf8");
ObjectMapper objectMapper=new ObjectMapper();
//这个方法同时完成了,吧java对象转成json字符串,并且把这个字符串写到响应对象中
objectMapper.writeValue(resp.getWriter(),messageList);
}
在写好之后,我们可以用postman构建请求,测试一下,看看我们的后端逻辑是否正确.
事实证明,我们逻辑是正确的的.
4.4 调整前端页面代码
修改 之前的表白墙html的代码,中间主要修改了两个部分,我将在下面介绍两个部分
1.在表白墙页面输入信息,点击提交按钮,通过点击事件浏览器向服务器发送一个post请求,将用户输入的信息发给服务器。
具体的一个过程如下:
具体的代码如下:
let body = {
"from": from,
"to": to,
"message": msg
};
//这上面的步骤,js内置了吧对象转成json字符串格式的对象.
let strBody = JSON.stringify(body);
console.log("strBody: " + strBody);
//至关重要的一步
$.ajax({
type: 'post',
url: 'message',
data: strBody,
contentType: "application/json; charset=utf8",
success: function(body) {
console.log("数据发布成功");
}
});
}
2.在页面刷新的时候或者服务器重启的时候,表白墙页面(浏览器)从服务器那通过get请求获取到以前用户输入过的信息。
具体的流程如下:
$.ajax({
type: 'get',
url: 'message',
success: function(body) {
// 此处拿到的 body 就是一个 js 的对象数组了.
// 本来服务器返回的是一个 json 格式的字符串, 但是 jquery 的 ajax 能够自动识别
// 自动帮我们把 json 字符串转成 js 对象数组
// 接下来遍历这个数组, 把元素取出来, 构造到页面中即可
let containerDiv = document.querySelector('.container')
for (let message of body) {
// 针对每个元素构造一个 div
let rowDiv = document.createElement('div');
rowDiv.className = 'row message';
rowDiv.innerHTML = message.from + ' 对 ' + message.to + ' 说: ' + message.message;
containerDiv.appendChild(rowDiv);
}
}
});
4.5 数据存入数据库
使用文件的方式存储留言固然可行, 但是并不优雅. 我们还可以借助数据库完成存储工作.
- 创建数据库, 创建 messages 表
- 创建 DBUtil 类
- 创建 MysqlDataSource 实例, 设置 URL, username, password 等属性.
- 提供 getConnection 方法, 和 MySQL 服务器建立连接.
- 提供 close 方法, 用来释放必要的资源.
代码如下:
public class DBUtil {
// 静态成员跟随类对象的. 类对象在整个进程中只有唯一一份
// 静态成员相当于也是唯一的实例. (单例模式, 饿汉模式)
private static DataSource dataSource = new MysqlDataSource();
static {
// 使用静态代码块, 针对 dataSource 进行初始化操作
((MysqlDataSource)dataSource).setUrl("jdbc:mysql://127.0.0.1:3306/messagewall?characterEncoding=utf8&useSSL=false");
((MysqlDataSource)dataSource).setUser("root");
// 我这个机器的 mysql 没有密码, 直接写作 "" 即可
((MysqlDataSource)dataSource).setPassword("123456");
}
// 通过这个方法来建立连接
public static Connection getConnection() throws SQLException {
return dataSource.getConnection();
}
// 通过这个方法断开连接, 释放资源
public static void close(Connection connection, PreparedStatement statement, ResultSet resultSet) {
// 此处的三个 try catch 分开写更好, 避免前面的异常导致后面的代码不能执行.
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();
}
}
}
}
- 提供 load 和 save 方法, load方法用来往数据库中存一条记录,save方法,来从数据库查询所有记录.
load方法如下:
private List<Message> load() {
List<Message> messageList = new ArrayList<>();
Connection connection = null;
PreparedStatement statement=null;
ResultSet resultSet=null;
try {
//1.和数据库建立连接
connection=DBUtil.getConnection();
//2.构造SQL
String sql="select * from message";
statement =connection.prepareStatement(sql);
//3.执行SQL
resultSet=statement.executeQuery();
//4.遍历结果结合
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);
}
} catch (SQLException e) {
throw new RuntimeException(e);
}finally {
DBUtil.close(connection,statement,resultSet);
}
return messageList;
}
}
save方法如下:
private void save(Message message) {
// JDBC 操作
Connection connection = null;
PreparedStatement statement = null;
try {
// 1. 建立连接
connection = DBUtil.getConnection();
// 2. 构造 SQL 语句
String sql = "insert into message values(?, ?, ?)";
statement = connection.prepareStatement(sql);
statement.setString(1, message.from);
statement.setString(2, message.to);
statement.setString(3, message.message);
// 3. 执行 sql
statement.executeUpdate();
} catch (SQLException e) {
e.printStackTrace();
} finally {
// 4. 关闭连接.
DBUtil.close(connection, statement, null);
}
}
主函数逻辑:
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
//
ObjectMapper objectMapper=new ObjectMapper();
//把body的信息读取出来,解析成了message对象
Message message=objectMapper.readValue(req.getInputStream(),Message.class);
//此时先通过简单粗暴的方式进行保存
// messageList.add(message);
//用另外一种方式保存
save(message);
//此时设定状态码
resp.setStatus(200);
}
//从服务器获取数据,
// 只做一件事,把messageList准换成json字符串,返回给浏览器即可
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
//响应数据也是一个json格式
//基于objectMapper的writeValue方法.就可以完成转换
resp.setContentType("application/json; charset=utf8");
ObjectMapper objectMapper=new ObjectMapper();
//这个方法同时完成了,吧java对象转成json字符串,并且把这个字符串写到响应对象中
List<Message> messageList = load();
objectMapper.writeValue(resp.getWriter(),messageList);
//第一个参数是Writer对象,表示转成的json字符串,往哪个地方去写
//第二个参数用来存储消息的List,要把哪个对象转成json字符串.
/*
*/
}
五.附录
5.1 表白墙完整代码
<!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>
/* * 通配符选择器, 是选中页面所有元素 */
* {
/* 消除浏览器的默认样式. */
margin: 0;
padding: 0;
box-sizing: border-box;
}
.container {
width: 600px;
margin: 20px auto;
}
h1 {
text-align: center;
}
p {
text-align: center;
color: #666;
margin: 20px 0;
}
.row {
/* 开启弹性布局 */
display: flex;
height: 40px;
/* 水平方向居中 */
justify-content: center;
/* 垂直方向居中 */
align-items: center;
}
.row span {
width: 80px;
}
.row input {
width: 200px;
height: 30px;
}
.row button {
width: 280px;
height: 30px;
color: white;
background-color: orange;
/* 去掉边框 */
border: none;
border-radius: 5px;
}
/* 点击的时候有个反馈 */
.row button:active {
background-color: grey;
}
</style>
</head>
<body>
<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 id="submit">提交</button>
</div>
<div class="row">
<button id="revert">撤销</button>
</div>
<!-- <div class="row">
xxx 对 xx 说 xxxx
</div> -->
</div>
<script src="https://cdn.bootcdn.net/ajax/libs/jquery/3.6.4/jquery.min.js"></script>
<script>
// 实现提交操作. 点击提交按钮, 就能够把用户输入的内容提交到页面上显示.
// 点击的时候, 获取到三个输入框中的文本内容
// 创建一个新的 div.row 把内容构造到这个 div 中即可.
let containerDiv = document.querySelector('.container');
let inputs = document.querySelectorAll('input');
let button = document.querySelector('#submit');
button.onclick = function() {
// 1. 获取到三个输入框的内容
let from = inputs[0].value;
let to = inputs[1].value;
let msg = inputs[2].value;
if (from == '' || to == '' || msg == '') {
return;
}
// 2. 构造新 div
let rowDiv = document.createElement('div');
rowDiv.className = 'row message';
rowDiv.innerHTML = from + ' 对 ' + to + ' 说: ' + msg;
containerDiv.appendChild(rowDiv);
// 3. 清空之前的输入框内容
for (let input of inputs) {
input.value = '';
}
// 4. [新增] 给服务器发起 post 请求, 把上述数据提交到服务器这边
let body = {
"from": from,
"to": to,
"message": msg
};
//这上面的步骤,js内置了吧对象转成json字符串格式的对象.
let strBody = JSON.stringify(body);
console.log("strBody: " + strBody);
//至关重要的一步
$.ajax({
type: 'post',
url: 'message',
data: strBody,
contentType: "application/json; charset=utf8",
success: function(body) {
console.log("数据发布成功");
}
});
}
let revertButton = document.querySelector('#revert');
revertButton.onclick = function() {
// 删除最后一条消息.
// 选中所有的 row, 找出最后一个 row, 然后进行删除
let rows = document.querySelectorAll('.message');
if (rows == null || rows.length == 0) {
return;
}
containerDiv.removeChild(rows[rows.length - 1]);
}
// [新增] 在页面加载的时候, 发送 GET 请求, 从服务器获取到数据并添加到页面中
$.ajax({
type: 'get',
url: 'message',
success: function(body) {
// 此处拿到的 body 就是一个 js 的对象数组了.
// 本来服务器返回的是一个 json 格式的字符串, 但是 jquery 的 ajax 能够自动识别
// 自动帮我们把 json 字符串转成 js 对象数组
// 接下来遍历这个数组, 把元素取出来, 构造到页面中即可
let containerDiv = document.querySelector('.container')
for (let message of body) {
// 针对每个元素构造一个 div
let rowDiv = document.createElement('div');
rowDiv.className = 'row message';
rowDiv.innerHTML = message.from + ' 对 ' + message.to + ' 说: ' + message.message;
containerDiv.appendChild(rowDiv);
}
}
});
</script>
</body>
</html>
5.2 服务器完整代码
package org.example;
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.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;
/**
* @author <a href="mailto:1065043594@qq.com">ChenJiaYi</a>
* @CreateDate 2023/7/5
* @ProjectDetails [项目简述]
*/
class Message{
public String from;
public String to;
public String message;
}
@WebServlet("/message")
public class MessageServlet extends HttpServlet {
//向服务器提交数据
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
//
ObjectMapper objectMapper=new ObjectMapper();
//把body的信息读取出来,解析成了message对象
Message message=objectMapper.readValue(req.getInputStream(),Message.class);
//此时先通过简单粗暴的方式进行保存
// messageList.add(message);
//用另外一种方式保存
save(message);
//此时设定状态码
resp.setStatus(200);
}
//从服务器获取数据,
// 只做一件事,把messageList准换成json字符串,返回给浏览器即可
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
//响应数据也是一个json格式
//基于objectMapper的writeValue方法.就可以完成转换
resp.setContentType("application/json; charset=utf8");
ObjectMapper objectMapper=new ObjectMapper();
//这个方法同时完成了,吧java对象转成json字符串,并且把这个字符串写到响应对象中
List<Message> messageList = load();
objectMapper.writeValue(resp.getWriter(),messageList);
//第一个参数是Writer对象,表示转成的json字符串,往哪个地方去写
//第二个参数用来存储消息的List,要把哪个对象转成json字符串.
/*
*/
}
// 提供一对方法
// 往数据库中存一条消息
private void save(Message message) {
// JDBC 操作
Connection connection = null;
PreparedStatement statement = null;
try {
// 1. 建立连接
connection = DBUtil.getConnection();
// 2. 构造 SQL 语句
String sql = "insert into messages values(?, ?, ?)";
statement = connection.prepareStatement(sql);
statement.setString(1, message.from);
statement.setString(2, message.to);
statement.setString(3, message.message);
// 3. 执行 sql
statement.executeUpdate();
} catch (SQLException e) {
e.printStackTrace();
} finally {
// 4. 关闭连接.
DBUtil.close(connection, statement, null);
}
}
private List<Message> load() {
List<Message> messageList = new ArrayList<>();
Connection connection = null;
PreparedStatement statement=null;
ResultSet resultSet=null;
try {
//1.和数据库建立连接
connection=DBUtil.getConnection();
//2.构造SQL
String sql="select * from messages";
statement =connection.prepareStatement(sql);
//3.执行SQL
resultSet=statement.executeQuery();
//4.遍历结果结合
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);
}
} catch (SQLException e) {
throw new RuntimeException(e);
}finally {
DBUtil.close(connection,statement,resultSet);
}
return messageList;
}
}