表白墙服务器版【交互接口、服务器端代码、前端代码、数据存入文件/数据库】

news2024/10/6 22:33:01

文章目录

  • 一、准备工作
  • 二、约定前后端交互接口
  • 三、实现服务器端代码
  • 四、调整前端页面代码
  • 五、数据存入文件
  • 六、数据存入数据库
  • a46959635a9a4887b871e33e071411f3.png

一、准备工作

1) 创建 maven 项目
 
2) 创建必要的目录 webapp, WEB-INF, web.xml;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>

3) 引入依赖(Servlet、Jackson)

4) 把表白墙前端页面代码拷贝到 webapp 目录中

 

二、约定前后端交互接口

所谓 "前后端交互接口" 是进行 Web 开发中的关键环节。

为了完成前后端交互,要约定两个交互接口:

1.从服务器上获取到所有消息:

请求: GET/message

响应: JSON 格式

{

       {from:"xxx" ,to:"xxx", message:"xxxxxx"}

        ..............

        .............

}

2.往服务器上提交数据

请求: body 也为 JSON 格式    

POST/message

 {from:"xxx" ,to:"xxx", message:"xxxxxx"}

响应: JSON 格式

{ok:1}

三、实现服务器端代码

//这个类表示一条消息的数据格式
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> messageList = new ArrayList<>();

    //doGet方法用来从服务器上获取消息
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        resp.setContentType("application/json;charset=utf-8");
        //writeValue就是把messageList对象转换成json格式的字符串,并通过写入响应(resp.getWriter())返回
        objectMapper.writeValue(resp.getWriter(),messageList);
    }

    //doPost方法用来把客户端的数据提交到服务器
    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        //readValue第一个参数可以支持一个字符串,也可以放inputStream对象;第二个参数是用来接收读取到的结果
        //返回值放到Message对象中
        //通过这个代码就完成了读取body,并且解析成json的过程
        Message message = objectMapper.readValue(req.getInputStream(),Message.class);
        messageList.add(message);
        resp.setContentType("application/json;charset=utf-8");
        resp.getWriter().write("{\"ok\":1}");
    }
}

四、调整前端页面代码

 <script src="https://lib.baomitu.com/jquery/1.12.4/jquery.min.js"></script>
    <script>
        //1.在页面加载的时候访问服务器,从服务器这边获取到消息列表,并展示出来
        function load(){
            $.ajax({
                type:'GET',
                url:'message',
                success: function(data,status){
                    let container = document.querySelector('.container');
                    for(let message of data){
                        let row = document.createElement('div');
                        row.className = 'row';
                        row.innerHTML = message.from + '对' + message.to + '说: ' + message.message;
                        container.appendChild(row);
                    }
                }
            });
        }
        load();
        //2.点击提交按钮的时候,把当前的数据构造成一个http请求,发送给服务器
        let submitButon = document.querySelector('#submit');
        submitButon.onclick = function(){
            //1.先获取到编辑框中的内容
            let edits = document.querySelectorAll('.edit');
            console.log(edits);
            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里面包含用户输入的话
            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 = '';
            }
            //5.构造成一个http请求,发送给服务器
            $.ajax({
                type:'POST',
                url:'message',
                //data里面就是body数据
                data: JSON.stringify({from:from, to:to, message:message}),
                contentType: "application/json;charset=utf-8",
                success: function(data,status){
                    if(data.ok == 1){
                        console.log('提交成功');
                    }else{
                        console.log('提交失败');
                    }
                }
            })
        }
    </script>
此时在浏览器通过 URL http://127.0.0.1:8080/messageWall924/表白墙.html访问服务器, 即可看
到 。

 数据此时是存储在服务器的内存中 ( private List<Message> messages = new ArrayList<Message>(); ), 一旦服务器重启, 数据仍然会丢失。

五、数据存入文件

在上面的代码中,我们是把数据保存在messageList这个变量里面的,如果我们要把数据放在文件中,进行持久化存储,就不需要这变量了。

FileWriter fileWriter = new FileWriter(filePath,true)

java打开文件主要由三种方式:

1.读方式打开(使用输入流对象的时候)

2.写方式打开(使用输出流对象的时候)这种方式会清空原有内容

3.追加写方式打开(使用输出流对象的时候) ,这种方式不会清空原有内容,而是直接在文件内容后面拼接。后面加上true就是追加写状态。

数据存入文件完整代码如下:

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> messageList = new ArrayList<>();

    //保存文件的路径
    private String filePath = "d:code/java/messageWall924/messages924.txt";
    //doGet方法用来从服务器上获取消息
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        resp.setContentType("application/json;charset=utf-8");
        //writeValue就是把messageList对象转换成json格式的字符串,并通过写入响应(resp.getWriter())返回
        List<Message> messageList = load();
        objectMapper.writeValue(resp.getWriter(),messageList);
    }
    private List<Message> load(){
        //把读到的数据放到List<Message>中
        List<Message> messageList = new ArrayList<>();
        System.out.println("开始从文件加载数据!");
        //此处需要按行读取,FileReader不支持,需要套上一层BufferedReader
        try(BufferedReader bufferedReader = new BufferedReader(new FileReader(filePath))){
            while (true){
                String line = bufferedReader.readLine();
                if (line == null){
                    break;
                }
                //读取到的内容,就解析成Message对象
                String[] tokens = line.split("\t");
                Message message = new Message();
                message.from = tokens[0];
                message.to = tokens[1];
                message.message = tokens[2];
                messageList.add(message);
            }
        }catch (IOException e){
            e.printStackTrace();
        }
        return messageList;
    }

    //doPost方法用来把客户端的数据提交到服务器
    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        //readValue第一个参数可以支持一个字符串,也可以放inputStream对象;第二个参数是用来接收读取到的结果
        //返回值放到Message对象中
        //通过这个代码就完成了读取body,并且解析成json的过程
        Message message = objectMapper.readValue(req.getInputStream(),Message.class);
        //这里进行一个写文件操作
        save(message);


        resp.setContentType("application/json;charset=utf-8");
        resp.getWriter().write("{\"ok\":1}");
    }
    private void save(Message message){
        System.out.println("数据开始写入文件");
        try(FileWriter fileWriter = new FileWriter(filePath,true)){
            fileWriter.write(message.from + '\t' + message.to +
                    '\t' + message.message + '\n');
        }catch (IOException e){
            e.printStackTrace();
        }
    }
}

六、数据存入数据库

1) 在 pom.xml 中引入 mysql 的依赖
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <version>5.1.47</version>
        </dependency>
2) 创建数据库, 创建 messages 表
1249ea2809ed445f8f5f35dc31bc20b9.png

 

 3) 创建 DBUtil 类

DBUtil 类主要实现以下功能:
创建 MysqlDataSource 实例, 设置 URL, username, password 等属性。
提供 getConnection 方法, 和 MySQL 服务器建立连接。
提供 close 方法, 用来释放必要的资源。
public class DBUtil {
    private static final String URL = "jdbc:mysql://127.0.0.1:3306/messageWall924?characterEncoding=utf8&useSSL=false";
    private static final String USERNAME = "root";
    private static final String PASSWORD = "1234";

    private static volatile DataSource dataSource = null;

    public static DataSource getDataSource(){
        if (dataSource == null){
            synchronized (DBUtil.class){
                if (dataSource == null){
                    dataSource = new MysqlDataSource();
                    ((MysqlDataSource)dataSource).setURL(URL);
                    ((MysqlDataSource)dataSource).setUser(USERNAME);
                    ((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();
            }
        }
    }
}
4) 修改 load 和 save 方法, 改成操作数据库

    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        //readValue第一个参数可以支持一个字符串,也可以放inputStream对象;第二个参数是用来接收读取到的结果
        //返回值放到Message对象中
        //通过这个代码就完成了读取body,并且解析成json的过程
        Message message = objectMapper.readValue(req.getInputStream(),Message.class);
        //这里进行一个写数据操作
        save(message);
        resp.setContentType("application/json;charset=utf-8");
        resp.getWriter().write("{\"ok\":1}");
    }
    private void save(Message message){
        System.out.println("向数据库写入数据!");

        //1.先和数据库建立连接
        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);
            //执行sql
            int ret = statement.executeUpdate();
            if (ret == 1){
                System.out.println("插入数据库成功");
            }else {
                System.out.println("插入数据库失败");
            }
        } catch (SQLException e) {
            e.printStackTrace();
        }finally {
            DBUtil.close(connection,statement,null);
        }
    }
    //doGet方法用来从服务器上获取消息
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        resp.setContentType("application/json;charset=utf-8");
        //writeValue就是把messageList对象转换成json格式的字符串,并通过写入响应(resp.getWriter())返回
        List<Message> messageList = load();
        objectMapper.writeValue(resp.getWriter(),messageList);
    }
    private List<Message> load(){
        //把读到的数据放到List<Message>中
        List<Message> messageList = new ArrayList<>();
        System.out.println("从数据库开始读取数据!");
        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");
                messageList.add(message);
            }
        } catch (SQLException e) {
            e.printStackTrace();
        }finally {
            DBUtil.close(connection,statement,resultSet);
        }
        return messageList;
    }

 

 

 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/20129.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

家居行业如何实现智能化?快解析来助力

什么是智能家居&#xff1f;主要是指利用先进的电子通信技术&#xff0c;将居家生活有关的各个子系统有机结合在一起&#xff0c;通过网络化便可以对这些系统进行智能控制与管理。智能家居概念之所以逐渐普及&#xff0c;得益于物联网、大数据、人工智能等新兴技术的进步。智能…

科学计算模型 Numpy 详解

本文主要介绍Numpy&#xff0c;并试图对其进行一个详尽的介绍。 通过阅读本文&#xff0c;你可以&#xff1a; 了解什么是 Numpy掌握如何使 Numpy 操作数组&#xff0c;如创建数组、改变数组的维度、拼接和分隔数组等掌握 Numpy 的常用函数&#xff0c;如数组存取函数、加权平均…

表关联查询

表关联查询 1.表别名 当表的名字很长或者执行一些特殊查询时&#xff0c;为了方便操作或者需要多次使用相同的表时&#xff0c;可以为表指定别名&#xff0c;以替代表原来的名称。 在为表取别名时&#xff0c;要保证不能与数据库中的其他表的名称冲突。 对单表做简单的别名查询…

能否通过手机号查询他人位置及技术实现(省流:不能)

前言 &#x1f340;作者简介&#xff1a;被吉师散养、喜欢前端、学过后端、练过CTF、玩过DOS、不喜欢java的不知名学生。 &#x1f341;个人主页&#xff1a;红中 &#x1fad2;每日emo&#xff1a;纪念我死去的爱情 &#x1f342;灵感来源&#xff1a;艺术源于生活&#xff0c…

SpringBoot SpringBoot 开发实用篇 5 整合第三方技术 5.2 Spring 缓存使用方式

SpringBoot 【黑马程序员SpringBoot2全套视频教程&#xff0c;springboot零基础到项目实战&#xff08;spring boot2完整版&#xff09;】 SpringBoot 开发实用篇 文章目录SpringBootSpringBoot 开发实用篇5 整合第三方技术5.2 Spring 缓存使用方式5.2.1 Spring 缓存使用5.2.…

数字集成电路设计(五、仿真验证与 Testbench 编写)(二)

文章目录4. 信号时间赋值语句4.1 时间延迟的语法说明4.2 时间延迟的描述形式4.3 边沿触发事件4.3.1 事件表达式4.3.2 边沿触发语法格式4.4 电平敏感事件4. 信号时间赋值语句 &#xff01;&#xff01;信号赋值语句是硬件描述语言非常重要的一条语句&#xff0c;是对于任意信号…

Zookeeper:Zookeeper的主从选举机制

ZAB 协议&#xff0c;全称 Zookeeper Atomic Broadcast&#xff08;Zookeeper 原子广播协议&#xff09;&#xff0c;是为分布式协调服务 ZooKeeper 专门设计的一种支持崩溃恢复的一致性协议。基于该协议&#xff0c;ZooKeeper 实现了一种主从模式的系统架构来保持集群中各个副…

业务定制型异地多活架构设计

1个原理 大道至简-异地多活核心原理 异地多活本质上是 CAP 中的AP 大道至深-CAP 粒度 CAP 关注的粒度是数据&#xff0c;而不是系统&#xff0c;需要根据不同业务的数据特点来设计异地多活 延迟 CAP 是忽略网络延迟的 &#xff0c;但工程落地不可能做到零延迟 分区容忍…

【Linux】linux中你不得不爱的命令集(上)

Linux命令集 我们将要介绍的命令并不是linux中所有的命令&#xff0c;是我们常见的和经常要使用的命令。 我们所用的linux版本是centos7&#xff0c;我们的linux搭建是在腾讯云服务器上搭建的&#xff0c;借助Xshell登录服务器&#xff0c;在root下进行命令行的操作。 目录 L…

[附源码]java毕业设计社区生鲜仓库管理系统

项目运行 环境配置&#xff1a; Jdk1.8 Tomcat7.0 Mysql HBuilderX&#xff08;Webstorm也行&#xff09; Eclispe&#xff08;IntelliJ IDEA,Eclispe,MyEclispe,Sts都支持&#xff09;。 项目技术&#xff1a; SSM mybatis Maven Vue 等等组成&#xff0c;B/S模式 M…

异地多活架构的3种模式

业务定制型异地多活 按照业务的优先级进行排序&#xff0c;优先保证核心业务异地多活 基于核心业务的流程和数据&#xff0c;设计定制化的异地多活架构 优点 对基础设施无强要求&#xff0c;例如机房部署、存储系统、时延等&#xff0c;一般部署在远距离的两个城市&#xff…

经济师报考专业选择及难度分析!这三个专业每年报考人数超10万!

经济师 经济师考试报考专业设有10个专业&#xff0c;含工商管理、农业经济、财政税收、金融、保险、运输经济、人力资源管理、旅游经济、建筑与房地产经济、知识产权。那么&#xff0c;哪些专业是经济师报考的热门专业&#xff1f;哪些专业前景较好&#xff1f;哪个又更好考呢…

SAP 物料分类账配置详解Part 2( 基于SAP S/4HANA1909 版本)

1.12 检查物料会计科目的结算 1.13 激活在制品实际成本计算 1.14 定义并分配评估策略 1.15 定义实际成本核算/物料分类帐的访问 1.16 分配成本核算码到物料类型 1.17 将评估范围设置为生产 1.12 检查物料会计科目的结算 1.12.1 概念说明 为物料分类账的结账配置自动…

C++模拟OpenGL库——图片处理及纹理系统(二):图片Alpha值混合操作

目录 Alpha值混合操作 更改一些类接口设置&#xff0c;实现Alpha值设定 Alpha值混合操作 先上图&#xff0c;其实原理和ColorLerp的原理一样&#xff0c;一种线性插值的方法来实现Alpha通道的混合。 Alpha通道就是对RGB三个值的一种表现约束&#xff0c;比如Alpha0.5&#x…

使用keytool生成Tomcat证书

一、HTTPS原理 1、HTTP、HTTPS、SSL、TLS介绍与相互关系 &#xff08;1&#xff09;HTTP&#xff1a;平时浏览网页时候使用的一种协议。HTTP协议传输的数据都是未加密的&#xff08;明文&#xff09;&#xff0c;因此使用HTTP协议传输隐私信息非常不安全。 &#xff08;2&am…

人工智能学习相关笔记

文章目录留出法(hold-out)Artifact (error)理解交叉熵损失函数(CrossEntropy Loss)信息量信息熵相对熵(KL散度)交叉熵交叉熵在单分类问题中的应用回顾知识蒸馏公式对抗学习随机投影(Random Projection)概述基本实现sklearn中的随机投影独立成分分析(ICA)ICA算法ICA 应用sklearn…

tslib库编译与移植

tslib库编译与移植 1.tslib库简介 tslib 是电阻式触摸屏用于校准的一个软件库&#xff0c;是一个开源的程序&#xff0c;能够为触摸屏驱动获得的采样提供诸如滤波、去抖、校准等功能&#xff0c;通常作为触摸屏驱动的适配层&#xff0c;为上层的应用提供了一个统一的接口。 2…

数据结构——顺序表

目录 一.简介 线性表 顺序表 二.结构体与初始化 1.创建 2.初始化 三.功能实现 1.打印 2.销毁 3.扩容 4.尾插 5.尾删 6.头插 7.头删 8.查找元素 9.下标位置的插入与某一数据前的插入 10.下标位置的删除与某一数据的删除 11.头插、头删、尾插、尾删的常态化 一.简…

模块电路选型(1)----电源模块

系列文章目录 1.电源模块 2.主控模块 3.传感器模块 4.通信模块 5.电机驱动模块 6.存储模块 7.人机交互模块 文章目录前言一、DCDC电源模块1、LM2596 DCDC降压模块设计二、LDO电源模块1、1117芯片前言 送给大学毕业后找不到奋斗方向的你&#xff08;每周不定时更新&#x…

Spring Data JPA之Spring boot整合JPA进行CRUD

Spring boot整合JPA进行CRUD前言系列博客本博客的实现demo环境配置1.POM依赖2.application.yml文件完整的项目结构代码实现实体类启动类创建数据访问层使用Spring Data JPA 创建带条件的CRUD编写业务层创建UserController类运行测试插入用户数据删除用户数据修改数据查询数据根…