confession wall program

Table of contents

1. Page code part

2. Design program

2. Implement doPost editing

3. Implement doGet

4. Front-end code part

5. Use database to store data


1. Page code part

In a previous blog, I have already written about the page code implementation of the confession wall, so I won’t repeat it here.

The page code is as follows:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>表白墙</title>
</head>
<body>
    <div class="container">
        <h1>表白墙</h1>
        <p>输入后点击提交,会将信息显示在表格中</p>
        <div class="row">
            <span>谁:</span>
            <input type="text" class="edit">
        </div>
        <div class="row" >
            <span>对谁:</span>
            <input type="text" class="edit">
        </div>
        <div class="row">
            <span>说什么:</span>
            <input type="text" class="edit">
        </div>
        <div class="row">
            <input type="button" value="提 交" id="submit">
        </div>
        <script>
            let submitButton=document.querySelector('#submit');
            submitButton.onclick=function(){
                //1.先获取到编辑框的内容
                let edits=document.querySelectorAll('.edit');
                //依靠.value来获得其输入框的值
                let from=edits[0].value;
                let to=edits[1].value;
                let message=edits[2].value;
                console.log(from,to,message);
                //这里是对用户输入进行合法的校验,看用户输入是否合法
                if(from==''||to==' '||message==''){
                    return;
                }
                //2.根据内容,构造HTML元素(.row里面包含用户输入的话)
                //createElement:创建一个元素
                let row=document.createElement('div');
                row.className='row';
                row.innerHTML=from+'对'+to+'说:'+message;
                //3.把这个新的元素添加到DOM树上
                let container=document.querySelector('.container');
                container.appendChild(row);
                //4.清空原来的输入框
                for(let i=0;i<edits.length;i++){
                    edits[i].value='';
                }
            }
        </script>
        <style>
            /*去除浏览器默认样式:内边距,外边距,内边框和外边框不会撑大盒子*/
            *{
                margin:0;
                padding: 0;
                box-sizing: border-box;
            }
            /*margin:0 auto :意思是 中央居中*/
            .container{
                width: 400px;
                margin:0 auto;
            }
            /*padding:20px auto :h1标签:上下间距20*/
            h1{
               text-align:center;
                padding:20px auto;
            }
            p{
                text-align:center;
                color:#666;
                padding: 10px 0;
                font-size:14px;
            }
            /*display:flex:基于弹性布局
              justify-content:center:水平居中
              align-items:center:垂直居中
            */
            .row{
                height:50px ;
                display: flex;
                justify-content: center;
                align-items:center;
            }
            /*现在对于span和input的长度进行调整*/
            span{
                width:90px;
                font-size: 20px;
            }
            input{
                width:310px;
                height: 40px;
                font-size: 18px;
            }
            /*现在处理一下 提交 按钮
             首先,提交按钮宽度和父元素一样宽
             其次,设置字体颜色和背景颜色
             然后,border:none:作用:为了去除黑边框
                  border-radius:设置四个角角为圆矩形
                  font-size:设置 提交 字体的大小
            */

            #submit{
                width: 400px;
                color: white;
                background-color:orange;
                border:none;
                border-radius:5px;
                font-size: 18px;
            }
            /*点击 提交 按钮 就会改变其背景颜色*/
            #submit:active{
                background-color: black;
            }
        </style>
    </div>
</body>
</html>

2. Design program

The page I wrote before has two very serious problems:

1. If you refresh the page/close the page and reopen it, the previously entered message will disappear.

2. If data is entered on one machine, it cannot be seen on the second machine (these data are all in the local browser)

Solutions:

Let the server store the data submitted by the user and save it by the server

When the page is opened by a new browser, the data is obtained from the server

The server here can be used for archiving and reading operations.

When writing web programs, you must focus on how the front-end and back-end interact, that is, agree on the data format for front-end and back-end interaction.

This process is called designing the front-end and back-end interactive interfaces.

What does the request look like, what does the response look like, when does the browser send the request, and in what format does the browser parse it...

So what aspects involve front-end and back-end interaction?

1. Click Submit, and the browser sends the confession information to the server.

2. The page loads and the browser obtains the confession information from the server.

1. Click Submit, and the browser sends the confession information to the server.

2. The page loads and the browser obtains the confession information from the server.

The agreement here has no fixed mandatory requirements, as long as it ensures that the necessary requirements can be achieved, the purpose here is to ensure that the front and back ends can be aligned.

Note: The path here must be consistent with the previously agreed one.


2. Implement doPost

We need to first define a class to describe the body content of the request to facilitate Jackson's json parsing.

class Message{
    public String from;
    public String to;
    public String message;
}

Then use List to store data

 //使用 List 变量保存所有消息
    private List<Message> messagesList = 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);
        //此处,通过一个简单粗暴的方式来完成保存
        messagesList.add(message);
        //此处的设定状态码可以省略,不设置,默认也是200
        resp.setStatus(200);
    }

What doPost does is to add the parsed message to the List.


3. Implement doGet

On the other hand, implement doGet, that is, return the results of the List to the front end

Response data is also a json data

Based on the writeValue method of objectMapper, List <Message> can be converted into json format.

This method simultaneously completes the conversion of java objects into json and writing the json string into the response object.

The first parameter is the Writer object, which indicates where to write the converted json string. The second parameter is the List in which the message is currently stored, which means which object should be converted into json. 

If divided into two steps, it would be written like this:

    //从服务器获取数据
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        ObjectMapper objectMapper = new ObjectMapper();
        //显示告诉浏览器,数据是 json 格式,并且字符集是 utf8
        resp.setContentType("applicaion/json; charseet=utf8");
        objectMapper.writeValue(resp.getWriter(),messagesList);
    }

For doGet, just convert the MessageList into a json string and return it to the browser

class Message{
    public String from;
    public String to;
    public String message;
}

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

    //使用 List 变量保存所有消息
    private List<Message> messagesList = 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);
        //此处,通过一个简单粗暴的方式来完成保存
        messagesList.add(message);
        //此处的设定状态码可以省略,不设置,默认也是200
        resp.setStatus(200);
    }

    //从服务器获取数据
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        ObjectMapper objectMapper = new ObjectMapper();
        //显示告诉浏览器,数据是 json 格式,并且字符集是 utf8
        resp.setContentType("applicaion/json; charset=utf8");
        //objectMapper.writeValue(resp.getWriter(),messagesList);

        //把 java 对象转换成 json 字符串
        String jsonResp = objectMapper.writeValueAsString(messagesList);
        //把字符串写回到响应 body 中
        resp.getWriter().write(jsonResp);
    }
}

Having written this, the backend of the confession wall is complete. We can open postman to test the code.

Currently this just returns a json string to the front end. To become a key-value pair, additional code is required.


4. Front-end code part

Next, let’s write the front-end code, which allows the page to initiate the above request and parse the response

post is initiated when the submit button is clicked, and get is initiated when the page is loaded.

This code is defining a js object (key-value pair similar to json)

Key is actually a string, and value is a variable/constant in js.

js requires that the key in the object must be a string, so the "" here can be omitted

The current body is a js object, not a string. For network transmission, only strings can be stringed, not objects.

Therefore, we need to convert the current object into a string

js has a built-in library for converting json

                //4、[新增] 给服务器发起 post 请求,把上述数据提交到服务器
                let body = {
                    from :from,
                    to:to,
                    message:msg
                };
                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("数据发布成功");
                    }
                });

Next, you need to implement the file reading operation and let ajax send a GET request.

            //[新增] 在页面加载的时候,发送 GET 请求,从服务器获取到数据并添加到页面中
            $.ajax({
                type:'get',
                url:'message',
                success:function(body){
                    //此处拿到的 body 就是一个 js 的对象数组了
                    //本来服务器返回的是一个 json 格式的字符串,但是 jquery 的 ajax 可以自动识别,
                    //自动帮我们把 json 字符串转成 js 对象数组
                    //接下来,遍历这个数组,把元素取出来,并且构造到页面中即可
                    for(let message of body){
                        //针对每个元素构造一个 div
                        let row=document.createElement('div');
                        row.className='row';
                        row.innerHTML=message.from +'对'+message.to +'说:'+message.message;
                        containerDiv.appendChild(rowDiv);
                    }
                }
            });

5. Use database to store data

Currently our data is saved in memory (variables), and it will be gone when we restart the server.

If you want to save it persistently, you need to write it to a file (hard disk)

1. Directly use the stream object to write to the text file

2. With the help of database

Create data table

There is only one table here: message (from, to, message)

Implement database operations:

//通过这个类,把数据库连接过程封装一下
//此处,把 DBUtil 作为一个工具类,提供 static 方法,供其它方法来调用
public class DBUtil {
    //静态成员是跟随类对象的,类对象在整个进程中,只有唯一一份
    //静态成员相当于也是唯一的实例(单例模式,饿汉模式)
    private static DataSource dataSource = new MysqlDataSource();

    static {
        //使用静态代码块,针对 dataSourse 进行初始化
        ((MysqlDataSource)dataSource).setUrl("jdbc:mysql://127.0.0.1:3306/java?charactorEncoding=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 statement, ResultSet resultSet)  {
       //此处的三个 try catch 分开写更好,避免前面的异常导致后面的代码无法执行
        if (resultSet != null){
            try {
                resultSet.close();
            } catch (SQLException e) {
                throw new RuntimeException(e);
            }
        }
        if (statement != null){
            try {
                statement.close();
            } catch (SQLException e) {
                throw new RuntimeException(e);
            }
        }
        if (connection != null){
            try {
                connection.close();
            } catch (SQLException e) {
                throw new RuntimeException(e);
            }
        }
    }
}

The data to be inserted is three variables. To fill these three variables into Sql, placeholders are needed.

class Message{
    public String from;
    public String to;
    public String message;
}

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

    //使用 List 变量保存所有消息
    //private List<Message> messagesList = 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);
        //此处,通过一个简单粗暴的方式来完成保存
        //messagesList.add(message);
        save(message);
        //此处的设定状态码可以省略,不设置,默认也是200
        resp.setStatus(200);
    }

    //从服务器获取数据
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        ObjectMapper objectMapper = new ObjectMapper();
        //显示告诉浏览器,数据是 json 格式,并且字符集是 utf8
        resp.setContentType("applicaion/json; charset=utf8");
        //objectMapper.writeValue(resp.getWriter(),messagesList);

        //把 java 对象转换成 json 字符串
        List<Message> messagesList = load();
        String jsonResp = objectMapper.writeValueAsString(messagesList);
        //把字符串写回到响应 body 中
        resp.getWriter().write(jsonResp);
    }

    //提供一对方法
    //往数据库中存一条消息
    private void save(Message message) {
        //JDBC 操作
        //1、建立连接
        Connection connection = null;
        PreparedStatement statement = null;
        try {
            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) {
            throw new RuntimeException(e);
        }finally {
            //4、关闭连接
            DBUtil.close(connection,statement,null);
        }
    }

    //从数据库中取所有消息
    private List<Message> load(){
        List<Message> messageList = new ArrayList<>();
        PreparedStatement statement = null;
        Connection connection = 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){
            e.printStackTrace();
        }finally {
            //5、需要释放资源,断开连接
            DBUtil.close(connection,statement,resultSet);
        }
        return messageList;
    }
}

Guess you like

Origin blog.csdn.net/weixin_73616913/article/details/132501260