servletApi详解

前言

我们在解释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 数据存入数据库

使用文件的方式存储留言固然可行, 但是并不优雅. 我们还可以借助数据库完成存储工作.

  1. 创建数据库, 创建 messages 表
    在这里插入图片描述

在这里插入图片描述

  1. 创建 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();
            }
        }
    }
}
  1. 提供 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;
    }
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

忘忧记

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值