Servlet的实战用法(表白墙前后端)

news2024/11/17 1:59:00

作者:~小明学编程 

文章专栏:JavaEE

格言:热爱编程的,终将被编程所厚爱。
在这里插入图片描述

目录

服务器版本的表白墙

创建项目

约定前后端交互接口

获取全部留言

发表新的留言

服务端代码

创建Message类

创建DBUtil类

创建MessageServlet类

前端代码

效果演示


服务器版本的表白墙

在我们了解了Servlet API的使用之后下面我们就可以来修改前面的表白墙代码了,让其加上一些后端代码实现前后端的交互。

创建项目

首先我们要给表白墙的的代码专门创建一个项目来,创建的过程可以参考上一篇文章,这里我们要说一下就是我们的依赖,因为我们想要把后面表白墙的信息都给存入数据库中所以我们要引入mysql的依赖包,然后我们的传输格式想要采用JSON的格式所以还要引入jackson的依赖具体代码见下面的代码:

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <groupId>org.example</groupId>
    <artifactId>test_1_10_love_wall</artifactId>
    <version>1.0-SNAPSHOT</version>

    <properties>
        <maven.compiler.source>8</maven.compiler.source>
        <maven.compiler.target>8</maven.compiler.target>
    </properties>

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

        <!-- https://mvnrepository.com/artifact/com.fasterxml.jackson.core/jackson-databind -->
        <dependency>
            <groupId>com.fasterxml.jackson.core</groupId>
            <artifactId>jackson-databind</artifactId>
            <version>2.12.6.1</version>
        </dependency>
<!--        引入mysql驱动包-->
        <!-- https://mvnrepository.com/artifact/mysql/mysql-connector-java -->
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <version>5.1.47</version>
        </dependency>


    </dependencies>

</project>

约定前后端交互接口

约定前后端的交互接口是非常的关键的,我们在开发的过程中通常是前端负责前端,后端负责后端,最后前后端代码合在一起,所以二者要约定好前端发送什么样的请求我们后端处理请求然后再将处理好的请求给发送回去,最后前端再解析后端返回的数据。

获取全部留言

这里我们采用get的请求方式来获取全部的留言,然后约定我们的数据格式。

请求:

GET /message

响应:Json格式

{
        {
        from: "黑猫",
        to: "白猫",
        message: "喵"
        },
        {
        from: "黑狗",
        to: "白狗",
        message: "汪"
        },
        ......
}

我们期望浏览器给服务器发送一个 GET /message 这样的请求, 就能返回当前一共有哪些留言记
录. 结果以 json 的格式返回过来。

发表新的留言

请求:body为json格式

POST /message
        {
        from: "黑猫",
        to: "白猫",
        message: "喵"
}

响应:json格式

{
    ok: true
}

服务端代码

创建Message类

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

创建DBUtil类

public class DBUtil {
    private static final String URL = "jdbc:mysql://127.0.0.1:3306/test?characterEncoding=utf8&useSSL=false";
    private static final String USERNAME = "root";
    private static final String PASSWORD = "0217";

    private volatile static DataSource dataSource = null;//创建数据库源

    private 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();
            }
        }
    }

}

这里我们要连接数据库,我们采用JDBC的方式与数据库建立连接。

创建MessageServlet类

@WebServlet("/message")
public class MessageServlet extends HttpServlet {
    private ObjectMapper objectMapper = new ObjectMapper();
//    private List<Message> messages = new ArrayList<>();
    //改成数据库版本

    //发表新留言
    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
  
    }
    //获取全部留言
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
  
    }
    private void save(Message message) {
        //存入数据
 

    }
    private List<Message> load() {
        //获取数据


    }

}

doPost()

    //发表新留言
    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        //处理提交信息
        Message message = objectMapper.readValue(req.getInputStream(),Message.class);
        //将处理提交信息存在我们的内存中去
//        messages.add(message);
        //告诉页面返回的数据是 json 格式
        save(message);
        resp.setContentType("application/json; charset=utf8");
        resp.getWriter().write("{\"ok\":true}");
    }

doPost()方法主要是处理我们新发表的留言,当我们的前端代码发来post请求之后我们会从请求中读取其body中的数据然后将其放在我们的Message类中,接着将数据写入数据库中,然后设置我们的返回的数据格式将其设置为json格式,最后返回响应ok:true。

doGet()

    //获取全部留言
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        //把Java对象转换成JSON格式的字符串
        resp.setContentType("application/json; charset=utf8");
        List<Message> messages = load();
        String jsonString = objectMapper.writeValueAsString(messages);
        System.out.println("jsonString"+jsonString);
        resp.getWriter().write(jsonString);
    }

doGet()样式的请求是获取我们当前全部留言,首先设置我们返回的数据格式,然后用一个List集合类来获取我们数据库中的相关数据,然后通过writeValueAsString的方法将一个一个的对象转换成json格式的字符串,最后返回我们所有的数据。

这里我在做项目的时候遇到了一个问题,就是少写了setContentType然后前端将其解析成字符串了,导致前后端处理数据的格式不一样。

 最后出现这种情况,解析的都是空的。

全部代码:

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;

/**
 * Created with IntelliJ IDEA.
 * Description:
 * User: 86184
 * Date: 2023-01-10
 * Time: 15:21
 */
class Message{
    public String from;
    public String to;
    public String message;
}
@WebServlet("/message")
public class MessageServlet extends HttpServlet {
    private ObjectMapper objectMapper = new ObjectMapper();
//    private List<Message> messages = new ArrayList<>();
    //改成数据库版本

    //发表新留言
    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        //处理提交信息
        Message message = objectMapper.readValue(req.getInputStream(),Message.class);
        //将处理提交信息存在我们的内存中去
//        messages.add(message);
        //告诉页面返回的数据是 json 格式
        save(message);
        resp.setContentType("application/json; charset=utf8");
        resp.getWriter().write("{\"ok\":true}");
    }
    //获取全部留言
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        //把Java对象转换成JSON格式的字符串
        resp.setContentType("application/json; charset=utf8");
        List<Message> messages = load();
        String jsonString = objectMapper.writeValueAsString(messages);
        System.out.println("jsonString"+jsonString);
        resp.getWriter().write(jsonString);
    }
    private void save(Message message) {
        //存入数据
        Connection connection = null;
        PreparedStatement statement = null;
        //获得数据库连接
        try {
            connection = DBUtil.getConnection();
            //构造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);
            //执行sql
            statement.executeUpdate();
        } catch (SQLException e) {
            e.printStackTrace();
        } finally {
            DBUtil.close(connection,statement,null);
        }

    }
    private List<Message> load() {
        //获取数据
        List<Message> messages = new ArrayList<>();
        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");
                messages.add(message);
            }
        } catch (SQLException e) {
            e.printStackTrace();
        } finally {
            DBUtil.close(connection,statement,resultSet);
        }
        return messages;

    }

}

前端代码

关于前端代码这里就不详细介绍了主要就是通过ajax发送请求,然后通过解析数据将其加载到页面上。

<!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 src="https://cdn.staticfile.org/jquery/1.10.2/jquery.min.js"></script>
        <script>
            //点击按钮提交的时候,ajax要构造数据发送给服务器
            //页面加载的时候,从服务器获取消息列表,并且在页面上直接显示。
            function getMessages() {
                $.ajax({
                    type: 'get',
                    url:'message',
                    contentType: 'json',
                    success: function(body) {
                        let container=document.querySelector('.container');
                        console.log(body);
                        for(let message of body) {
                            let row=document.createElement('div');
                            row.innerHTML=message.from+'对'+message.to+'说:'+message.message;
                            row.className='row';
                            //3.把这个新的元素添加到DOM树上
                            container.appendChild(row);

                        }
                    }
                });
            }
            getMessages();
            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='';
                }
                5.//把当前获取到的输入框的内容,构造成一个HTTP POST请求,然后通过ajax发给服务器
                let body = {
                    "from": from,
                    "to": to,
                    "message": message
                };
                $.ajax({
                    type: "post",
                    url: "message",
                    contentType: "application/json;charset=utf8",
                    data: JSON.stringify(body),
                    success: function(body) {
                        alert("消息提交成功!");
                    },
                    error: function() {
                        alert("消息提交失败!");
                    }
                });
            }
        </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>

效果演示

 

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

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

相关文章

双指针合集

87合并两个有序的数组 import java.util.*; public class Solution {public void merge(int A[], int m, int B[], int n) { int i m-1;int j n-1;for(int k nm-1;k>0;k--){if(j<0) A[k] A[i--];else if(i<0) A[k] B[j--];else if(A[i]>B[j]) A[k] A[i--]…

六道数据结构算法题详解

目录 1.力扣350题. 两个数组的交集 II 2.力扣121题. 买卖股票的最佳时机 3.力扣566题. 重塑矩阵 4.力扣118题. 杨辉三角 5.牛客BM13 判断一个链表是否为回文结构 6.牛客BM14 链表的奇偶重排 1.力扣350题. 两个数组的交集 II 题目&#xff1a;给你两个整数数组 nums1 和 n…

2022年终总结---权衡好工作和生活

2022总结 【校园】2022年6月研究生顺利毕业&#xff0c;让下文的一切才变的有机会。感谢师弟送学长毕业&#xff0c;感谢在最后时刻各位舍友帮忙送材料&#xff0c;怀念最后一个月一起打球的时光。 【工作】2022年6月入职阿里&#xff0c;成为打工人。在这个大的平台&#xf…

Goland项目使用gomod配置

Goland 项目创建 goland2020.3 及以上 IDE&#xff0c;默认创建的 go 项目 就是使用 gomod 管理&#xff01; goland2020.3 及以下的 IDE&#xff0c;创建项目时需要选择 带小括号 vgo 的才是 gomod 管理模式 下图为使用 goland2021.3 版本创建使用 gomod 管理的 go 项目&…

14种可用于时间序列预测的损失函数

在处理时间序列预测问任务时&#xff0c;损失函数的选择非常重要&#xff0c;因为它会驱动算法的学习过程。以往的工作提出了不同的损失函数&#xff0c;以解决数据存在偏差、需要长期预测、存在多重共线性特征等问题。本文工作总结了常用的的 14 个损失函数并对它们的优缺点进…

线段树(Segment tree)

线段树 线段树是一种二叉树形数据结构,用以储存区间或线段,并且允许快速查询结构内包含某一点的所有区间。 视频讲解 线段树主要实现两个方法:「求区间和」&「修改区间」,且时间复杂度均为 O(logn)。 nums = [1, 2, 3, 4, 5] 对应的线段树如下所示: 使用数组表示线段…

【阶段三】Python机器学习33篇:机器学习项目实战:医学病症关联规则分析

本篇的思维导图: 医学病症关联规则分析 项目背景 本项目演示一个医学领域的有趣应用——病症关联规则分析,同时利用apyori库和mlxtend库来编写代码,从数据分析的角度去研究病症背后的关联规则。假设有一种医学理论认为,五脏和一些病症之间存在关联关系,见下表。例…

4.线性神经网络

4.线性神经网络 目录 线性回归 线性回归的基本元素 线性模型损失函数解析解随机梯度下降 矢量化加速正态分布与平方损失 优化方法 梯度下降选择学习率小批量随机梯度下降选择批量大小总结 线性回归的从零开始实现 生成数据集读取数据集初始化模型参数定义模型定义损失函数定义…

磨金石教育摄影技能干货分享|优秀摄影作品欣赏——世界掠影

这世上很多地方都在发生着有趣的事&#xff0c;很多地方不同的人与物&#xff0c;都在不同的时间和环境下展现着不同的状态。让我们跟随摄影师的镜头去欣赏这些精彩的画面吧。1 悬而未定想象一下这张照片是什么角度拍的&#xff1f;是不是看上去很像俯拍&#xff1f;无论怎么看…

【Python】groupby操作后不把列作为索引单独提出

这是一个困了我几天的问题。 一开始的搜索方向错了&#xff0c;按照groupby的key column搜索&#xff0c;没有搜到。 最近悟出的一个技巧是&#xff0c;没有头绪时看看数据类型和数据内容。如果思路是没问题的情况下。 问题描述 date_date.groupby([XXXX]) poi_date.groupby(…

可视化工具,Java 应用性能分析、调优

JVisualVM 简介 VisualVM 是Netbeans的profile子项目&#xff0c;已在JDK6.0 update 7 中自带&#xff0c;能够监控线程&#xff0c;内存情况&#xff0c;查看方法的CPU时间和内存中的对 象&#xff0c;已被GC的对象&#xff0c;反向查看分配的堆栈(如100个String对象分别由哪…

动态规划 —— 最长上升子序列全解

题目链接&#xff1a;300. 最长递增子序列 - 力扣&#xff08;LeetCode&#xff09; 朴素做法 设元素数组为arr&#xff0c;定义一维数组dp&#xff0c;dp[i]表示以i位置结尾的子序列中&#xff0c;最长的上升子序列的长度 这些子序列可以被划分成哪些子集合呢&#xff1f; …

ArcGIS10.8保姆式安装教程,超详细;附安装包

安装前请关闭杀毒软件&#xff0c;系统防火墙&#xff0c;断开网络连接 参考链接&#xff1a;请点击 下载链接&#xff1a; 通过百度网盘分享的文件&#xff1a;ArcGIS10.8zip 链接:https://pan.baidu.com/s/1023fbyQpt6r6U6wtgBuReg 提取码:820w 复制这段内容打开「百度网盘A…

设计模式——解释器模式

解释器模式一、基本思想二、应用场景三、结构图四、代码五、优缺点优点缺点一、基本思想 给分析对象定义一个语言&#xff0c;并定义该语言的文法表示&#xff0c;再设计一个解析器来解释语言中的句子。 二、应用场景 当对象间存在一对多关系&#xff0c;一个对象的状态发生…

ESP32蓝牙+EC11旋转编码器实现对电脑音量控制

ESP32蓝牙EC11旋转编码器实现对电脑音量控制✨本项目基于Arduino开发框架下功能实现。 &#x1f6e0;蓝牙设备添加和连接 ⚡需要有带蓝牙硬件支持的电脑才能实现连接并控制&#xff0c;当然手机也可以连接但是不能实现对手机音量控制&#xff0c; &#x1f33f;以Win10系统电脑…

java 语法基础看这一篇文章就够了

第一章 关键字 关键字的概念1被Java语言赋予了特殊含义&#xff0c;用作专门用途的字符串(单词)关键字特点1关键字中所有字母都是小写常见关键字 classinterfaceenumbyteshortintfloatlongdoublecharbooleanvoidtruefalsenullifelseswitchcasedefaultwhiledoforbreakcontinuer…

数字信号处理音频FIR去噪滤波器(基于MATLAB GUI的开发)

1、内容简介利用MATLAB GUI设计平台&#xff0c;用窗函数法设计FIR数字滤波器&#xff0c;对所给出的含有噪声的声音信号进行数字滤波处理&#xff0c;得到降噪的声音信号&#xff0c;进行时域频域分析&#xff0c;同时分析不同窗函数的效果。将文件解压至一个目录下&#xff0…

第6章 ESP32-Kconfig配置

ESP32-Kconfig配置 1. 新建Kconfig.projbuild文件 2. 写入配置项 新建menu menu "点灯配置"endmenu运行 idf.py menuconfig&#xff0c;结果如下 powershel vscode 可以看到&#xff0c;power shell中文支持上有乱码&#xff0c;所以接下来选择英文 2. 配置menu…

开发实践:一份复杂业务系统的 RESTFul 接口规范

1. 从需求入手 对象&#xff1a;增删改查 对象列表&#xff1a;获取 对象的复杂处理&#xff1a;挖掘、整理、汇总 2. 资源分类 对象型&#xff1a;**/project/1 列表型&#xff1a;**/projects 算法型&#xff1a;**/project/search?input** 3. 设计 URI 3.1. URI 命名…

游戏盾如何防护

什么是游戏盾呢游戏盾是DDoS高防IP产品系列中针对游戏行业的安全解决方案。 游戏盾专为游戏行业定制&#xff0c;针对性解决游戏行业中复杂的DDoS攻击、游戏CC攻击等问题。目前以对抗的形式存在的高防产品形态&#xff0c;也就是防御带宽要大于攻击者的流量。如果你是做运营商商…