java里module 表白_java里module 表白

java里module 表白_servlet_02


java里module 表白_java里module 表白_03


📍内容导读📍

  • 🍅1.约定接口
  • 🍅2.后端框架搭建
  • 🍅3.实现服务器端代码
  • 🍅4.构造请求测试服务器端
  • 🍅5.调整前端页面代码
  • 🍅6.数据存入数据库


java里module 表白_java_04

🍅1.约定接口

实现这个表白墙案例的第一步,就是需要自定义应用层协议,确定好客户端服务器如何进行交互

数据能够进行存储的格式有很多种,也就是前后端需要共同指定数据格式,以便在客户端向服务器发送给去数据请求后,能够按照彼此约定好的应用层协议进行数据解析

对于表白墙来说,主要要提供两个接口,要约定好客户端要发送一个怎样的HTTP请求服务器返回一个怎样的HTTP响应,下边我们会直接指定数据格式json格式:

接口一

告诉服务器,当前留言了一条怎样的数据

(当用户点击提交按钮的时候,就会给服务器发送一个HTTP请求,让服务器把这个消息给存下来)

java里module 表白_java里module 表白_05

接口二

从服务器获取到当前都有哪些留言数据

(当页面加载,就需要从服务器获取到曾经存储的留言内容)

java里module 表白_java_06

在我们确定好接口后,就可以进行代码的编写了。

🍅2.后端框架搭建

我们接下来,就按照常规Servlet程序的搭建流程进行搭建,先进性整体框架的搭建。

1.创建maven项目

java里module 表白_javascript_07


2.引入依赖

(引入Servlet依赖和JSON依赖)

java里module 表白_servlet_08


3.创建目录

java里module 表白_java_09


4.编写代码

(只编写简单代码,用于测试是否搭建接口完成)

@WebServlet("/message")
public class MessageServlet extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        resp.getWriter().write("hello get");
    }

    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        resp.getWriter().write("hello post");
    }
}

5、6.打包部署

java里module 表白_java里module 表白_10


7.验证

java里module 表白_服务器_11

🍅3.实现服务器端代码

先将消息列表存储到内容中(通过顺序表实现)

/**
 * 与json格式对应的类
 */
class Message {
    public String from;
    public String to;
    public String message;
}

@WebServlet("/message")
public class MessageServlet extends HttpServlet {
    //用于将类和json进行转换的类
    private ObjectMapper objectMapper=new ObjectMapper();
    //用于存放消息的顺序表
    private List<Message> messages=new ArrayList<>();

    /**
     * 处理提交消息请求,对数据进行保存
     */
    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        Message message=objectMapper.readValue(req.getInputStream(),Message.class);
        messages.add(message);
        //指定响应的数据格式
        resp.setContentType("application/json;charset=utf8");
        resp.getWriter().write("{\"ok\":true}");
    }

    /**
     *获取消息列表,把消息列表中的内容返回给客户端
     */
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        //将Java对象转成JSON格式字符串
        String jsonString=objectMapper.writeValueAsString(messages);
        System.out.println("jsonString:"+jsonString);
        resp.setContentType("application/json;charset=utf8");
        resp.getWriter().write(jsonString);
    }
}

🍅4.构造请求测试服务器端

利用应用postman来进行构造请求,用于测试服务器端代码。

java里module 表白_servlet_12


postman可自行下载,专门用来构造HTTP请求,进行服务器端的测试。首先我们在idea通过smart tomcat启动服务器,然后进行测试。

java里module 表白_服务器_13


对接口一进行测试,构造POST请求,输入数据。

java里module 表白_java里module 表白_14

对接口二进行测试,构造GET请求,得到对接口一测试时输入的消息列表,测试完成。

java里module 表白_java里module 表白_15

🍅5.调整前端页面代码

在之前文章【JavaScript进阶3.2 表白墙案例】的表白墙代码可以直接拿来用,再进行调整,完成两个接口的功能即可。

java里module 表白_java里module 表白_16


将该前端html文件拷贝到webapp目录下,再进一步调整完善前端代码的ajax请求

对前端代码的调整,主要的逻辑有两部分:
1.点击提交按钮时,ajax要构造数据发送给服务器。
2.页面加载的时候,从服务器获取消息列表,并在界面上直接显示。

首先我们还是先引入jQuery

java里module 表白_服务器_17


功能1:把当前输入框的内容,构造成一个HTTP POST请求,通过ajax发送给服务器。

java里module 表白_java_18


功能2:通过函数完成消息列表的获取打印。

java里module 表白_java_19


完整前端代码:

<!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>Document</title>
</head>
<body>
    <style>
        * {
            margin: 0;
            padding: 0;
            box-sizing: border-box;
            background-color: rgb(30,100,200);
        }

        .container {
            width: 100%;
        }

        h3 {
            text-align: center;
            padding: 30px 0;
            font-size: 24px;
            color: rgb(255,140,10);
        }
        p {
            text-align: center;
            color: rgba(255, 50, 100);
            font-size: 18px;
            padding: 5px 0;
        }
        .row {
            width: 400px;
            height: 50px;
            margin: 0 auto;

            display: flex;
            justify-content: center;
            align-items: center;
        }
        .row span{
            width: 100px;
            height: 40px;
            text-align: center;
            padding-right: 0px;
            font-size: 24px;
            color: rgb(255,140,10);
        }
        .row input {
            width: 300px;
            height: 40px;
            border: 2px solid  rgb(255, 140,160);
            border-radius: 5px;
            outline: 0;
            text-align: left;
            padding-left: 0px;
            margin-left: 0px;
            text-indent: 0.4em;
            font-size: 20px;

            color: rgb(9, 245, 135);
        }
        .row #submit{
            width: 200px;
            height: 40px;
            border-radius: 10px;
            font-size: 24px;
            border: 0px solid  rgb(255, 140, 160);
            background-color:  rgb(255, 140, 160);
            color:  aliceblue;
            line-height: 40px;
            margin-top: 8px;
        }
        .row #submit:active{
            background-color: rgb(140,180,240);
        }
    </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 src="https://cdn.bootcdn.net/ajax/libs/jquery/3.6.0/jquery.min.js"></script>
    <script>
        function getMessages() {
            $.ajax({
                type:"get",
                url:'message',
                success:function(body) {
                    let container=document.querySelector('.container');
                    for(let message of body) {
                        let div=document.createElement('div');
                        div.innerHTML=message.from+'对'+message.to+'说:'+message.message;
                        div.className='row';
                        container.appendChild(div);
                    }
                }
            })
        }

        getMessages();
        // 当用户点击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='';
            }

            //4.功能一
            let body={
                from:from,
                to:to,
                message:msg
            };
            $.ajax({
                type:"post",
                url:"message",
                contentType:"application/json;charset=utf8",
                data:JSON.stringify(body),
                success:function(body) {
                    alert("消息提交成功!");
                },
                error:function(body) {
                    alert("消息提交失败!");
                }
            });
        }
    </script>
</body>
</html>

效果预览:

java里module 表白_java里module 表白_20


通过将消息存入内容的方式,只要服务器不重启,可以使得页面即使刷新,消息列表也不会丢失,但如果将服务器重启,消息列表一定会丢失。所以如果想要将数据持久化存储,需要将数据写入硬盘,可以通过写入文件或者写入数据库的方式,下边我们就将消息存入数据库,实现数据的持久化存储

🍅6.数据存入数据库

1)引入mysql数据库依赖

java里module 表白_javascript_21


2)创建数据库

java里module 表白_javascript_22

3)创建DBUtil类,用于与数据库的交互。

public class DBUtil {
    private static final String url="jdbc:mysql://localhost:3306/homework?characterEncoding=utf8&useSSL=false";
    private static final String user="root";
    private static final String password="1234";

    private volatile static DataSource dataSource=null;

    //线程安全的单例模式
    private static DataSource getDataSource() {
        if(dataSource==null) {
            synchronized (DBUtil.class) {
                if(dataSource==null) {
                    dataSource=new MysqlDataSource();
                    ((MysqlDataSource)dataSource).setURL(url);
                    ((MysqlDataSource)dataSource).setUser(user);
                    ((MysqlDataSource)dataSource).setPassword(password);
                }
            }
        }
        return dataSource;
    }

    public static Connection getConnection() throws SQLException {
        return getDataSource().getConnection();
    }

    public static void close(Connection connection,PreparedStatement statement,ResultSet resultSet) {
        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();
            }
        }
    }
}

由于客户端发出的请求可能存在线程安全的问题,所以得到数据源的方法使用线程安全的单例模式

java里module 表白_servlet_23


4)调整Servlet代码,完成数据存入数据库关键方法:

java里module 表白_java里module 表白_24


java里module 表白_服务器_25

完整代码:

/**
 * 与json格式对应的类
 */
class Message {
    public String from;
    public String to;
    public String message;
}

@WebServlet("/message")
public class MessageServlet extends HttpServlet {
    //用于将类和json进行转换的类
    private ObjectMapper objectMapper=new ObjectMapper();
    //用于存放消息的顺序表
//    private List<Message> messages=new ArrayList<>();

    /**
     * 处理提交消息请求,对数据进行保存
     */
    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        Message message=objectMapper.readValue(req.getInputStream(),Message.class);
//        messages.add(message);
        //指定响应的数据格式
        resp.setContentType("application/json;charset=utf8");
        resp.getWriter().write("{\"ok\":true}");
    }

    /**
     *获取消息列表,把消息列表中的内容返回给客户端
     */
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        //将Java对象转成JSON格式字符串
        String jsonString=objectMapper.writeValueAsString(messages);
        System.out.println("jsonString:"+jsonString);
        resp.setContentType("application/json;charset=utf8");
        resp.getWriter().write(jsonString);
    }

    /**
     * 把一条消息保存到数据库中
     * @param message
     */
    private void save(Message message) {
        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 {
            DBUtil.close(connection,statement,null);
        }
    }

    /**
     * 从数据库中获取到所有的消息
     * @return
     */
    private List<Message> load() {
        List<Message> messages=new ArrayList<>();
        Connection connection=null;
        PreparedStatement statement=null;
        ResultSet resultSet=null;
        try {
            connection=DBUtil.getConnection();
            String sql="select * from message";
            statement=connection.prepareStatement(sql);
            resultSet=statement.executeQuery();
            while (resultSet.next()) {
                Message message=new Message();
                message.from=resultSet.getString("from");
                message.to=resultSet.getString("to");
                message.message=resultSet.getString("message");
                messages.add(message);
            }

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

效果演示:

java里module 表白_java里module 表白_26

由上述演示可得,现在的消息已经写入数据库,能够持久化存储了,至此,表白墙小案例也就大功告成了,快自己动手试试吧!