实现第一个服务器版本的表白墙程序

这篇具有很好参考价值的文章主要介绍了实现第一个服务器版本的表白墙程序。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

表白墙

前言

基于MySQL数据库和servlet实现的前后端交互的服务器版本表白墙。在页面输入表白内容,在本地通过数据库存储历次表白内容,保证网页刷新重进时数据仍存在。以下为打开表白墙效果展示:

实现第一个服务器版本的表白墙程序
我们可以在输入框输入表白对象,表白内容然后提交就能显示到新动态中,提交之后输入框自动清空内容。

完整项目代码可以通过我的gitee获取MessageWall

1. 环境部署

1.1 创建maven项目

我们在idea里面点击new project创建一个maven项目,然后一路next选择好项目位置以及命名即可。
实现第一个服务器版本的表白墙程序
实现第一个服务器版本的表白墙程序

1.2 引入依赖

在创建完maven项目之后我们需要加载依赖,部分同学可能由于网络问题难以加载,可以多试几遍,实在不行可以更换国内的镜像下载此处不作多介绍。以下需要引入的依赖主要有:java.servlet-api、mysql-connector-java,以及后续发送json格式的数据需要的jackson依赖(jackson-databind)

我们通过maven仓库官网https://mvnrepository.com/ 即可获取。

如图:复制链接黏贴到我们项目的pom.xml文件
实现第一个服务器版本的表白墙程序

代码 : 以下是我部署的依赖可以直接复制黏贴

 <dependencies>
<!--        servlet依赖-->
        <!-- https://mvnrepository.com/artifact/javax.servlet/javax.servlet-api -->
        <dependency>
            <groupId>javax.servlet</groupId>
            <artifactId>javax.servlet-api</artifactId>
            <version>3.1.0</version>
            <scope>provided</scope>
        </dependency>
<!--        jackson依赖-->
        <!-- 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>
<!--        数据库依赖-->
        <!-- https://mvnrepository.com/artifact/mysql/mysql-connector-java -->
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <version>5.1.47</version>
        </dependency>
    </dependencies>

1.3 创建目录结构

在我们的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>

1.4 部署程序

我们在插件市场搜索 Smart Tomcat 插件,将Tomcat集成到idea就不用我们手动打包,之后点击即可运行。
实现第一个服务器版本的表白墙程序
然后点击新增运行配置,将Smart Tomcat加入,此处选择Tomcat路径,如果还没有下载Tomcat,可以通过官网下载。博主使用的是 3.1版本的servlet+tomcat 8

实现第一个服务器版本的表白墙程序
实现第一个服务器版本的表白墙程序

然后就可以点击运行:出现以下结果就是部署成功了。之后我们就可以通过127.0.0.1:8080/MessageWall/xx.html(html页面)访问,其中MessageWall是Context path,一般默认是项目名。

实现第一个服务器版本的表白墙程序

2. 前端页面

由于该程序只是作为我们学习使用servlet实现前后端交互的一个开端,我们我们前端页面只包括:输入框 input 、提交按钮 button 、无语义标签 div 用来划分页面。

页面展示:
实现第一个服务器版本的表白墙程序

HTML代码: 除了html本身代码还包含通过 style 标签引入的css代码,通过 script 标签引入的js代码。

通过css实现页面样式以及布局,通过js实现提交按钮的点击效果(点击变灰)以及向服务器发送GET请求并获取数据加载到页面。

注意: 本次我们采用的是通过 form表单构造json格式的get请求发送到服务器 ,需要通过 jquery的ajax 实现:

  1. 导入jquery cdn,在浏览器搜索即可,也可以直接下载我的
<script src="https://cdn.bootcdn.net/ajax/libs/jquery/3.6.4/jquery.min.js"></script>

  1. 通过ajax构造请求
 $.ajax({
        type: 'get',
        url: 'message',
        success: function(body) {
            // 此处拿到的 body 就是一个 js 的对象数组了.
            // 本来服务器返回的是一个 json 格式的字符串, 但是 jquery 的 ajax 能够自动识别
            // 自动帮我们把 json 字符串转成 js 对象数组
            // 接下来遍历这个数组, 把元素取出来, 构造到页面中即可
            let containerDiv = document.querySelector('.qian')
            for (let message of body) {
                // 针对每个元素构造一个 div
                let rowDiv = document.createElement('div');
                rowDiv.className = 'row message';
                rowDiv.innerHTML = message.from + ' 对 ' + message.to + ' 说: ' + message.message;
                containerDiv.appendChild(rowDiv);
            }
        }
    });

完整代码:

<!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: 20px auto;
        }

        h1 {
            text-align: center;
        }

        p {
            text-align: center;
            color: #666;
            margin: 20px 0;
        }

        .row {
            /* 开启弹性布局 */
            display: flex;
            height: 40px;
            /* 水平方向居中 */
            justify-content: center;
            /* 垂直方向居中 */
            align-items: center;
        }

        .row span {
            width: 80px;
        }

        .row input {
            width: 200px;
            height: 30px;
        }

        .row button {
            width: 280px;
            height: 30px;
            color: white;
            background-color: orange;
            /* 去掉边框 */
            border: none;
            border-radius: 5px;
        }

        /* 点击的时候有个反馈 */
        .row button:active {
            background-color: grey;
        }
        .qian{
            width: 300px;
            height: 500px;
            margin: 20px auto;
            background-color: pink;
            text-align: center;

            }
    </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 id="submit">提交</button>
    </div>

    <div class="row">
        <button id="revert">撤销</button>
    </div>

<!--    公示栏-->
    <div class="qian">
        <h2>新动态</h2>
    </div>

</div>

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

<script>
    // 实现提交操作. 点击提交按钮, 就能够把用户输入的内容提交到页面上显示.
    // 点击的时候, 获取到三个输入框中的文本内容
    // 创建一个新的 div.row 把内容构造到这个 div 中即可.
    let containerDiv = document.querySelector('.qian');
    let inputs = document.querySelectorAll('input');
    let button = document.querySelector('#submit');
    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 message';
        rowDiv.innerHTML = from + ' 对 ' + to + ' 说: ' + msg;
        containerDiv.appendChild(rowDiv);
        // 3. 清空之前的输入框内容
        for (let input of inputs) {
            input.value = '';
        }

        // 4. [新增] 给服务器发起 post 请求, 把上述数据提交到服务器这边
        let body = {
            "from": from,
            "to": to,
            "message": msg
        };
        let 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("数据发布成功");
            }
        });
    }
    let revertButton = document.querySelector('#revert');
    revertButton.onclick = function() {
        // 删除最后一条消息.
        // 选中所有的 row, 找出最后一个 row, 然后进行删除
        let rows = document.querySelectorAll('.message');
        if (rows == null || rows.length == 0) {
            return;
        }
        containerDiv.removeChild(rows[rows.length - 1]);
    }


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

3. 后端实现

在后端实现中创建两个类即可,MessageServlet类由于实现前后端交互,DBUtils类用于操作数据库的工具类。

3.1 后端逻辑

  1. 前后端交互的数据约定为 json格式,在后端实现中也是通过导入的jackson库 解析该数据。
  2. 点击提交:浏览器将表白信息发送到服务器,对应着一对请求(Post)和响应
  3. 页面加载:浏览器从服务器哪获取到我们之前输入过的表白信息显示在页面,也对应一组请求(Get)与响应,该响应的body部分 通过json数组存储json格式的每条数据(json对象)。

由此我们在MassageServlet代码中只用实现 doPost()方法向服务器发送数据,doGet()方法从服务器获取数据,save()方法调用DBUtils类向数据库存储信息,load()方法从数据库取所有信息;

3.2 后端代码

MassageServlet.class:

  1. 在该类中 @WebServlet(“/message”) 对应着我们前端页面通过ajax构造请求发送的url路径一致,此处我们写的是相对路径。
  2. 导入jackson库之后我们就可以通过ObjectMapper类的readValue()读取请求中body的数据并规定以Massage.class格式读取,然后赋值给massage;
 Message message = objectMapper.readValue(req.getInputStream(),Message.class);
      
  1. massage.class,该类是为了存储读取到的json格式的键值对数据而创建。
import com.fasterxml.jackson.databind.ObjectMapper;

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;

/**
 * @author zq
 */
class Message{
    public String from;
    public String to;
    public String message;
}

@WebServlet("/message")

public class MessageServlet extends HttpServlet {
    //private List<Message> messageList = new ArrayList<>();
    //向服务器发送数据
    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        ObjectMapper objectMapper = new ObjectMapper();
        //读取body中的内容赋值给massage对象
        Message message = objectMapper.readValue(req.getInputStream(),Message.class);
        //通过简单粗暴的方法保存,list
        //messageList.add(message);
        save(message);
        //设置响应状态码(可以不设置)
        resp.setStatus(200);
    }

    //从服务器获取数据
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        resp.setContentType("application/json;charset=utf8");
        ObjectMapper objectMapper = new ObjectMapper();
        List<Message> messageList = load();
       // objectMapper.writeValue(resp.getWriter(),messageList);
        objectMapper.writeValue(resp.getWriter(),messageList);
    }

    //提供一对方法
    //王数据库存一条消息
    private void save(Message message)  {
        //这是基本的jdbc操作
        //1.建立连接
        Connection connection = null;
        PreparedStatement statement =null;

        try {
            connection = DBUtil.getConnection();
            //2.构造sql语句
            String sql = "insert into message value(?,?,?)";
            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 {
            //4.关闭连接
           DBUtil.close(connection,statement,null);
        }

    }
    //从数据库取所以消息
    private List<Message> load(){
        List<Message> messageList = new ArrayList<>();
        //1.建立连接
        Connection connection = null;
        PreparedStatement statement =null;
        ResultSet resultSet = null;

        try {
            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();
                //根据列名取出sql语句
                message.from = resultSet.getString("from");
                message.to = resultSet.getString("to");
                message.message = resultSet.getString("message");
                messageList.add(message);

            }
        } catch (SQLException e) {
            e.printStackTrace();
        }finally {
            //4.关闭连接
            DBUtil.close(connection,statement,resultSet);
        }
        return messageList;
    }
}

DBUtils.class:文章来源地址https://www.toymoban.com/news/detail-448630.html

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;

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

    static{
        //使用静态代码块,针对dataSource进行初始化操作
        ((MysqlDataSource)dataSource).setUrl("jdbc:mysql://127.0.0.1:3306/javaee?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 preparedStatement, ResultSet resultSet){
       //此处三个try-catch分开写更好
        // 避免前面的出问题后面的执行不了
        if (resultSet !=null){
            try {
                resultSet.close();
            } catch (SQLException e) {
                e.printStackTrace();
            }
        }
        if (preparedStatement != null){
            try {
                preparedStatement.close();
            } catch (SQLException e) {
                e.printStackTrace();
            }
        }
        if (connection != null){
            try {
                connection.close();
            } catch (SQLException e) {
                e.printStackTrace();
            }
        }
    }
}

到了这里,关于实现第一个服务器版本的表白墙程序的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

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

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

相关文章

  • 12-代码实战——服务器版表白墙

    目录 1.版本一:将数据存到内存中 ①约定前后端交互接口 a.添加表白信息: b.查询表白列表: ②在webapp包下创建message-wall.html前端文件 ③在java包下创建AddMessageServlet后端类 ④在java包下创建MessageListServlet后端类 2.版本二:将数据存到数据库中 ①创建数据库, 创建 messages 表 ②

    2024年02月10日
    浏览(53)
  • 用Rust设计一个并发的Web服务:常用Rust库如Tokio、Hyper等,基于TCP/IP协议栈,实现了一个简单的并发Web服务器,并结合具体的代码讲解如何编写并发Web服务器的程序

    作者:禅与计算机程序设计艺术 1994年,互联网泡沫破裂,一批优秀的程序员、工程师纷纷加入到web开发领域。而其中的Rust语言却备受瞩目,它是一种现代系统编程语言,专注于安全和并发。因此,Rust在当下成为最流行的编程语言之一,很多框架也开始使用Rust重构,这使得

    2024年02月06日
    浏览(58)
  • 【Servlet学习四】实现一个内存版本的表白墙~

    目录 一、前端代码 二、后端代码实现 🌈1、全局类定义AppVar 🌈2、实体类定义Message 🌈3、获取所有信息:getMessageServlet实现前后端的交互 🌈4、添加数据:addMessageServlet,实现前后端交互 三、效果演示 目标:         将输入内容放在内存里面存储,用List存储对象,这个

    2024年02月11日
    浏览(41)
  • 在局域网搭建一个带 web 操作页面的 git 版本服务器 - Gitlab

    以下内容为本人的著作,如需要转载,请声明原文链接 微信公众号「ENG八戒」https://mp.weixin.qq.com/s/Br0ETd_aNffEZoTAba03Bw 最近到了新团队,只有几部新电脑,然后啥也没有了。老江说需要一个管理工程代码的 git 版本服务器,还说他以前用过 gitlab,于是我就自告奋勇接下了锅,在

    2024年01月19日
    浏览(50)
  • 一个服务器实现本机服务互联网化

    欢迎来到我的博客,代码的世界里,每一行都是一个故事 在数字世界的网络战场上,中微子代理就像是一支潜伏在黑暗中的数字特工队,通过看似微不足道的信息流进行高效的通信。想象一下,你正在追踪一项机密任务,而中微子代理就是你的数字伪装大师,让你在网络的阴

    2024年03月12日
    浏览(52)
  • 最新开源版本GPT3.5小程序源码 无需服务器搭建

    简介: 最新开源版本GPT3.5小程序源码 无需服务器搭建 搭建前说明:此教程使用阿里云函数搭建,搜阿里云函数,开通,领取100万次调用。 此教程只是函数使用阿里云,数据库什么的不用动,如果你之前有版本上线,直接复制那个版本的数据库账号密码填写到新搭建的阿里云

    2024年02月13日
    浏览(42)
  • 极光Java 版本服务器端实现别名消息推送

    REST API 文档:

    2024年02月15日
    浏览(44)
  • 【Linux】从云服务器购买到第一个Linux程序

    目录 1. 我们为什么要学Linux 2. 云服务器购买 3. 远程连接云服务器 4. 如何创建新用户   5. 第一个Linux程序 总结: 写在最后: 作为一个程序员,你必须学好Linux,至于为什么,这个问题, 在我们日后的学习中,自然会慢慢展现出来,而校招对于Linux也有掌握的要求, 所以我们

    2023年04月15日
    浏览(44)
  • 基于Netty实现一个HTTP服务器

    一、序言 Netty因其易编程,高可靠性,高性能的网络IO,在分布式开发中被广泛用于网络通信,比如RocketMQ,Dubbo底层都能看到Netty的身影,高性能的本质是其Reactor线程模型以及异步的编程处理。Reactor有三种模型,常用的有主从 Reactor多线程模式,具体表现如下: 在日常开发中

    2023年04月25日
    浏览(49)
  • 【Linux环境搭建】从云服务器购买到第一个Linux程序

    目录 1. 我们为什么要学Linux 2. 云服务器购买 3. 远程连接云服务器 4. 如何创建新用户   5. 第一个Linux程序 总结: 写在最后: 作为一个程序员,你必须学好Linux,至于为什么,这个问题, 在我们日后的学习中,自然会慢慢展现出来,而校招对于Linux也有掌握的要求, 所以我们

    2023年04月17日
    浏览(43)

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

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

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

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

二维码1

领取红包

二维码2

领红包