【小程序】Servlet程序:表白墙

Servlet程序:表白墙


明确表白墙程序和服务器的交互过程
在这里插入图片描述

  • 约定前端和后端,数据交互的格式
  • 此处约定的是以json字符串的格式进行传输

1、点击提交,浏览器先把数据提交到服务器

2、页面加载,浏览器从服务器获取表白信息

3、把客户端传过来的数据存储到数据库中

持久化保存:把浏览器传递来的数据保存到服务器中进行持久化保存

前端页面代码

<!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 = '';
            }

            //[新增]给服务器发起一个post请求,把数据提交给服务器这边
            //定义一个js对象
            let body={
                from:from,
                to:to,
                message:msg
            };
            let strBody = JSON.stringify(body);

            $.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){
                    let rowDiv = document.createElement('div');
                    rowDiv.className = 'row message';
                    rowDiv.innerHTML = message.from+ ' 对 ' + message.to + ' 说: ' + message.message;
                    containerDiv.appendChild(rowDiv)
                }

            }



        });
    </script>
</body>
</html>

后端代码

工具类Util

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;

/**
 * Created with IntelliJ IDEA.
 * Description:工具类  进行连接数据库的操作
 *
 * User: Wangduan
 * Date: 2023-07-07
 * Time: 4:10
 */



public class DBUtil{

    //首先要有DataSource

        private static DataSource dataSource = new MysqlDataSource();

        static
        {
        ((MysqlDataSource)dataSource).setURL("jdbc:mysql://127.0.0.1:3306/messagewall?characterEncoding=utf8&useSSL=false");
        ((MysqlDataSource)dataSource).setUser("root");
        ((MysqlDataSource)dataSource).setPassword("123456");

        }

    public static Connection getConnection() throws SQLException {

        return dataSource.getConnection();
    }

    public static void close(Connection connection, PreparedStatement preparedStatement, ResultSet resultSet){

        if(resultSet!=null){
            try {
                resultSet.close();
            } catch (Exception e) {
                e.printStackTrace();
            }
        }

        if (preparedStatement!=null){
            try{
                preparedStatement.close();
            }catch (Exception e){
                e.printStackTrace();
            }
        }

        if (connection!=null){
            try {
                connection.close();
            } catch (SQLException e) {
                e.printStackTrace();
            }
        }



    }




}

  1. 实例化DataSource对象,来更方便地进行与数据连接

  2. 在静态代码块中,对mysql的URL、用户名、密码进行配置

  3. 写连接和关闭的方法,方便在主类中调用

    下面是在chatgpt中查询的:

    1. MysqlDataSource是MySQL提供的一个实现了DataSource接口的类,用于与MySQL数据库建立连接。通过使用MysqlDataSource,可以配置和管理与MySQL数据库相关的连接信息,如URL、用户名、密码等。
    2. 通过dataSource就可以获取与MySQL数据库建立连接所需的信息,并在需要的时候通过dataSource.getConnection()方法获取一个数据库连接对象。

在使用JDBC进行数据库操作时,使用DataSource可以提供一种更灵活和可管理的方式来获取数据库连接。DataSource是一个接口,代表了与数据库连接池进行交互的对象。

使用DataSource的主要好处包括:

  1. 连接池管理:DataSource可以管理一组数据库连接,这些连接被预先创建并保存在连接池中。这样,在需要与数据库建立连接时,可以从连接池中获取一个可用的连接,而不需要每次都创建和销毁连接。这种连接池管理可以提高性能和可伸缩性,特别是在高并发的情况下。

  2. 连接配置和管理:DataSource可以统一管理数据库连接的配置信息,如数据库URL、用户名、密码、连接超时等。这样,可以集中管理这些配置信息,而不需要在每个连接获取的地方都进行硬编码。同时,可以通过调整连接池的配置参数来优化连接的使用和性能。

  3. 连接的重用和共享:使用DataSource可以实现连接的重用和共享。当一个连接不再需要时,可以将其释放回连接池中,以供其他请求复用。这样可以减少连接的创建和销毁开销,提高系统资源的利用率。

  4. 连接的生命周期管理:通过DataSource,可以定义连接的生命周期,包括连接的创建、销毁、空闲时的检查和回收等。这样可以确保连接的有效性和可靠性,并防止长时间占用连接而导致资源浪费。

总之,使用DataSource可以简化和优化数据库连接的管理和使用,提供更好的性能、可靠性和可维护性。它提供了一种连接池的机制,允许开发人员更方便地获取和释放数据库连接,而无需手动管理连接的创建和销毁。同时,它还提供了连接配置的集中管理,使得数据库连接的使用更加灵活和可配置。

主类

  1. 导入所需的类和包。
  2. 创建一个 Message 类,使用 @Getter@Setter 注解生成相应的 getter 和 setter 方法,用于表示消息对象。
  3. MessageTwo 类继承自 HttpServlet,并使用 @WebServlet 注解指定了它处理的 URL 路径为 /message
  4. MessageTwo 类中定义了一个 ObjectMapper 对象,用于进行 JSON 数据的序列化和反序列化。
  5. doPost 方法用于处理 POST 请求,从请求中获取 JSON 数据,将其转换为 Message 对象,并保存到数据库中。
  6. doGet 方法用于处理 GET 请求,从数据库中加载消息数据,并将其序列化为 JSON 格式返回给客户端。
  7. save 方法用于将 Message 对象保存到数据库中,使用 JDBC 进行数据库操作。
  8. load 方法用于从数据库中加载消息数据,使用 JDBC 进行数据库查询操作。
import com.fasterxml.jackson.databind.ObjectMapper;
import lombok.Getter;
import lombok.Setter;

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.io.InputStream;
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: Wangduan
 * Date: 2023-07-07
 * Time: 4:03
 */

@Getter
@Setter
class Message{
    private String from;
    private String to;
    private String message;
}

@WebServlet("/message")
public class MessageTwo extends HttpServlet {




    //List<Message> messageList = new ArrayList<>();
    ObjectMapper objectMapper=new ObjectMapper();

    //像服务器提交请求
    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {

        //获取请求的字符流
        InputStream inputStream = req.getInputStream();
        //把字符流构造成类对象
        Message message = objectMapper.readValue(inputStream,Message.class);

        //添加到List中
        //messageList.add(message);
        save(message);

        //设置状态码
        resp.setStatus(200);
    }

    //从服务器获取数据
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {

        resp.setContentType("application/json;charset=utf8");

       List<Message> messageList = load();
       objectMapper.writeValue(resp.getWriter(),messageList);


    }

    public void save(Message message){
        //提供一对方法,往jdbc中添加数据

        Connection connection = null;
        PreparedStatement preparedStatement=null;
        //1、先建立连接
        try {

             connection = DBUtil.getConnection();
            //2、编写sql语句
            String sql = "insert into message values(?,?,?)";
            preparedStatement = connection.prepareStatement(sql);
            preparedStatement.setString(1,message.getFrom());
            preparedStatement.setString(2,message.getTo());
            preparedStatement.setString(3,message.getMessage());

            //3、执行sql语句
            preparedStatement.executeUpdate();


        } catch (SQLException e) {
            e.printStackTrace();
        }finally {
            //4、关闭连接
            DBUtil.close(connection,preparedStatement,null);
        }



    }

    public List<Message> load(){

        List<Message> messageList = new ArrayList<>();
        Connection connection =null;
        PreparedStatement preparedStatement = null;
        ResultSet resultSet=null;
        //从服务器获取到数据库中的数据
        try {
            //1、建立连接
             connection = DBUtil.getConnection();
             //2、构造Sql语句
            String sql = "select *from message";
            preparedStatement = connection.prepareStatement(sql);
            //3、执行sql语句
            resultSet = preparedStatement.executeQuery();

            //4、遍历查询
            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);
            }

        } catch (SQLException e) {
            e.printStackTrace();
        }finally {
            DBUtil.close(connection,preparedStatement,resultSet);
        }
        return messageList;

    }

}


1、★★★executeQuery()executeUpdate() 是 JDBC 中用于执行不同类型操作的方法。

  1. executeQuery() 方法:

    • 用于执行 SELECT 查询操作。
    • 返回一个 ResultSet 对象,该对象包含查询结果集的数据。
    • 适用于从数据库中获取数据,可以使用 ResultSet 提供的方法来访问和处理查询结果的数据。
    • 该方法不返回受影响的行数,因为它只用于查询操作,不修改数据库的内容。
  2. executeUpdate() 方法:

    • 用于执行 INSERT、UPDATE 或 DELETE 等更新操作。
    • 返回一个整数值,表示受影响的行数,即数据库中受到影响的记录数量。
    • 适用于修改数据库中的数据,如插入新记录、更新现有记录或删除记录。
    • 该方法不返回查询结果集,因为它主要用于更新操作,而不是从数据库中获取数据。

需要注意的是,这两个方法的使用场景是不同的,根据操作类型选择合适的方法。如果需要执行查询操作并获取查询结果集,应该使用 executeQuery() 方法;如果需要执行更新操作并获取受影响的行数,应该使用 executeUpdate() 方法。

同时,需要确保在调用这些方法之前,已经设置了正确的参数值,并且相关的 PreparedStatement 对象和数据库连接都是有效的。根据具体的需求和操作类型,选择适当的方法来执行数据库操作。


2、在你提供的代码中,preparedStatement.setString() 方法用于设置 PreparedStatement 对象中的参数值。

具体来说,setString(int parameterIndex, String value) 方法用于将字符串值设置到预编译的 SQL 语句中的指定参数位置。在你的代码中,你使用了 message.getFrom()message.getTo()message.getMessage() 方法分别获取 message 对象中的 “from”、“to” 和 “message” 属性的值,并将它们作为参数值传递给 setString() 方法。

例如,preparedStatement.setString(1, message.getFrom()) 表示将 message.getFrom() 的返回值设置为预编译的 SQL 语句中的第一个参数的值。同样地,preparedStatement.setString(2, message.getTo())preparedStatement.setString(3, message.getMessage()) 分别设置了第二个和第三个参数的值。

通过这样的设置,当执行预编译的 SQL 语句时,参数的值会被替换为相应的属性值,从而构建出最终的可执行的 SQL 语句。

需要确保在调用 preparedStatement.setString() 方法之前,已经创建了有效的 PreparedStatement 对象,并且相关的属性和方法在 Message 类中都有正确的定义和实现。同时,还要确保 message 对象中的属性值是有效的,并可以正确地通过 getFrom()getTo()getMessage() 方法获取到。


3、在你提供的代码中,resultSet.getString("from") 是用于从结果集中获取 “from” 列的值,并将其设置到 message 对象的属性中。

具体来说,resultSet.getString(String columnLabel) 方法用于从结果集中获取指定列(字段)的字符串值。在你的代码中,你通过传递 “from” 给 getString() 方法,从结果集中获取 “from” 列的值作为一个字符串。

然后,你使用 message.setFrom() 方法将获取到的字符串值设置到 message 对象的 “from” 属性中,以便后续的处理和使用。

需要注意的是,确保在调用 resultSet.getString("from") 之前,已经执行了查询操作,并将结果集移到了有效的位置,以便能够正确获取列的值。同时,确保 message 对象和相关的类定义中有一个合适的属性和设置方法来存储和获取 “from” 列的值。


pom.xml

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <groupId>org.example</groupId>
    <artifactId>messagewallReview</artifactId>
    <version>1.0-SNAPSHOT</version>

    <properties>
        <maven.compiler.source>8</maven.compiler.source>
        <maven.compiler.target>8</maven.compiler.target>
    </properties>

    <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.3</version>
        </dependency>

        <!-- https://mvnrepository.com/artifact/org.projectlombok/lombok -->
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <version>1.14.8</version>
            <scope>provided</scope>
        </dependency>
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <version>5.1.49</version>
        </dependency>

    </dependencies>

</project>

web.xml

<!DOCTYPE web-app PUBLIC
        "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN"
        "http://java.sun.com/dtd/web-app_2_3.dtd" >
<web-app>
    <display-name>Archetype Created Web Application</display-name>
</web-app>
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值