【JavaEE】基于mysql与servlet自制简易的表白墙程序

news2024/9/20 12:39:14

文章目录

  • 1 表白墙页面构建
  • 2 Servlet 回顾
  • 3 表白墙后端程序实现
    • 3.1 我们需要做什么?
    • 3.2 实现细节
  • 4 实现结果
  • 写在最后


1 表白墙页面构建

在这里插入图片描述
 该页面由标题、文本、三个 input 输入框与一个提交按钮构成,整体比较简单,相关样式文件和页面代码会在后面给出。

 我们需要解决的核心问题,就是考虑:如何让表白信息在页面上显示出来?
显然,我们可以使用 JavaScript 中的选择器,选中三个输入框,并对提交按钮添加点击监听事件。当我们点击按钮的时候,获取三个输入框的内容,并将输入框的内容以自己定义的格式插入到 html 中,并在浏览器上显示出来~

 需要注意的是,如果用户还未写完内容,即三个输入框中的内容没有输入完整,则不能进行提交~ 页面构建代码如下:

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>
</head>
<body>
<style>
    * {
        margin: 0;
        padding: 0;
        box-sizing: border-box;
    }

    .container {
        width: 100%;
    }

    h3 {
        text-align: center;
        padding: 30px 0;
        font-size: 24px;
    }

    p {
        text-align: center;
        color: #999;
        padding: 10px 0;
    }

    .row {
        width: 400px;
        height: 50px;
        margin: 0 auto;

        display: flex;
        justify-content: center;
        align-items: center;
    }

    .row span {
        width: 60px;
        font-size: 20px;
    }

    .row input {
        width: 300px;
        height: 40px;
        line-height: 40px;
        font-size: 20px;
        text-indent: 0.5em;
        /* 去掉输入框的轮廓线 */
        outline: none;
    }

    .row #submit {
        width: 300px;
        height: 40px;
        font-size: 20px;
        line-height: 40px;
        margin: 0 auto;

        color: white;
        background-color: #fa8497;
        /* 去掉边框 */
        border: none;

        border-radius: 10px;
    }

    .row #submit:active {
        background-color: gray;
    }
</style>
<div class="container">
    <h3>小黄圆圆表白墙</h3>
    <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>

<script>
    // 当用户点击 submit, 就会获取到 input 中的内容, 从而把内容构造成一个 div, 插入到页面末尾.
    let submitBtn = document.querySelector('#submit');
    submitBtn.onclick = function() {
        // 1. 获取到 3 个 input 中的内容.
        let inputs = document.querySelectorAll('input');
        let from = inputs[0].value;
        let to = inputs[1].value;
        let msg = inputs[2].value;
        if (from == '' || to == '' || msg == '') {
            // 用户还没填写完, 暂时先不提交数据.
            return;
        }
        // 2. 生成一个新的 div, 内容就是 input 里的内容. 把这个新的 div 加到页面中.
        let div = document.createElement('div');
        div.innerHTML = from + ' 对 ' + to + ' 说: ' + msg;
        div.className = 'row';
        let container = document.querySelector('.container');
        container.appendChild(div);
        // 3. 清空之前输入框的内容.
        for (let i = 0; i < inputs.length; i++) {
            inputs[i].value = '';
        }
    }
</script>
</body>
</html>

来一个简单的测试~
在这里插入图片描述
 至此,程序都没有什么问题。但是,当我们点击页面刷新的时候,数据(表白)信息就丢失了。原因很简单~ 没有实现数据的持久化 怎么解决呢?显然,我们可以通过服务器,来对数据实现持久化存储,这就需要用到我们的 Servlet 了。
简而言之,就是通过 Servlet 程序处理页面的请求,将请求数据中的表白信息,持久化存储到数据库中,当再次刷新页面的时候,从服务器中拉取数据~


2 Servlet 回顾

Servlet是什么?

  • Servlet是JavaEE规范之一,规范就是接口
  • Servlet是JavaWeb的三大组件之一,三大组件分别是:Servlet程序、Filter过滤器、Listener监听器
  • Servlet是运行在服务器上的一个java小程序,可以接收客户端发来的请求,并响应数据给客户端

其他内容,可以参考笔者的 JavaWeb 专栏的 Servlet 部分,这里不再赘述:Servlet 核心编程

与笔者前面文章不同的是,这次我们使用 maven 来导入相关的依赖,在本 Demo 中,我们主要使用了 Servlet,mysql 以及 jackson 来解析 json 数据,相关依赖核心代码如下:

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

        <!-- 用于解析 json 的依赖 -->
        <!-- https://mvnrepository.com/artifact/com.fasterxml.jackson.core/jackson-databind -->
        <dependency>
            <groupId>com.fasterxml.jackson.core</groupId>
            <artifactId>jackson-databind</artifactId>
            <version>2.12.7.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>

3 表白墙后端程序实现

3.1 我们需要做什么?

核心:让表白数据不丢失

我们就需要通过服务器,来保存上述程序的消息数据,做到持久化存储~

那么问题来了~ 客户端 和 服务端该如何交互呢?
在这里插入图片描述
  试想一个场景,你来到一个陌生的国家,想要买一张回国的机票。但是,你给路人说:“你好~请问机场怎么走?” 路人:“What can I do for you?”
这里我们做出如下假设:

  1. 你不会说英语;
  2. 路人不会说中文;
  3. 你听不懂英语;
  4. 路人听不懂中文。

 路人表示:“你说什么~我完全听不懂的吖。” 而如果我们想让后端服务器能够正确的提供给客户端需要的服务,就需要前后端都能听得懂,说得通。因此,有必要统一语言,即自定义应用层协议,规范请求和响应的数据组织形式~

  那么,再回到问题本身。我们要写一个服务器,服务器是干什么的?既然是服务器,服务器就应该提供服务。试想一个这样的场景:你想要洗衣服,但是家里只提供给你了个智能电饭煲~ 有如下的功能:

  1. 煲汤
  2. 做饭

 显然,电饭煲再智能,它也是没有办法帮你洗衣服滴~ 对于前后端的交互来说,我们也需要约定好都需要什么样的功能,能提供什么样的功能,即约定好前后端交互的接口,定好相应的规范~
在这里插入图片描述

小结:约定前后端交互的接口,自定义应用层协议~

对于表白墙来说,主要提供如下两个接口:

  • 告诉服务器,当前留言了一个怎么样的数据:当用户点击提交按钮的时候,就会给服务器发送一个 http 请求,服务器将这个消息保存下来。
  • 从服务器获取到,当前都有哪些留言数据:当页面加载,就需要从服务器获取曾经存储的数据。

如何约定协议呢?

  • 只需要约定好,客户端应该发送一个怎么样的 http请求 服务器返回一个怎么样的 http响应。只要前后端都按照这个约定去做就好~
  • 常见的可以使用 json 等~ 这里,我们采用的就是 json 格式:
    在这里插入图片描述

3.2 实现细节

修改前端代码,使用 ajax 构造请求

  1. 点击提交的时候,ajax 要构造数据发送给服务器
  2. 页面加载的时候,从服务器获取消息列表,并在界面显示

JavaScript 的代码修改如下:

<script src="https://cdn.bootcdn.net/ajax/libs/jquery/3.6.0/jquery.min.js"></script>
<script>
    function getMessages(){
        $.ajax({
            type: 'get',
            url: 'message',
            success: function(body){
                // 当前 body 已经是一个 js 对象数组了,ajax 会根据响应的 content type 自动解析
                // 如果服务器返回的 content-type 已经是 application/json 了,ajax 就会把 body 自动转成 js 的对象
                // 如果客户端没有自动转,也可以通过 JSON.parse() 手动转换

                // 依次来取数组中的每个元素
                let container = document.querySelector('.container');
                for(let message of body){
                    let div = document.createElement('div');
                    div.innerHTML = message.from + ' 对 ' + message.to + ' 说: ' + message.message;
                    div.className = 'row';
                    container.appendChild(div);
                }
            }
        })
    }

    getMessages();

    // 当用户点击 submit, 就会获取到 input 中的内容, 从而把内容构造成一个 div, 插入到页面末尾.
    let submitBtn = document.querySelector('#submit');
    submitBtn.onclick = function() {
        // 1. 获取到 3 个 input 中的内容.
        let inputs = document.querySelectorAll('input');
        let from = inputs[0].value;
        let to = inputs[1].value;
        let msg = inputs[2].value;
        if (from == '' || to == '' || msg == '') {
            // 用户还没填写完, 暂时先不提交数据.
            return;
        }
        // 2. 生成一个新的 div, 内容就是 input 里的内容. 把这个新的 div 加到页面中.
        let div = document.createElement('div');
        div.innerHTML = from + ' 对 ' + to + ' 说: ' + msg;
        div.className = 'row';
        let container = document.querySelector('.container');
        container.appendChild(div);
        // 3. 清空之前输入框的内容.
        for (let i = 0; i < inputs.length; i++) {
            inputs[i].value = '';
        }

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

构建相应的类,方便存储 json 对应的数据,这里需要属性和 key 名称一致,便于 jackson 自动读取数据存储到该类的对象中~

Message.java

这里使用 public 修饰完全是为了图方便,读者可以自行封装,并提供相应的 get、set 方法,结果也是一样滴~

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

创建数据库与相应的表

create database message_wall;
use message_wall;
create table message(
	`from` varchar(1024), 
	`to` varchar(1024), 
	message varchar(4096)
);

DBUtil.java
用于操作获取数据库资源的工具类,注意考虑线程安全问题~

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 兴趣使然黄小黄
 * @version 1.0
 * 方便与数据库之间的操作
 */
@SuppressWarnings({"all"})
public class DBUtil {
    private static final String URL = "jdbc:mysql://127.0.0.1:3306/message_wall?characterEncoding=utf8&useSSL=false";
    private static final String USER_NAME = "root";
    private static final String PASSWORD = "123456";

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

Servlet 程序的实现

具体可见代码注释~

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 兴趣使然黄小黄
 * @version 1.0
 * servlet程序, 实现表白墙后台逻辑
 */
class Message{
    public String from;
    public String to;
    public String message;
}

@SuppressWarnings({"all"})
@WebServlet("/message")
public class MessageServlet extends HttpServlet {

    private ObjectMapper objectMapper = new ObjectMapper(); // 用于解析 json

    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        // 处理提交消息请求
        Message message = objectMapper.readValue(req.getInputStream(), Message.class); // 读取 json
        save(message); // 存储
        // 通过 ContentType 来告知页面, 返回的数据是 json 格式.
        // 有了这样的声明, 此时 jquery ajax 就会自动的帮我们把字符串转成 js 对象.
        // 如果没有, jquery ajax 就只是当成字符串来处理的~~
        resp.setContentType("application/json; charset=utf8");
        resp.getWriter().write("{ \"ok\": true }");
    }

    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        // 获取到消息列表. 只要把消息列表中的内容整个的都返回给客户端即可
        // 此处需要使用 ObjectMapper 把 Java 对象, 转成 JSON 格式字符串~
        List<Message> messages = load(); // 获取数据
        String jsonString = objectMapper.writeValueAsString(messages);
        System.out.println("jsonString: " + jsonString);
        resp.setContentType("application/json; charset=utf8");
        resp.getWriter().write(jsonString);
    }

    /**
     * 将一条消息保存到数据库中
     * @param message 要保存的数据
     */
    private void save(Message message){
        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) {
            e.printStackTrace();
        } finally {
            // 4. 释放资源
            DBUtil.close(connection, statement, null);
        }
    }

    /**
     * 从数据库中获取到所有的表白信息
     * @return 返回一个List,存储的就是表白信息
     */
    private List<Message> load(){
        List<Message> messages = 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. 执行 sql
           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");
                messages.add(message);
            }
        } catch (SQLException e) {
            e.printStackTrace();
        } finally {
            // 4. 释放资源
            DBUtil.close(connection, statement, resultSet);
        }
        return messages;
    }
}


4 实现结果

启动 Tomcat 服务器,访问表白墙页面后,我们依次在页面中插入三条数据后刷新页面,结果如下图所示:
在这里插入图片描述
使用Fiddler进行抓包,请求和响应数据正常~

在这里插入图片描述

我们在数据库中查看,也能找到相应的数据~
在这里插入图片描述


写在最后

 本文相关代码已上传 gitee,如有需要请自取:JavaEE-表白墙Demo
 以上便是本文的全部内容啦!创作不易,如果你有任何问题,欢迎私信,感谢您的支持!

在这里插入图片描述

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

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

相关文章

【16】linux命令每日分享——tail命令查看文件

大家好&#xff0c;这里是sdust-vrlab&#xff0c;Linux是一种免费使用和自由传播的类UNIX操作系统&#xff0c;Linux的基本思想有两点&#xff1a;一切都是文件&#xff1b;每个文件都有确定的用途&#xff1b;linux涉及到IT行业的方方面面&#xff0c;在我们日常的学习中&…

分布式中雪花算法

背景需要选择合适的方案去应对数据规模的增长&#xff0c;以应对逐渐增长的访问压力和数据量。 数据库的扩展方式主要包括&#xff1a;业务分库、主从复制&#xff0c;数据库分表。 2.数据库分表概念&#xff1a;将不同业务数据分散存储到不同的数据库服务器&#xff0c;能够支…

网络参考模型

OSI参考模型 应用层 不服务于任何其他层&#xff0c;就是位APP提供相应的服务&#xff0c;不如HTTP、域名解析DNS提供服务表示层 1.使得应用数据能够被不同的系统&#xff08;Windows\Linux&#xff09;进行识别和理解 2.数据的解码和编码、数据的加密与解密、数据的压缩和解…

简单易懂值得收藏的Spring源码解析,依赖注入和bean的初始化

简单易懂值得收藏的Spring源码解析&#xff0c;依赖注入和bean的初始化原理解析依赖注入PropertyValues、PropertyValue、PropertyAccessorbyNamebyTypeAutowiredbean的初始化源码走读依赖注入populateBean方法autowireByNameautowireByType方法AutowiredAnnotationBeanPostPro…

广义状态平均法功率变换器建模分析

两种状态平均法在功率变换器建模的应用比较 [!info] Bibliography [1] 高朝晖, 林辉张晓斌 & 吴小华, “两种状态平均法在功率变换器建模的应用比较,” 计算机仿真, no. 241-244248, 2008. [!note] 状态空间平均法采用直流量近似&#xff08;线性系统模型&#xff09;&…

通达信指标公式颜色代码的四种写法(COLOR/RGB)

通达信指标公式颜色代码有四种写法&#xff0c;分别为COLOR颜色的英文、COLOR十六进制、RGBX十六进制、RGB(R,G,B)。标题有点尴尬&#xff0c;让我想到孔乙己“茴”字的四种写法&#xff0c;哈哈。 一、COLOR颜色的英文 “COLOR颜色的英文”这种写法比较简单&#xff0c;函数库…

【C++】bsearch函数的使用及二分法查找介绍

写程序的时候&#xff0c;肯定避免不了需要从集合中找到符合条件的元素&#xff0c;一般情况下&#xff0c;最简单也最常用的就是循环遍历元素&#xff0c;这种方法虽然写的简单&#xff0c;但是小数据量还行&#xff0c;但是数据过大的话&#xff0c;这样效率就低了。循环的时…

浅谈游戏中运用到的人工智能

电子游戏中的人工智能意味着电子游戏中角色的创造性行为就像人类游戏玩家正在控制他们一样。它提供了自适应和响应式的视频游戏体验。1949年初&#xff0c;密码学家克劳德香农发现了游戏中的人工智能&#xff0c;从而联想到了电脑上的单人国际象棋游戏。对于人工智能的发展&…

Android的基础介绍

一、Android介绍 Android是一种基于Linux的自由及开放源代码的操作系统,Android 分为四个层,从高层到低层分别是应用程序层、应用程序框架层、系统运行库层和Linux内核层。 Android 是Google开发的基于Linux平台的开源手机操作系统。它包括操作系统、用户界面和应用程序——…

力扣-可回收且低脂的产品

大家好&#xff0c;我是空空star&#xff0c;本篇带大家了解一道超级超级超级简单的力扣sql练习题。 文章目录前言一、题目&#xff1a;1757. 可回收且低脂的产品二、解题1.正确示范①提交SQL运行结果2.正确示范②提交SQL运行结果3.正确示范③提交SQL运行结果4.正确示范④提交S…

iview tree树形菜单实践之数据回显与选中

iview tree树形菜单在使用过程中&#xff0c;多多少少有一些小坑&#xff0c;本文简单罗列几个&#xff1a; 避坑指南&#xff1a; 关于iview tree树形菜单在使用过程中存在父级菜单的数据传输和回显问题 简单就是两个方面&#xff1a;勾选后数据传输和回显问题。 一&#xff…

mac 环境下安装MongoDB

目录 一、下载MongoDB数据库并进行安装 二. 解压放在/usr/local目录下 三. 配置环境变量 “无法验证开发者”的解决方法 mongodb可视化工具的安装与使用 一、下载MongoDB数据库并进行安装 下载地址&#xff1a;https://www.mongodb.com/try/download/community 二. 解压…

大数据项目实战之数据仓库:用户行为采集平台——第2章 项目需求及架构设计

第2章 项目需求及架构设计 2.1 项目需求分析 1&#xff09;采集平台 &#xff08;1&#xff09;用户行为数据采集平台搭建 &#xff08;2&#xff09;业务数据采集平台搭建 2&#xff09;离线需求 3&#xff09;实时需求 4&#xff09;思考题 1、项目技术如何选型&…

索引调优的一点基础知识

索引是什么 通过 show profile for query 1&#xff1b; 可以查看该查询语句执行的整个过程&#xff0c;则我们就能分析出那部分是需要优化的索引是帮助Mysql高效获取数据的数据结构 索引存储在文件系统中 索引的文件存储形式与存储引擎有关 索引文件的结构 hash 范围查找不方便…

深度学习-第T2周——彩色图片分类

深度学习-第T2周——彩色图片分类深度学习-第P1周——实现mnist手写数字识别一、前言二、我的环境三、前期工作1、导入依赖项并设置GPU2、导入数据集3、归一化4、可视化图片四、构建简单的CNN网络五、编译并训练模型1、设置超参数2、编写训练函数六、预测七、模型评估深度学习-…

产品经理如何去做需求分析,建议收藏

目录 一、需求收集 1. 产品需求 2. 功能需求 3. 迭代需求 二、需求分析 1. 系统了解需求&#xff08;5W2H法&#xff09; 2. 判断需求真实性 3. 分析现有解决方案-竞品分析 4. 行业结构分析 5. 总结 三、方案验证 四、商业模式 五、路线规划 六、战略制定 七、总…

基于贝叶斯优化CNN-LSTM混合神经网络预测(Matlab代码实现)

&#x1f468;‍&#x1f393;个人主页&#xff1a;研学社的博客&#x1f4a5;&#x1f4a5;&#x1f49e;&#x1f49e;欢迎来到本博客❤️❤️&#x1f4a5;&#x1f4a5;&#x1f3c6;博主优势&#xff1a;&#x1f31e;&#x1f31e;&#x1f31e;博客内容尽量做到思维缜密…

监控视频模糊看不清怎么处理提高监控视频清晰度?

随着监控设备的日益普及&#xff0c;监控视频的画质也成为了人们关注的焦点。然而&#xff0c;很多人反映监控视频画质不佳&#xff0c;有些甚至看不清。那么&#xff0c;对于这样的问题&#xff0c;我们该如何去处理呢&#xff1f;监控画面模糊变清晰处理方法如下&#xff1a;…

网上购物网站的设计

技术&#xff1a;Java、JSP等摘要&#xff1a;本文介绍了JSP和JAVA等相关技术&#xff0c;针对网上购物系统的实际需求&#xff0c;设计开发了一个基于JSP的小型电子商务网站也就是网上购物系统&#xff0c;。在设计开发中&#xff0c;采用的是SSH框架&#xff08;strutsspring…

一篇教你解决如何在不加锁的情况下解决多线程问题!

怎样在不加锁的情况下解决线程安全问题&#xff0c;你需要了解lock free和wait free这两个概念&#xff0c;在此之前我们先从最简单的有锁编程开始。 我们知道&#xff0c;多线程同时修改共享变量时会出现数据不一致的问题&#xff0c;比如多个线程同时对一个变量加1&#xff…