Servlet实现一个简单的表白墙网站

在这里插入图片描述

文章目录

  • 前言
  • 效果展示
  • 事前准备
  • HTML、CSS、JavaScript分别负责哪些
  • HTML和CSS构架出页面的基本结构和样式
  • JavaScript 实现行为和交互
  • 实现服务器端的业务
  • 代码整理
    • pom.xml
    • web.xml
    • messageWall.html
    • MessageServlet.java

前言

前面我们学习了 Java 中知名的 HTTP 服务器 tomcat 的安装和使用,还学习了 servlet 相关 API 的学习,今天,这篇文章我们将运用前面学习的 HTTP 知识、tomcat和servlet来实现一个简单的表白墙网站。

效果展示

我先为大家展示一下这个表白墙网站完成之后的最终效果。

首先当我们访问表白墙网站的 HTML 页面的时候,得到的是这个结果。

在这里插入图片描述
当我们输入信息并且提交的时候,会将输入的信息进行处理,然后显示在这个页面的下面。

在这里插入图片描述

在这里插入图片描述

然后我们就可以根据上面的效果来逐步实现代码。

事前准备

在这里我给大家说明一下:要想实现网站,不仅需要后端的知识,还需要一些像什么 HTML、CSS、JavaScript这样的前端知识,而很多人可能还没接触过前端,大家不用慌,我也是刚接触前端,本篇文章我将为大家简单的介绍一下关于前端的时候,让大家大概知道我前段的每一段代码都是干啥的就行了。并且,我也是一个前端小白,如果我的分享有错误的话,欢迎大家在评论区或者私信我指出来,我在这里谢谢大家了。

首先我们需要创建出一个 Maven 项目,然后根据 tomcat 的要求创建出符合要求的目录结构,以及配置一些文件中的内容。

在这里插入图片描述

创建出符合 tomcat 标准的目录结构。

在这里插入图片描述
在 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>

创建出一个 MessageServlet.java 文件用来写我们的后端主要的代码。

HTML、CSS、JavaScript分别负责哪些

HTML、CSS 和 JavaScript 是构建网页的三种主要技术,它们分别负责网页的结构、样式和行为。

HTML (HyperText Markup Language):HTML 是网页的基础,它负责创建和组织网页的内容。HTML 是一种标记语言,它使用各种标签来定义网页中的不同元素,例如标题、段落、链接、图片等。

CSS (Cascading Style Sheets):CSS 负责网页的样式和布局。它可以改变文本的颜色、字体和大小,也可以调整元素的位置、大小和边距等。

JavaScript:JavaScript 负责网页的行为和交互。它可以动态地更改网页的内容、响应用户的点击和输入,甚至加载新的内容。

简单的讲,HTML的作用就是决定你这个网页有哪些基本的结构,就是一个人有一个嘴巴、两个眼睛、一个鼻子;CSS则是决定你某一结构的具体样式和布局,就是一个人是双眼皮、高鼻梁、小嘴巴;而JavaScript则决定你网页的行为和交互,你怎么吃饭的、怎么呼吸的。

HTML和CSS构架出页面的基本结构和样式

当做好前面的准备之后,我们就需要实现表白墙网站的第一步:显示出基本页面。这个显示出页面主要用到了 HTML和CSS的知识。我们的这个 html 文件需要放在 webapp 目录下。

在这里插入图片描述

<!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;
        }
    </style>

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

</body>
</html>

在这里插入图片描述
在这里插入图片描述
CSS中的通配符选择器(*),它选中了页面上的所有元素,然后将所有元素的margin(外边距)、padding(内边距)设置为0,并将box-sizing属性设置为border-box。

这段代码的目的主要是重置网页上所有元素的默认样式。在很多情况下,浏览器会对HTML元素应用默认样式,这些默认样式可能会影响到网页的布局和元素的尺寸。通过将margin和padding设置为0,可以消除元素之间的间距(margin)和内部填充(padding),而将box-sizing设置为border-box可以使元素的宽度和高度包括其边框和内边距。

在这里插入图片描述
它定义了一个名为".container"的类。这个类设置了一个元素的宽度为600像素,并将外边距(margin)设置为20像素,且上下外边距为自动(auto),使得这个元素在页面上居中。

在这里插入图片描述

用于设置HTML文档中的h1和p元素的样式。也就是h1标签和p标签。

  • h1元素内的文本应该居中显示(text-align: center;)。
  • p元素内的文本也应该居中显示,颜色为#666(一个深灰色),并且上下边距为20px。

在这里插入图片描述
用于设置一个名为".row"的类的样式。这段代码使用Flexbox模型来定义行内元素的布局和对齐方式。

  • display: flex;:这会使得元素变为弹性容器,其子元素会按Flexbox模型布局。
  • height: 40px;:这会设置元素的高度为40像素。
  • justify-content: center;:这会使得行内元素在主轴(水平方向)上居中对齐。
  • align-items: center;:这会使得行内元素在交叉轴(垂直方向)上居中对齐。

在这里插入图片描述

所有属于.row类的元素的span子元素,其宽度将被设置为80px。

在这里插入图片描述
所有属于.row类的元素的input子元素,其宽度将被设置为200px,高度将被设置为30px。这个就是我们输入框的相关属性。

在这里插入图片描述

在这里插入图片描述
所有属于.row类的元素的button子元素,其宽度将被设置为280px,高度将被设置为30px,文本颜色将被设置为白色,背景颜色将被设置为橙色,边框将被移除,并且边框半径(用于创建圆角)将被设置为5px。这个就是点击按钮的相关属性。

在这里插入图片描述

JavaScript 实现行为和交互

上面主要用到了我们的 HTML 和 CSS 相关的知识,基本构建出了页面的基本结构和样式,而接下来,我们将使用 JavaScript 来完成提交信息这个动作。

首先需要构建出container类中的各个输入框的行为。

<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">
            xxx 对 xx 说 xxxx
        </div> -->
    </div>
  • <div class=“container”>:开始一个容器div,用于包装整个页面的内容。创建出container这个类。
  • <h1>表白墙:创建一个主标题,显示“表白墙”字样。
  • <p>输入内容后点击提交, 信息会显示到下方表格中:创建一个段落,用于向用户说明他们可以输入表白信息,然后点击提交按钮,信息会显示在下方的表格中。
  • <div class=“row”>:开始一个行div,用于包装每一条表白信息。
  • <span>谁: :创建一个标签span,显示“谁:”字样,用于提示用户输入表白者的名字。
  • <input type=“text”>:创建一个文本输入框,用户可以在这里输入他们的名字。test表示输入的是文本。
  • <div class=“row”>:开始最后一个行div。
  • <button id=“submit”>提交:创建一个按钮,id为“submit”,用于提交表单。按钮上显示“提交”字样。

以上的JavaScript完成了输入框和提交按钮的行为,而JavaScript还需要完成点击提交按钮之后将数据经过处理然后显示在页面上。

<script>
    let containerDiv = document.querySelector('.container');]
    let inputs = document.querySelector('.input');
    let button = document.querySelector('#submit');
    button.onclick = function() {
        //获取到三个输入框的内容
        let from = inputs[0];
        let to = inputs[1];
        let message = input[2];
        //判断是否未输入
        if (from == '' || to == '' || message == '') {
            return;
        }
        //创建出一个新的元素
        let rowDiv = document.createElement('div');
        //定义出rowDiv的类名
        rowDiv.className = 'row message';
        //为rowDiv中插入元素
        rowDiv.innerHtml = from + ' 对 ' + to + ' 说: ' + msg;
        //将这个新创建的元素添加到containerDiv类的末尾
        containerDiv.appendChild(rowDiv);
        //将输入框中的内容置为空
        for (let input of inputs) {
            input.value = '';
        }
        //构造出一个对象用来存储刚才输入框输入的内容,并且这个内容是以json的格式存在的
        let requestBody = {
            "from": from,
            "to": to,
            "message": message
        }
        //通过我们前面引入的Jackson依赖,使用JSON中的stringify方法将对象转换为json
        let jsonString = JSON.stringify(requestBody);
        //$是我们前面引入的jQuery依赖中的全局变量,通过这个$可以调用jQuery中的很多方法
        //通过这个ajax方法构造请求,并且发送给服务器
        $.ajax({
            type: 'post',
            url: 'message',
            contentType: 'application/json; charset=utf8';
            data: jsonString,
            success: function(responseBody) {
                console.log(responseBody);
            }
        });
    }
</script>

Ajax属于第三方库,所以我们要想使用的话,就需要引入相关依赖。引入jQuery库。https://cdn.bootcdn.net/ajax/libs/jquery/3.7.1/jquery.min.js

在这里插入图片描述

实现服务器端的业务

当前端构造出 post 请求发送给服务器,服务器接收到这个请求之后就需要根据这个发送来的请求做出业务处理。因为我们使用的是 Servlet 实现的,所以就需要先引入 Servlet 依赖。

在这里插入图片描述
在这里插入图片描述

因为前端构造请求的数据格式是 json 的数据格式,所以要想在 Java 中使用 json,也就需要引入 json 库,或者包装了 json 库的其他库。

引入Jackson依赖。
在这里插入图片描述
在这里插入图片描述

当引入 Servlet 和 Jackson 依赖之后,我们服务端就可以通过 Servlet 的相关 API 做出相应的业务处理了。

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;

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

    @Override
    public String toString() {
        return "Message{" +
                "from='" + from + '\'' +
                ", to='" + to + '\'' +
                ", message='" + message + '\'' +
                '}';
    }
}
@WebServlet("/message")
public class MessageServlet extends HttpServlet {
    private ObjectMapper objectMapper = new ObjectMapper();
    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        //设置相应的状态码
        resp.setStatus(200);
        //通过ObjectMapper中的readValue方法将json数据转换为Java对象
        Message message = objectMapper.readValue(req.getInputStream(), Message.class);
        //将客户端输入的信息进行存储
        save(message);
        System.out.println(message);
        resp.getWriter().write("ok");
    }
}

当客户端进行提交请求之后,前端会将输入的信息传给服务器,那么当服务器接收到这个请求之后,应该将输入存储在哪个地方呢?如果只是拿一个简单的 List 容器存储数据话,那么这个数据就是存储在内存中的,当服务器重启之后,之前存储的数据就会消失,那么该如何存储才能保证数据的持久性呢?这里想到的肯定就是数据库了,数据库天然支持数据存储的持久性,所以我们这里选择使用 MySQL 数据库来实现数据的存储。

-- 创建数据库
create database if not exists message_wall;

-- 选中数据库
use message_wall;

-- 为了防止这个表存在对我们的数据库造成影响,我们先删除数据库
drop table if exists message;

-- 创建表
create table message(`from` varchar(1024), `to` varchar(1024), message varchar(1024));

在这里插入图片描述
当创建完成数据库和表之后,我们继续要引入 MySQL 依赖,然后实现 JDBC 编程了。

这里因为我的 MySQL 版本是 MySQL8,所以依赖选择的也是 MySQL8 版本,大家需要根据自己的 MySQL 版本来导入对应的依赖。
在这里插入图片描述
在这里插入图片描述

import com.fasterxml.jackson.databind.ObjectMapper;
import com.mysql.cj.jdbc.MysqlDataSource;

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 javax.sql.DataSource;
import java.io.IOException;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.SQLException;

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

    @Override
    public String toString() {
        return "Message{" +
                "from='" + from + '\'' +
                ", to='" + to + '\'' +
                ", message='" + message + '\'' +
                '}';
    }
}
@WebServlet("/message")
public class MessageServlet extends HttpServlet {
    private ObjectMapper objectMapper = new ObjectMapper();
    private DataSource dataSource = new MysqlDataSource();

    @Override
    public void init() throws ServletException {
        ((MysqlDataSource)dataSource).setURL("jdbc:mysql://127.0.0.1:3306/message_wall?characterEncoding=utf8&useSSl=false");
        ((MysqlDataSource)dataSource).setUser("root");
        ((MysqlDataSource)dataSource).setPassword("*******"); //这里是我们的MySQL密码
    }

    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        //设置相应的状态码
        resp.setStatus(200);
        //通过ObjectMapper中的readValue方法将json数据转换为Java对象
        Message message = objectMapper.readValue(req.getInputStream(), Message.class);
        //将客户端输入的信息进行存储
        try {
            save(message);
        } catch (SQLException e) {
            throw new RuntimeException(e);
        }
        System.out.println(message);
        resp.getWriter().write("ok");
    }

    private void save(Message message) throws SQLException {
        Connection connection = dataSource.getConnection();
        String sql = "insert into message values(?, ?, ?)";
        PreparedStatement statement = connection.prepareStatement(sql);
        statement.setString(1, message.from);
        statement.setString(2, message.to);
        statement.setString(3, message.message);
        statement.executeUpdate();
        statement.close();
        connection.close();
    }
}

当实现完成将客户端输入的数据存储进MySQL数据库之后,当我们进入这个网站的时候,还需要将数据库已经存在的信息给读取到页面上,所以,当我们访问这个网站的时候,浏览器会向服务器发送一个 Ajax 请求,当服务器接收到这个 Ajax 请求的时候就会将数据库中的数据给返回给客户端。

$.ajax({
            type: 'get',
            url: 'message',
            success: function(body) {
                let containerDiv = document.querySelector('.container');
                for (let i = 0; i < body.length; i++) {
                    let message = body[i];
                    let div = document.createElement('div');
                    div.className = 'row';
                    div.innerHTML = message.from + "对" + message.to + "说" + message.message;
                    containerDiv.appendChild(div);
                }

            }
        });

我们这个标签放在 <script> 标签下,当访问这个 html 文件的时候,就会自动向服务器发送一个请求。

而当我们的服务器接收到这个请求的时候,便会将数据库中存在的数据返回给客户端。

protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        resp.setStatus(200);
        resp.setContentType("application/json; charset=utf8");
        List<Message> messageList = null;
        try {
            messageList = load();
        } catch (SQLException e) {
            throw new RuntimeException(e);
        }
        String jsonString = objectMapper.writeValueAsString(messageList);
        resp.getWriter().write(jsonString);
    }

private List<Message> load() throws SQLException {
        Connection connection = dataSource.getConnection();
        String sql = "select * from message";
        PreparedStatement statement = connection.prepareStatement(sql);
        ResultSet resultSet = statement.executeQuery();
        List<Message> messageList = new ArrayList<>();
        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);
        }

        statement.close();
        connection.close();
        return messageList;
    }

代码整理

pom.xml

<?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>message_wall1</artifactId>
    <version>1.0-SNAPSHOT</version>

    <properties>
        <maven.compiler.source>8</maven.compiler.source>
        <maven.compiler.target>8</maven.compiler.target>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
    </properties>

    <dependencies>
        <!-- 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/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/mysql/mysql-connector-java -->
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <version>8.0.28</version>
        </dependency>
    </dependencies>
</project>

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>

messageWall.html

<!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;
        }
    </style>

    <script src="https://cdn.bootcdn.net/ajax/libs/jquery/3.7.1/jquery.min.js"></script>
</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">
        xxx 对 xx 说 xxxx
    </div> -->
</div>

<script>
        // 实现提交操作. 点击提交按钮, 就能够把用户输入的内容提交到页面上显示.
        // 点击的时候, 获取到三个输入框中的文本内容
        // 创建一个新的 div.row 把内容构造到这个 div 中即可.
        let containerDiv = document.querySelector('.container');
        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. 把用户填写的内容, 发送给服务器. 让服务器来保存.
            //    $ 是 jquery 提供的全局变量. ajax 就是 $ 的一个方法.
            //    ajax 的参数是一个 js 对象, 可以有很多属性
            let requestBody = {
                "from": from,   // from 变量里的值, 就是第一个输入框的内容, "张三"
                "to": to,       // to 变量的值, 就是第二个输入框的内容, "李四"
                "message": msg  // msg 变量的值, 就是第三个输入框的内容, "我喜欢你很久了"
            };
            // 上述 body 是一个 js 对象, 还需要转成 json 字符串.
            let jsonString = JSON.stringify(requestBody);
            $.ajax({
                type: 'post',
                url: 'message',
                contentType: 'application/json; charset=utf8',
                data: jsonString,
                success: function(responseBody) {
                    // 这个回调就是收到响应之后要执行的代码了.
                    // 前端使用 console.log 打印日志到控制台. (chrome 开发者工具的控制台)
                    console.log("responseBody: " + responseBody);
                }
            });
        }
        $.ajax({
            type: 'get',
            url: 'message',
            success: function(body) {
                let containerDiv = document.querySelector('.container');
                for (let i = 0; i < body.length; i++) {
                    let message = body[i];
                    let div = document.createElement('div');
                    div.className = 'row';
                    div.innerHTML = message.from + "对" + message.to + "说" + message.message;
                    containerDiv.appendChild(div);
                }

            }
        });


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

MessageServlet.java

import com.fasterxml.jackson.databind.ObjectMapper;
import com.mysql.cj.jdbc.MysqlDataSource;
import sun.dc.pr.PRError;

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 javax.sql.DataSource;
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;

    @Override
    public String toString() {
        return "Message{" +
                "from='" + from + '\'' +
                ", to='" + to + '\'' +
                ", message='" + message + '\'' +
                '}';
    }
}
@WebServlet("/message")
public class MessageServlet extends HttpServlet {
    private ObjectMapper objectMapper = new ObjectMapper();
    private DataSource dataSource = new MysqlDataSource();

    @Override
    public void init() throws ServletException {
        ((MysqlDataSource)dataSource).setURL("jdbc:mysql://127.0.0.1:3306/message_wall?characterEncoding=utf8&useSSl=false");
        ((MysqlDataSource)dataSource).setUser("root");
        ((MysqlDataSource)dataSource).setPassword("lmh041105666");
    }

    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        resp.setStatus(200);
        resp.setContentType("application/json; charset=utf8");
        List<Message> messageList = null;
        try {
            messageList = load();
        } catch (SQLException e) {
            throw new RuntimeException(e);
        }
        String jsonString = objectMapper.writeValueAsString(messageList);
        resp.getWriter().write(jsonString);
    }

    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        //设置相应的状态码
        resp.setStatus(200);
        //通过ObjectMapper中的readValue方法将json数据转换为Java对象
        Message message = objectMapper.readValue(req.getInputStream(), Message.class);
        //将客户端输入的信息进行存储
        try {
            save(message);
        } catch (SQLException e) {
            throw new RuntimeException(e);
        }
        System.out.println(message);
        resp.getWriter().write("ok");
    }

    private List<Message> load() throws SQLException {
        Connection connection = dataSource.getConnection();
        String sql = "select * from message";
        PreparedStatement statement = connection.prepareStatement(sql);
        ResultSet resultSet = statement.executeQuery();
        List<Message> messageList = new ArrayList<>();
        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);
        }

        statement.close();
        connection.close();
        return messageList;
    }

    private void save(Message message) throws SQLException {
        Connection connection = dataSource.getConnection();
        String sql = "insert into message values(?, ?, ?)";
        PreparedStatement statement = connection.prepareStatement(sql);
        statement.setString(1, message.from);
        statement.setString(2, message.to);
        statement.setString(3, message.message);
        statement.executeUpdate();
        statement.close();
        connection.close();
    }
}

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

电脑盘符错乱,C盘变成D盘怎么办?

在一些特殊情况下&#xff0c;磁盘盘符会出现错乱&#xff0c;C盘可能会变成D盘。那么&#xff0c;这该怎么办呢&#xff1f;下面我们就来了解一下。 通过磁盘管理更改盘符 磁盘管理是Windows自带的工具&#xff0c;它位于“计算机管理”的控制台中。管理硬盘及其所包含的卷或…

Word隐藏批注知识分享,快速提升工作效率!

“请问大家&#xff0c;word里的批注应该怎么隐藏呢&#xff1f;有没有什么简单的方法可以将批注隐藏的呀&#xff1f;感谢感谢&#xff01;” Word中的批注功能在文档编辑中起着重要的作用&#xff0c;但有时为了保护文档的隐私和保密性&#xff0c;我们需要隐藏批注。 Word隐…

uboot移植-野火imx6ull

uboot移植及LCD和网络驱动设置 环境&#xff1a; Ubuntu 20.04 野火imx6ull pro开发板 tftp服务的搭建 IMX6ULL开发板参考的是NXP官方的I.MX6ULL EVK开发板做的硬件。 Linux的移植要复杂的多&#xff0c;在移植Linux之前我们需要先移植一个 bootloader 代码&#xff0c;这…

寄存器、缓存、内存之间的关系和区别

https://blog.csdn.net/m0_46761060/article/details/124689209 目录 关系1、寄存器2、缓存&#xff08;Cache&#xff09; 2.1、寄存器和缓存的区别2.2、一级缓存和二级缓存3、内存 3.1、只读存储器 ROM&#xff08;Read Only Memory&#xff09;3.2、随机存储器 RAM&#xf…

什么是凸函数

假设函数是定义在某个向量空间的凸子集上的实值函数&#xff0c;并且&#xff0c;如果对于中的任何两个向量和&#xff0c;都满足&#xff1a; 则称为上的凸函数

ESP32 Arduino实战Web篇-使用 WebSocket 创建 ESP32 Web 服务器

本文将详细介绍如何使用 WebSocket 创建 ESP32 Web 服务器,解释WebSocket原理与搭建步骤,并附超详细的代码解释 假设我们需要创建一个使用 ESP32 通过 WiFi 控制灯泡的项目。实现非常简单:我们将 ESP32 设置为软 AP 或 STA 模式,使其能够提供一个网页,显示灯开关的状态为…

计数排序+桶排序 详讲(思路+图解+代码详解)

文章目录 计数排序和桶排序一、计数排序概念&#xff1a;写法一&#xff1a;写法二&#xff1a; 二、桶排序概念代码 计数排序和桶排序 一、计数排序 时间复杂度&#xff1a;空间复杂度&#xff1a;稳定性&#xff1a;稳定 概念&#xff1a; 非基于比较的排序 计数排序又称为…

【Pytorch】Visualization of Fature Maps(2)

学习参考来自 使用CNN在MNIST上实现简单的攻击样本https://github.com/wmn7/ML_Practice/blob/master/2019_06_03/CNN_MNIST%E5%8F%AF%E8%A7%86%E5%8C%96.ipynb 文章目录 在 MNIST 上实现简单的攻击样本1 训练一个数字分类网络2 控制输出的概率, 看输入是什么3 让正确的图片分…

Visual Studio连接unity编辑器_unity基础开发教程

Visual Studio连接unity编辑器 问题描述解决方法意外情况 问题描述 当我们在unity编辑器中打开C#脚本的时候发现Visual Studio没有连接unity编辑器&#xff0c;在编写代码的时候也没有unity关键字的提醒。 简单来说就是敲代码没有代码提示。 解决方法 这时候需要在unity中进行…

【Pytorch】Visualization of Feature Maps(1)

学习参考来自 CNN可视化Convolutional Featureshttps://github.com/wmn7/ML_Practice/blob/master/2019_05_27/filter_visualizer.ipynb 文章目录 filter 的激活值 filter 的激活值 原理&#xff1a;找一张图片&#xff0c;使得某个 layer 的 filter 的激活值最大&#xff0c…

限时开发、码力全开、2w奖金!AGI Hackathon等你挑战!

AGI时代&#xff0c;我们已不再满足于简单的产品开发&#xff0c;与大模型结合的无限想象力&#xff0c;成为开发者们新的追求。 你有能力将想法转化为现实吗&#xff1f;你有勇气接受挑战&#xff0c;创造全新的AI应用吗&#xff1f; 如果你有热情&#xff0c;有信心&#x…

Git 教程

目录 Git 与 SVN 区别 Git 快速入门 学习目录 git简明指南 Git 安装配置 Git 工作流程、工作区、暂存区和版本库 Git 创建仓库 Git 基本操作 Git 分支管理 Git 查看提交历史 Git 标签 Git 远程仓库(Github) Git 服务器搭建 Git 是一个开源的分布式版本控…

909-2014-T1

文章目录 1.原题2.算法思想3.关键代码4.完整代码5.运行结果 1.原题 为带表头的单链表类Chain编写一个成员函数Reverse&#xff0c;该函数对链表进行逆序操作&#xff08;将链表中的结点按与原序相反的顺序连接&#xff09;&#xff0c;要求逆序操作就地进行&#xff0c;不分配…

MySQL - 4种基本索引、聚簇索引和非聚索引、索引失效情况

目录 一、索引 1.1、简单介绍 1.2、索引的分类 1.2.1、主键索引 1.2.2、单值索引&#xff08;单列索引、普通索引&#xff09; 1.2.3、唯一索引 1.2.4、复合索引 1.2.5、复合索引经典问题 1.3、索引原理 1.3.1、主键自动排序 1.3.2、索引的底层原理 1.3.3、B 树和 B…

简单几步,借助Aapose.Cells将 Excel XLS 转换为PPT

数据呈现是商业和学术工作的一个重要方面。通常&#xff0c;您需要将数据从一种格式转换为另一种格式&#xff0c;以创建信息丰富且具有视觉吸引力的演示文稿。当您需要在幻灯片上呈现工作表数据时&#xff0c;需要从 Excel XLS 转换为 PowerPoint 演示文稿。在这篇博文中&…

新能源充电桩工业4G路由器应用,推动绿色出行,响应环保理念

在智慧城市环保事业发展领域&#xff0c;新能源技术应用成熟&#xff0c;物联网技术越来越广泛&#xff0c;充电桩物联网成为了智慧城市建设的热门应用。充电桩作为新能源汽车的重要配套设施&#xff0c;对于节能减排和推动环保理念可持续发展具有重要意义。而工业4G路由器作为…

数环通对企业销售业务流程(O2C)的成熟度模型分享

保持紧密的客户关系&#xff0c;给客户留下良好的第一印象至关重要&#xff0c;而从下单到顺利履约是实现这一目标的最重要一环。 客户在做出购买决策后往往在最开始是充满了正向情绪&#xff08;例如兴奋、期待&#xff09;&#xff0c;但随着时间的推移&#xff0c;焦虑感会持…

(C++)验证回文字符串

愿所有美好如期而遇 力扣&#xff08;LeetCode&#xff09;官网 - 全球极客挚爱的技术成长平台备战技术面试&#xff1f;力扣提供海量技术面试资源&#xff0c;帮助你高效提升编程技能&#xff0c;轻松拿下世界 IT 名企 Dream Offer。https://leetcode.cn/problems/valid-pali…

什么款式的蓝牙耳机跑步不容易掉?推荐几款很不错的运动耳机

​如果你正在寻找一款性能卓越、佩戴舒适的耳机&#xff0c;那么运动耳机绝对是你的不二选择。它们不仅具备出色的音质&#xff0c;还具备防水、防汗、防震等多项特点&#xff0c;让你在运动时更加尽情享受音乐。接下来给大家推荐几款很不错的运动耳机。 1.南卡开放式运动耳机…

阿里云高效计划学生和老师免费代金券申请认证方法

阿里云高校计划学生和教师均可参与&#xff0c;完成学生认证和教师验证后学生可以免费领取300元无门槛代金券和3折优惠折扣&#xff0c;适用于云服务器等全量公共云产品&#xff0c;订单原价金额封顶5000元/年&#xff0c;阿里云百科aliyunbaike.com分享阿里云高校计划入口及学…