ServletAPI的使用案例-前后端交互的表白墙

这篇具有很好参考价值的文章主要介绍了ServletAPI的使用案例-前后端交互的表白墙。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

目录

1.分析问题

2.设计程序

3.编写代码

后端

前端

连接数据库

4.完整代码


1.分析问题

我们之前学习前端的时候写过一个表白墙的页面的案例,但是这个页面是存在问题的

问题

1.如果刷新页面或者关闭页面重开,之前的数据就丢失了

2.这些输入的数据都是在本地上的,一个机器输入了数据,其他机器是看不见的

需求

为了优化这些问题,我们可以让服务器来存储用户提交的数据,当有新的浏览器打开页面时,就从服务器获取数据,服务器就可以进行"读档""存档"

每次提交数据,触发存档,将数据存到服务器

每次打开/刷新页面,触发读档,将所有数据从服务器读取加载到页面

2.设计程序

写web程序要重点考虑,数据交互的格式,要提前约定好前后端交互的格式,这件事叫做设计前后端交互接口(包括请求数据是什么格式,响应是什么格式,什么时候发请求,浏览器按什么格式解析)

前后端交互的环节:

1.点击提交(向浏览器提交数据,存档)

请求:POST/message

格式:json

ServletAPI的使用案例-前后端交互的表白墙

响应:HTTP/1.1 200 OK

2.页面加载(从服务器获取数据,读档)

请求:GET/message

响应:HTTP/1.1 200 OK

数据格式:json

ServletAPI的使用案例-前后端交互的表白墙

约定的前后端交互数据格式是很灵活的,存在很多的格式,主要是前后端要约定好

能够实现需求即可

3.编写代码

后端

和之前创建第一个Servlet程序相同,准备工作要做好

我们引入的依赖有

maven的依赖

        <dependency>
            <groupId>com.fasterxml.jackson.core</groupId>
            <artifactId>jackson-databind</artifactId>
            <version>2.14.2</version>
        </dependency>

我们还约定了数据交互格式是json,所以需要解析json的jackson库的依赖

ServletAPI的使用案例-前后端交互的表白墙

<!-- 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>

除了使用服务器存储,我们还可以用数据库存储数据,再导入数据库的依赖ServletAPI的使用案例-前后端交互的表白墙

<!-- https://mvnrepository.com/artifact/mysql/mysql-connector-java -->
<dependency>
    <groupId>mysql</groupId>
    <artifactId>mysql-connector-java</artifactId>
    <version>5.1.48</version>
</dependency>

刷新后就可以导入这些依赖了

准备工作完成,下来就编写代码了

创建一个Message Servlet类

注意这里的注解是前面约定过的

ServletAPI的使用案例-前后端交互的表白墙

我们先写向服务器提交数据的代码 

@Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        //向服务器提交数据
        
    }

我们约定过数据格式是json,那么在解析json数据时,就需要设置一个类来描述数据,将数据解析到对应的类的属性中

实现dopost,先定义一个类,来描述body的内容,方便jackson进行json解析

protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        //向服务器提交数据
        ObjectMapper objectMapper = new ObjectMapper();
        //将body中的数据读取出来,json数据=>java对象
        Message message = objectMapper.readValue(req.getInputStream(),Message.class);
        //保存数据
        list.add(message);
        //返回
        resp.setStatus(200);
    }

实现doget,将list的结果返回给前端

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

响应数据也是json格式,刚才存到list中的是一个个message对象,list对应的是json数组,数组中的每个对象就是每个message对象,直接对应起来了,如图

ServletAPI的使用案例-前后端交互的表白墙

那么数据格式转换成json可以通过 ObjectMapper的writeValue()方法将java对象转换成json格式数据,并且写入到resp响应对象中

protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        //设置数据格式
        resp.setContentType("application/json;charset = utf8");
        //从服务器获取数据
        ObjectMapper objectMapper = new ObjectMapper();
        //java对象=>json数据
        objectMapper.writeValue(resp.getWriter(),list);
    }

resp.getWriter()是表示转换的json字符串往哪写,list表示是被转换成json字符串的对象

分开写也可以

ServletAPI的使用案例-前后端交互的表白墙

合成一步就是最开始的代码,那么后端代码就全部写完了

启动服务器,输入URL后:浏览器此时发送了GET请求

ServletAPI的使用案例-前后端交互的表白墙

通过postman发送几个请求

ServletAPI的使用案例-前后端交互的表白墙

 还没有post数据,所以得到的是[],我们提交几个数据

ServletAPI的使用案例-前后端交互的表白墙

然后再GET

ServletAPI的使用案例-前后端交互的表白墙

当我们多post几次时,就会获得这种数组形式的数据了

ServletAPI的使用案例-前后端交互的表白墙

前端

接下来我们编写前端的代码,也就是能够让前端能发起这些请求并解析响应

post是点击提交按钮发起,get是页面加载是发起

我们先将前端代码拷贝至webapp,然后增加交互的代码

先构造一个js对象body用来获取输入框内容

ServletAPI的使用案例-前后端交互的表白墙当前body还是个js对象,网络传输中是不能传输js对象的

需要把js对象构造成约定好的json字符串来传输.js内置了转换库,不用引入解析库了

ServletAPI的使用案例-前后端交互的表白墙

重启服务器过后,输入数据提交,抓包观察结果

ServletAPI的使用案例-前后端交互的表白墙

POST请求抓包结果:

ServletAPI的使用案例-前后端交互的表白墙 可以看到body显然是一个json格式数据,符合我们最初的约定

我们分析一下前后端的交互过程:

ServletAPI的使用案例-前后端交互的表白墙

写到这里我们实现了存档功能,但是刷新后,页面还是没有数据,还要实现读档功能

让浏览器发送GET请求

ServletAPI的使用案例-前后端交互的表白墙

重启服务器后提交一些数据,再次刷新或者重开页面,数据都会被加载到页面上

ServletAPI的使用案例-前后端交互的表白墙

 通过抓包可以发现,当刷新页面时,会触发GET请求来获取服务器的数据

请求

ServletAPI的使用案例-前后端交互的表白墙

响应

ServletAPI的使用案例-前后端交互的表白墙

这里的数据时存储在服务器内存中的,重启服务器,数据仍然会丢失,所以我们需要将数据存储到数据库中,这样就没问题了,或者将数据存到文本文件中也行.这里我们使用数据库,功能更加强大

连接数据库

这里只有一个表,message(from,to,message)

mysql> create table message(`from` varchar(20),`to` varchar(20),message varchar(50));
Query OK, 0 rows affected (0.04 sec)

mysql> desc message
    -> ;
+---------+-------------+------+-----+---------+-------+
| Field   | Type        | Null | Key | Default | Extra |
+---------+-------------+------+-----+---------+-------+
| from    | varchar(20) | YES  |     | NULL    |       |
| to      | varchar(20) | YES  |     | NULL    |       |
| message | varchar(50) | YES  |     | NULL    |       |
+---------+-------------+------+-----+---------+-------+
3 rows in set (0.00 sec)

实现和数据库的操作

我们先封装一些数据库的操作

//封装数据库连接过程
//作为工具类
public class DBUtil {
    //单例饿汉模式
    private static DataSource dataSource = new MysqlDataSource();
    static{
        //使用静态代码块初始化
        ((MysqlDataSource)dataSource).setUrl("jdbc:mysql://127.0.0.1:3306/wall?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 statement, ResultSet resultSet){
        //此处的异常分开捕捉比较好,否则会影响后面的代码不能执行
        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);
            }
        }
    }
}

此时就不需要List来存储了

提供一对方法,存取消息

save方法用来提交一条信息,load方法用来加载所有信息

重启服务器后,提交几次数据

ServletAPI的使用案例-前后端交互的表白墙

控制台打印日志

ServletAPI的使用案例-前后端交互的表白墙

数据库的表中增加了数据,浏览器页面重新加载后,会通过服务器获取到数据库中的数据,以前的数据都会被加载到浏览器页面显示出来

mysql> select*from message;
+------+------+---------+
| from | to   | message |
+------+------+---------+
| 1    | 2    | 3       |
| 3    | 4    | 5       |
+------+------+---------+
2 rows in set (0.00 sec)

4.完整代码

MessageServlet代码

import com.fasterxml.jackson.databind.ObjectMapper;
import sun.plugin2.message.PrintAppletReplyMessage;

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;

class Message{
    public String from;
    public String to;
    public String message;
}
@WebServlet("/message")
public class MessageServlet extends HttpServlet {
    //保存数据的list
    //private List<Message> list = new ArrayList<>();
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        //设置数据格式
        resp.setContentType("application/json;charset = utf8");
        //从服务器获取数据
        ObjectMapper objectMapper = new ObjectMapper();
        //java对象=>json数据
        //objectMapper.writeValue(resp.getWriter(),list);

        List<Message> messageList = load();
        //将list=>json字符串
        String jsonResp = objectMapper.writeValueAsString(messageList);
        System.out.println(jsonResp);
        //将字符串写回到响应的body中
        resp.getWriter().write(jsonResp);
    }

    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        //向服务器提交数据
        ObjectMapper objectMapper = new ObjectMapper();
        //将body中的数据读取出来,json数据=>java对象
        Message message = objectMapper.readValue(req.getInputStream(),Message.class);
        //保存数据
        //list.add(message);
        save(message);
        //返回
        resp.setStatus(200);
    }
    //存一条消息
    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) {
            throw new RuntimeException(e);
        }finally {
            //4.关闭连接
            DBUtil.close(connection,statement,null);
        }

    }
    //取所有消息
    private List<Message> load(){
        List<Message> list = 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.执行
            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");
                list.add(message);
            }
        } catch (SQLException e) {
            throw new RuntimeException(e);
        }finally {
            //5.关闭资源
            DBUtil.close(connection,statement,resultSet);
        }
        return list;
    }
}

封装数据库操作代码

DBUtil

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;

//封装数据库连接过程
//作为工具类
public class DBUtil {
    //单例饿汉模式
    private static DataSource dataSource = new MysqlDataSource();
    static{
        //使用静态代码块初始化
        ((MysqlDataSource)dataSource).setUrl("jdbc:mysql://127.0.0.1:3306/wall?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 statement, ResultSet resultSet){
        //此处的异常分开捕捉比较好,否则会影响后面的代码不能执行
        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);
            }
        }
    }
}

前端代码

<!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: 0 auto;
        }
        h1{
            margin-top: 100px;
            text-align: center;
        }
        p{
            text-align: center;
            color: #666;
            margin: 20px auto;
        }
        .row{
            /* 开启弹性布局 */
            display: flex;
            height: 40px;
            /* 水平方向居中 */
            justify-content: center;
            /* 垂直方向居中 */
            align-items: center;

        }
        .row span{
            width: 50px;
        }
        .row input{
            width: 200px;
            height: 30px;
        }
        .row button{
            width: 250px;
            height: 30px;
            color: aliceblue;
            background-color: orange;
            /* 去掉边框 */
            border: none;
            border-radius: 3px;
        }
        /* 点击反馈 */
        .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>提交</button>
        </div>
    </div>
    <script src="https://cdn.bootcdn.net/ajax/libs/jquery/3.6.4/jquery.min.js"></script>
    <script>
        //实现提交操作,点击提交按钮,将用户输入的内容提交到页面上
        //点击的时候获取输入框内容,然后创建一个新的div.row,将内容构造进去
        let containerDiv = document.querySelector('.container');
        let inputs = document.querySelectorAll('input');
        let button = document.querySelector('button');
        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';
            rowDiv.innerHTML = from + ' 对 ' + to + ' 说: ' + msg;
            containerDiv.appendChild(rowDiv)
            //3.清空之前的输入
            for(let input of inputs){
                input.value = '';
            }
            //4.新增代码,将数据提交给服务器,构造post请求
            //定义js对象,key是字符串,value是js中的变量常量
            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("发布成功");
                }
            });

        }


        //新增:浏览器在页面加载的时候发送get请求,从服务器获取数据并添加到页面中
        $.ajax({
            type:'get',
            url:'message',
            success:function(body){
                //此处拿到的body是一个js数组
                //本来服务器返回的是一个json字符串,但是jquery的ajax能够自动识别并转换成js对象数组
                //遍历数组,取出元素,构造到页面
                for(let message of body){
                     //2.构造新的div
                    let rowDiv = document.createElement('div');
                    rowDiv.className = 'row message';
                    rowDiv.innerHTML = message.from + ' 对 ' + message.to + ' 说: ' + message.message;
                    containerDiv.appendChild(rowDiv);
                }
            }
        });

    </script>
</body>
</html>

至此,这个前后端可交互的网站就完成了,基于这样的机制,我们再添加其它的代码,就能做出其它更多的功能,可以说是从0到1的突破. 文章来源地址https://www.toymoban.com/news/detail-414613.html

到了这里,关于ServletAPI的使用案例-前后端交互的表白墙的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 【毕设必备】手把手带你用Python搭建一个简单的后端服务- API的创建,前后端交互的数据传递,GET,POST,JSON,FLASK

    Python是一种 流行 的高级编程语言,具有易于学习和使用的特性,被广泛应用于各种领域。 简单易学 :Python的语法清晰简洁,易于理解和学习。与其他编程语言相比,Python的语法设计非常直观,使得编程新手也能快速上手。 强大的标准库和丰富的第三方库 :Python拥有一个庞

    2024年02月04日
    浏览(174)
  • Vue入门三(表单控制|购物车案例|v-model进阶|与后端交互|计算属性|监听属性|Vue生命周期)

    v-model双向数据绑定,还可以对输入框数据进行一定的限定。 v-modle 释义 lazy 等待input框的数据绑定时区焦点之后再变化 number 以数字开头并只保留后面的数字,不保留字母;字母开头都保留 trim 去除首位的空格 与后端交互统一使用json编码格式 与后端交互涉及到跨域问题后,

    2024年01月21日
    浏览(52)
  • 使用Servlet实现表白墙网站(前后端互联)小项目,Mac的M1(没有setting)在哪里找到Setting页面,下载smart tomcat及smart tomcat的配置。

    首先我认为,最清楚的就是了解了前后端进行的初步作用,前端是布置画面,制作用户的交互,后端相当于,保存你的每一步操作,每一步进行的操作,历史搜索记录,保存一些数据,以及和前端相互连接,当然这个也是针对这个小项目,要是更大的则也需要更加细化。 目录

    2024年02月08日
    浏览(46)
  • 前后端交互开发模式yapi使用

    接手一个项目组,采用前后端开发模式分离,经过一阵子了解后,发现存在前后端配合不顺畅的情况,存在如下两个问题, 一:没有接口协议,前端开发时先用占位符,等后端开发协议出来后替换,影响效率。 二:前端开发好了, 后端没开发好,前端只能等待后端开发好。 做

    2024年02月13日
    浏览(31)
  • 使用ajax进行前后端交互的方法

    使用ajax进行前后端交互的方法:(我只测试通了json对象作为参数的方式,其他方式我没有测试通过) 1、前端方法: 传参方式:POST 请求类型:json对象 响应类型:json对象 2、后端方法:无需创建一个类来接收前端传来的json字符串,需要注意是:使用的接收参数必须与前端定

    2024年02月14日
    浏览(48)
  • 通过使用WebSocket使前后端数据交互

    1.对WebSocket的了解 WebSocket是一种在单个TCP连接上进行全双工通信的协议 WebSocket使得客户端和服务器之间的数据交换变得更加简单,允许服务端主动向客户端推送数据 在WebSocket API中,浏览器和服务器只需要完成一次握手,两者之间就直接可以创建持久性的连接,并进行双向数

    2024年02月16日
    浏览(42)
  • 使用Axios前后端交互(超详细)建议点赞收藏

    1、安装axios 将目录切换到当前项目目录下,执行下面安装命令: npm install --save axios vue-axios 2、将axios挂载到vue实例上或则直接导入组件中 在mian.js中做如下配置,可将axios挂载到vue实例上: import axios from \\\'axios\\\' import VueAxios from \\\'vue-axios\\\' Vue.use(VueAxios, axios) 3.vue.config.js中写配置代

    2024年02月06日
    浏览(40)
  • 表白墙案例(前端,Java,Mysql)

                    在输入框中输入内容,点击提交,便会在下面以字符串的形式展示出来,并且会将数据保存到数据库中         即使服务器重启,下次再打开表白墙页面,也能够从数据库中获取到之前的数据         前端(HTML,CSS,JS),Java(servlet,Jackson,JDBC),Mysql    

    2024年02月07日
    浏览(33)
  • OpenHarmony:使用网络组件axios与Spring Boot进行前后端交互

    流程图: 前端请求函数 这两个函数是使用axios库发起HTTP GET请求的函数,用于与服务器进行通信 服务器端点: http://192.168.211.1:8090/test/1 这是我本机的ip地址和springboot运行端口,使用在windows终端输入ipconfig可查看 返回值: 该函数返回一个Promise,该Promise在请求成功时将包含

    2024年01月22日
    浏览(54)
  • 校园小情书微信小程序源码 | 社区小程序前后端开源 | 校园表白墙交友小程序

    校园小情书微信小程序源码 | 社区小程序前后端开源 | 校园表白墙交友小程序 表白墙 卖舍友 步数旅行 步数排行榜 情侣脸 漫画脸 个人主页 私信 站内消息 今日话题 评论点赞收藏 服务器环境要求:PHP7.0+ MySQL5.7 https://www.qqmu.com/2422.html

    2024年03月12日
    浏览(70)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包