表白墙(服务器版)

在这里插入图片描述

文章目录

  • 一、准备工作
  • 二、前后端交互
    • 后端
    • 前端
  • 三、数据库版本

一、准备工作

我们之前实现过这样一个表白墙,具体前端代码参考 表白墙 这篇文章
表白墙(服务器版)_第1张图片
但是我们之前写的这个表白墙有一些问题:
1.如果我们刷新页面/重新开启,之前的数据就不见了
2.我们只能在单机操作,其他机器不能看见
于是我们现在就来解决这些问题,让服务器来存储用户提交的数据,当有新的浏览器打开该页面时,在从服务器获取数据,首先我们创建一个web项目,引入相关依赖
表白墙(服务器版)_第2张图片
在src下创建webapp/WEB-INF/web.xml,并在pom.xml下面引入mysql依赖,servlet依赖和jackson依赖

    <dependencies>
        <dependency>
            <groupId>mysqlgroupId>
            <artifactId>mysql-connector-javaartifactId>
            <version>5.1.49version>
        dependency>
        
        <dependency>
            <groupId>javax.servletgroupId>
            <artifactId>javax.servlet-apiartifactId>
            <version>3.1.0version>
            <scope>providedscope>
        dependency>

        
        <dependency>
            <groupId>com.fasterxml.jackson.coregroupId>
            <artifactId>jackson-databindartifactId>
            <version>2.14.1version>
        dependency>
    dependencies>

引入依赖之后记得刷新,
然后创建servelet类,并指明访问路径为message,具体实现我们后面在具体写

@WebServlet("/messagewell")
public class MessageWellServlet extends HttpServlet {
    

然后我们将我们之前写好的表白墙前端代码导入到webapp目录下,大家之前去我之前的文章里复制即可
表白墙(服务器版)_第3张图片

二、前后端交互

既然我们想要进行前后端交互,就得约定好接口,前端给服务器发什么样的HTTP请求,服务器返回什么样的HTTP响应
1.页面加载,浏览器从服务器获取表白信息
前端请求: GET/message
响应: HTTP/1.1 200OK,返回json数组形式的数据

2.提交表白信息,浏览器将表白信息发送到服务器
前端请求:POST/message,发送json形式的数据
响应:HTTP/1.1 200OK

后端

表白墙(服务器版)_第4张图片
我们前端提交数据后,使用json格式发给服务器,我们需要构建一个这样的类,然后使用jackson进行接收数据

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

我们来实现一下当前端提交数据时,我们服务器的处理

    List<Message> list = new ArrayList<>();
    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        ObjectMapper objectMapper = new ObjectMapper();
        //将body中的内容进行读取
        Message message = objectMapper.readValue(req.getInputStream(),Message.class);
        //将获取到的message对象加入到成员变量list中
        list.add(message);
        //设置响应状态码
        resp.setStatus(200);
    }

有了doPost的基础,我们doGET方法就简单的多了,直接将list中的所有数据写回响应即可

    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        //设置响应格式
        resp.setContentType("application/json; charset=utf8");
        ObjectMapper mapper = new ObjectMapper();
        mapper.writeValue(resp.getWriter(),list);
    }

在这里插入图片描述
该方法是将java对象转成json字符串,并将其写入到响应中,如果大家觉得这个方法看起来费劲的话,大家也可以换一种方法

    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        //设置响应格式
        resp.setContentType("application/json; charset=utf8");
        ObjectMapper mapper = new ObjectMapper();
        //将java对象转成json字符串
        String jsonResp = mapper.writeValueAsString(list);
        resp.getWriter().write(jsonResp);
    }

前端

我们前端需要发送两部分请求:
1.post,当我们点击提交表白信息的时候发起
2.get,我们加载页面的时候发起

我们使用VScode打开前端代码,引入jquery依赖

<script src="https://cdn.bootcdn.net/ajax/libs/jquery/3.6.4/jquery.min.js"></script>

在这里插入图片描述
然后我们使用ajax构造请求
表白墙(服务器版)_第5张图片
我们看一下我们之前写的前端代码,当我们onclick提交时,我们只是构造了一个div加入到页面内,现在我们增加一下,让其提交给后端
表白墙(服务器版)_第6张图片

我们将输入框读取到的数据,构建成一个js对象,但是我们body只能传输字符串不能传输对象,于是我们需要将对象转成一个json格式的字符串

   strBody = JSON.stringify(body);
            strBody = JSON.stringify(body);
            $.ajax({
                type: 'post',
                url: 'messagewell',
                data: strBody,
                contentType: "application/json; charset=utf8",
                success: function(body) {
                    console.log("数据提交成功");
                }
            });

然后使用ajax将数据提交给服务器,我们来测试一下当前代码,我们使用tomcat部署,并访问
表白墙(服务器版)_第7张图片
表白墙(服务器版)_第8张图片
然后我们点击提交,我们看到确认发送了一个HTTP请求
表白墙(服务器版)_第9张图片
表白墙(服务器版)_第10张图片
这里就证明我们提交表白信息这一前后端操作是正确的
接下来我们来实现当我们刷新页面时读取服务器数据,我们使用ajax发送GET请求

        //当我们页面加载时,给服务器发送GET请求,获取数据,添加到页面中
        $.ajax({
            type: 'get',
            url: 'messagewell',
            success: function(body) {
                //此数body就是一个js格式的字符串,但是我们这里需要js对象数组
                //jquery会帮我们将js对象字符串解析成js对象数组
                for(let message of body) {
                    let rowDiv = document.createElement('div');
                    rowDiv.className = 'row';
                    rowDiv.innerHTML = message.from + ' 对 ' + message.to + ' 说 ' + message.message;
                    containerDiv.appendChild(rowDiv);
                }
            }
        })

我们这里的body,jquery为我们将js格式字符串解析为js对象数组,我们需要创建div标签,将每个js对象的数据添加到里面,然后将div添加到页面即可
现在我们重启服务器来验证一下
表白墙(服务器版)_第11张图片
我们先随便提交几条数据,然后我们来尝试一下刷新页面
表白墙(服务器版)_第12张图片
我们刷新后,数据仍然在页面上,我们在刷新的同时,给服务器发送了一个GET请求
表白墙(服务器版)_第13张图片
同样的服务器将所有的表白信息响应给我们的浏览器
表白墙(服务器版)_第14张图片
这样一个服务器版本的表白墙就实现完成了,大家需要注意的是我们的数据是在内存中存放的,如果我们重启服务器之后,之前的数据就不见了,如果想要持久化存储就需要借助数据库了

三、数据库版本

我们这里只需要创建一张message信息表,表中有三个属性(from,to,message)
表白墙(服务器版)_第15张图片
大家需要注意我们在创表过程中的一些问题,因为我们的from和to是我们mysql中的关键字,所以我们需要加上`,接下来我们就使用JDBC来和数据库进行交互操作
因为我们数据库连接操作和关闭资源需要频频使用,所以我们这里创建一个DBUtil工具类来简化操作

import com.mysql.jdbc.jdbc2.optional.MysqlDataSource;
import javax.sql.DataSource;
import java.sql.*;
//DButi作为工具类,供其他类使用
public class DBUtil {
    private static DataSource dataSource = new MysqlDataSource();
    static{
        //对datasuorce初始化
        ((MysqlDataSource)dataSource).setURL("jdbc:mysql://127.0.0.1:3306/zd?characterEncoding=utf8&useSSL=false");
        ((MysqlDataSource)dataSource).setUser("root");
        ((MysqlDataSource)dataSource).setPassword("自己的密码");
    }
    //通过该方法获取连接
    public static Connection getConnection() throws SQLException {
        return dataSource.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();
            }
        }
    }
}

接下来我们在servlet类下实现两个方法,save()将我们前端提交的数据添加到数据库中,load()将我们数据库中的所有数据返回给前端

    public void save(Message message) {
        Connection connection = null;
        PreparedStatement statement = null;
        try {
            //获取连接
            connection = DBUtil.getConnection();
            //构造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);
            //执行sql
            statement.executeUpdate();
        }catch (SQLException e) {
            e.printStackTrace();
        }finally {
            //关闭连接
            DBUtil.close(connection,statement,null);
        }
    }
    public List<Message> load() {
        Connection connection = null;
        PreparedStatement statement = null;
        ResultSet resultSet = null;
        List<Message> messageList = new ArrayList<>();
        try {
            //获取连接
            connection = DBUtil.getConnection();
            //构造sql语句
            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");
                messageList.add(message);
            }
        }catch (SQLException e) {
            e.printStackTrace();
        }finally {
            //关闭连接
            DBUtil.close(connection,statement,resultSet);
        }
        return messageList;
    }

表白墙(服务器版)_第16张图片
表白墙(服务器版)_第17张图片

你可能感兴趣的:(JAVA,EE,servlet,java,前端)