博客系统(Servlet)

news2024/11/25 1:05:16

我们的目标是实现一个带有服务器版本的博客系统(重点关注后端开发)

1.准备工作

1)创建web项目

2)创建相应的目录结构、

 3)配置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>blog_system</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.15.0</version>
        </dependency>

        <!-- https://mvnrepository.com/artifact/mysql/mysql-connector-java -->
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <version>5.1.49</version>
        </dependency>
    </dependencies>

    <!-- 指定压缩包的格式 -->
    <packaging>war</packaging>
    <build>
        <!-- 指定war包的名称 -->
        <finalName>BlogSystem</finalName>
    </build>

</project>

2.前端代码

2.1创建相关的目录

2.2每个目录或文件的内容

我们查看我的博客根据相关路径创建相应的文件,复制相应的内容即可,所需要复制的内容只有上述标记的即可。

2.3editor

editor存放的是markdown编辑器的内容,主要用于编写相应的博客。这个我们下载相应的代码即可。

  • Editor.md - 开源在线 Markdown 编辑器 (pandao.github.io) 打开相应的网址
  • 点击下载安装,然后点击使用giteehub下载

  •  安装好后,我们有相应的压缩包,然后解压缩,把总文件夹相应的名字修改成一下,把他放到相应的目录下面即可

2.4页面效果预览

登录页面

博客列表页】

博客编辑页面】

博客详情页】

3.数据库设计

3.1表的设计

博客系统主要有两个重要数据,一个博客数据,一个是用户数据。所以我们需要设计两张表,一张是文章表,一张是用户表

文章表】文章表所需要的元素有 博客id博客标题博客正文博客作者id发布时间

用户表】用户表所需要的内容有 用户id用户名用户密码

【完整的SQL语句】

我们可以在src/main目录下,创建一个db.sql,用于记录创建数据库时的语句,这样在部署到不同的服务器时,我们只需要复制一下即可

-- 一班对于建表的 sql 都会单独搞一个文件, .sql文件来保存
-- 后续程序可能需要在不同的主机上进行部署,部署的时候就需要在对应的主机上把数据库也创建好。
-- 把建表 sql 保存好,方便在不同的机器上进行建库建表


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

use blog_system;

-- 默认先删除一下残留数据
drop table if exists blog;
-- 创建博客相关信息的表格
create table blog(
    blogId int primary key auto_increment,
    title varchar(20),
    content varchar(4096),
    userId int,
    postTime datetime);

-- 默认先删除一下残留的数据
drop table if exists user;
-- 创建用户表
create table user(
    userId int primary key auto_increment,
    username varchar(50) unique,
    password varchar(50));




-- 用于测试使用的些许数据
-- 用户数据
insert into user values(null, 'zhangsan', '123'), (null, 'lisi', '123');
-- 博客数据
insert into blog values(null, '我的第一篇博客', '这是第一篇博客的内容。', 1, '2023-06-04 12:00:00');
insert into blog values(null, '我的第二篇博客', '这是第二篇博客的内容。', 1, '2023-06-05 12:00:00');

 4.封装数据库操作代码

我们发现使用JDBC进行数据库操作的时候,很多步骤都是固定的,如设置URL,设置用户,设置密码,建立连接,关闭资源等操作,我们将这些步骤提取出来以简化代码

4.1创建DBUtil

通过一个单例模式来获取数据库连接。

package model;


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;

/**
 * Describe:封装数据库操作代码
 * User:lenovo
 * Date:2023-07-03
 * Time:15:29
 */
public class DBUtil {
    //使用单例模式
    private static volatile DataSource dataSource= null;

    private static DataSource getDataSource() {
        //这里使用一个if会每次都要加锁,使用两个if不用每次都加锁,同时用能判断dataSource == null
        if(dataSource == null) {
            synchronized(DBUtil.class) {
                if(dataSource == null) {
                    dataSource = new MysqlDataSource();
                    ((MysqlDataSource)dataSource).setUrl("jdbc:mysql://127.0.0.1:3306/blog_system?characterEncoding=utf8&useSSL=false");
                    ((MysqlDataSource)dataSource).setUser("root");
                    ((MysqlDataSource)dataSource).setPassword("1020118096");
                }
            }
        }
        return dataSource;
    }

    public static Connection getConnection() throws SQLException {
        return getDataSource().getConnection();
    }

    public static void close(Connection connection, PreparedStatement statement, ResultSet resultSet) throws SQLException {
        if(connection != null) {
            connection.close();
        }
        if(statement != null) {
            statement.close();
        }
        if(resultSet != null) {
            resultSet.close();
        }
    }
}

4.2创建Blog类和User类

【Blog】

package model;

import java.sql.Timestamp;

/**
 * Describe:表示一篇博客的类
 * User:lenovo
 * Date:2023-07-03
 * Time:15:47
 */
public class Blog {
    private int blogId;
    private String title;
    private String content;
    private int userId;
    private Timestamp postTime;
    
    //下面我们自动生成相应的获取和设置的方法

    public int getBlogId() {
        return blogId;
    }

    public void setBlogId(int blogId) {
        this.blogId = blogId;
    }

    public String getTitle() {
        return title;
    }

    public void setTitle(String title) {
        this.title = title;
    }

    public String getContent() {
        return content;
    }

    public void setContent(String content) {
        this.content = content;
    }

    public int getUserId() {
        return userId;
    }

    public void setUserId(int userId) {
        this.userId = userId;
    }

    //注意这个比较特殊,我需要自己手动写
    public String getPostTime() {
        //我们可以打印一下原来的类型,看看到Java中是什么样子
        System.out.println(postTime);
        SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd hh:mm:ss");
        return format.format(postTime);
    }

    public void setPostTime(Timestamp postTime) {
        this.postTime = postTime;
    }
}

 【User】

package model;

/**
 * Describe:表示用户相关信息的类
 * User:lenovo
 * Date:2023-07-03
 * Time:15:51
 */
public class User {
    private int userId;
    private String username;
    private String password;
    
    //自动生成相应的get和set方法

    public int getUserId() {
        return userId;
    }

    public void setUserId(int userId) {
        this.userId = userId;
    }

    public String getUsername() {
        return username;
    }

    public void setUsername(String username) {
        this.username = username;
    }

    public String getPassword() {
        return password;
    }

    public void setPassword(String password) {
        this.password = password;
    }
}

4.3创建BlogDao类和UserDao类

什么是"DAO"?

DAO的全程是“data access object"(数据访问对象),主要功能就是对某个数据库表进行增删查改。一般每张数据库表会对应一个DAO类。这是一种给类命名的习惯做法,并不是强制要求的。

创建BlogDao类,针对博客表进行操作

  • insert:插入一个Blog对象到blog表种
  • selectAll:从blog表中查找所有的Blog对象
  • selectOne:从blog表中查找指定的Blog对象
  • delete:从blog表中删除指定的Blog对象
package model;



import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;

/**
 * Describe:对一个博客进行操作
 * User:lenovo
 * Date:2023-07-03
 * Time:16:09
 */
public class BlogDao {
    //把一个Blog对象插入到数据库中
    public void insert(Blog blog) throws SQLException {
        Connection connection = null;
        PreparedStatement statement = null;
        try {
            //1.建立连接
            connection = DBUtil.getConnection();
            //2.构造SQL语句
            String sql = "insert into blog values(null, ?, ?, ?, ?)";
            statement = connection.prepareStatement(sql);
            statement.setString(1, blog.getTitle());
            statement.setString(2, blog.getContent());
            statement.setInt(3, blog.getUserId());
            statement.setString(4, blog.getPostTime());
            //执行sql语句
            statement.executeUpdate();
        } catch (SQLException e) {
            e.printStackTrace();
        } finally {
            DBUtil.close(connection, statement, null);
        }
    }

    //查询 blog 表中所有博客数据
    public List<Blog> selectAll() throws SQLException {
        List<Blog> blogs = new ArrayList<>();
        Connection connection = null;
        PreparedStatement statement = null;
        ResultSet resultSet = null;
        try {
            connection = DBUtil.getConnection();
            String sql = "select * from blog order by postTime desc";
            statement = connection.prepareStatement(sql);
            resultSet = statement.executeQuery();

            while(resultSet.next()) {
                Blog blog = new Blog();
                blog.setBlogId(resultSet.getInt("blogId"));
                blog.setTitle(resultSet.getString("title"));
                String content = resultSet.getString("content");
                //可以被预览内容的部分
                if(content.length() > 100) {
                    content = content.substring(0, 100) +"...";
                }
                blog.setContent(content);
                blog.setUserId(resultSet.getInt("userId"));
                blog.setPostTime(resultSet.getTimestamp("postTime"));
                blogs.add(blog);
            }
        } catch (SQLException e) {
            e.printStackTrace();
        } finally {
            DBUtil.close(connection, statement, resultSet);
        }
        return blogs;
    }

    //指定博客ID来查询对应的博客
    public Blog selectOne(int blogId) {
        Connection connection = null;
        PreparedStatement statement = null;
        ResultSet resultSet = null;

        try {
            connection = DBUtil.getConnection();
            String sql = "select * from blog where blogId = ?";
            statement = connection.prepareStatement(sql);
            statement.setInt(1, blogId);
            resultSet = statement.executeQuery();

            if(resultSet.next()) {
                Blog blog = new Blog();
                blog.setBlogId(resultSet.getInt("blogId"));
                blog.setTitle(resultSet.getString("title"));
                blog.setContent(resultSet.getString("content"));
                blog.setUserId(resultSet.getInt("userId"));
                blog.setPostTime(resultSet.getTimestamp("postTime"));
                return blog;
            }
        } catch (SQLException e) {
            e.printStackTrace();
        }
        return null;
    }

    //指定 博客Id 来删除博客
    public void delete(int blogId) {
        Connection connection = null;
        PreparedStatement statement = null;
        try {
            connection = DBUtil.getConnection();
            String sql = "delete from blog where blogId = ?";
            statement = connection.prepareStatement(sql);
            statement.setInt(1, blogId);
            statement.executeUpdate();
        } catch (SQLException e) {
            e.printStackTrace();
        }
    }
}

创建UserDao类,实现对用户表的增删查改。

package model;

import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;

/**
 * Describe:对用户进行操作
 * User:lenovo
 * Date:2023-07-04
 * Time:10:18
 */
public class UserDao {
    //通过ID查询
    public User selectUserById(int userId) throws SQLException {
        User user = null;
        Connection connection = null;
        PreparedStatement statement = null;
        ResultSet resultSet = null;
        try {
            connection = DBUtil.getConnection();
            String sql = "select * from user where userId = ?";
            statement = connection.prepareStatement(sql);
            statement.setInt(1, userId);
            resultSet = statement.executeQuery();

            if(resultSet.next()) {
                user = new User();
                user.setUserId(resultSet.getInt("userId"));
                user.setUsername(resultSet.getString("username"));
                user.setPassword(resultSet.getString("password"));
            }
        } catch (SQLException e) {
            e.printStackTrace();
        } finally {
            DBUtil.close(connection, statement, resultSet);
        }
        return user;
    }

    //通过名字查询
    public User selectUserByName(String name) throws SQLException {
        User user = null;
        Connection connection = null;
        PreparedStatement statement = null;
        ResultSet resultSet = null;

        try {
            connection = DBUtil.getConnection();
            String sql = "select * from user where username = ?";
            statement = connection.prepareStatement(sql);
            statement.setString(1, name);
            resultSet = statement.executeQuery();

            if(resultSet.next()) {
                user = new User();
                user.setUserId(resultSet.getInt("userId"));
                user.setUsername(resultSet.getString("username"));
                user.setPassword(resultSet.getString("password"));
            }
        } catch (SQLException e) {
            e.printStackTrace();
        } finally {
            DBUtil.close(connection, statement, resultSet);
        }
        return user;
    }
}

5.创建相应的API

5.1创建BlogServlet.java

这个主要用于查看博客列表,查看博客详情,以及提交博客使用

package api;

import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import model.Blog;
import model.BlogDao;
import model.User;

import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.sql.SQLException;
import java.sql.Timestamp;
import java.util.List;

/**
 * Describe:通过这个类实现一些后端接口,这个主要用于查看博客列表,查看博客详情,以及提交博客使用
 * User:lenovo
 * Date:2023-07-08
 * Time:10:58
 */
@WebServlet("/blog")
public class BlogServlet extends HttpServlet {
    private ObjectMapper objectMapper = new ObjectMapper();

     @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        // 从query string 中查询是否有 blogId,如果有就认为是查询指定的博客;如果没有就是查询所有博客
        BlogDao blogDao = new BlogDao();
        String blogId = req.getParameter("blogId");
        System.out.println("这里在查看参数");
        if(blogId == null) {
            System.out.println("URL后面没有参数,表示查找全部博客");
            List<Blog> blogs = null;
            try {
                blogs = blogDao.selectAll();
            } catch (SQLException e) {
                e.printStackTrace();
            }
            String respString = objectMapper.writeValueAsString(blogs);
                resp.setContentType("application/json;charset=utf8");
                resp.getWriter().write(respString);
        }else {
            Blog blog = blogDao.selectOne(Integer.parseInt(blogId));
            String respString = objectMapper.writeValueAsString(blog);
            resp.setContentType("application/json; charset=utf8");
            resp.getWriter().write(respString);
        }
    }

    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws IOException {
        req.setCharacterEncoding("utf8");
        // 1.先从请求中拿到标题和正文
        String title = req.getParameter("title");
        String content = req.getParameter("content");
        if (title == null || title.equals("") || content == null || content.equals("")) {
            String html = "<h3>title 或者 content 为空!新增博客失败!</h3>";
            resp.setContentType("text/html; charset=utf8");
            resp.getWriter().write(html);
            return;
        }
        // 2.从会话中拿到作者的id
        HttpSession session = req.getSession(false);
        if(session == null) {
            String html = "<h3>当前用户为登录!新增博客博客失败!</h3>";
            resp.setContentType("text/html; charset=utf8");
            resp.getWriter().write(html);
            return;
        }
        User user = (User)session.getAttribute("user");
        if(user == null) {
            String html = "<h3>当前用户未登录!新增博客失败!<h3>";
            resp.setContentType("text/html; charset=utf8");
            resp.getWriter().write(html);
            return;
        }
        // 3.构造blog对象
        Blog blog = new Blog();
        blog.setUserId(user.getUserId());
        blog.setTitle(content);
        blog.setContent(content);
        blog.setPostTime(new Timestamp(System.currentTimeMillis()));
        // 4.插入blog对象到数据库中
        BlogDao blogDao = new BlogDao();
        try {
            blogDao.insert(blog);
        } catch (SQLException e) {
            e.printStackTrace();
        }
        // 5.跳转到博客列表页
        resp.sendRedirect("blog_list.html");
    }
}

5.2创建LoginServlet.java

这个类主要用于匹配登录,并验证是否登录的,如果没有登录却在访问其他选项,会跳转到登录页面。

package api;

import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import model.User;
import model.UserDao;

import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.sql.SQLException;

/**
 * Describe:登录的一些接口
 * User:lenovo
 * Date:2023-07-09
 * Time:19:08
 */
@WebServlet("/login")
public class LoginServlet extends HttpServlet {
    private ObjectMapper objectMapper = new ObjectMapper();

    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws IOException{
        req.setCharacterEncoding("utf8");
        // 1.从请求中,获取到用户名和密码
        String username = req.getParameter("username");
        String password = req.getParameter("password");
        if(username == null || username.equals("") || password == null || password.equals("")) {
            // 用户名或密码残缺
            String html = "<h3>登录失败!缺少用户名或者密码!</h3>";
            resp.setContentType("text/html; charset=uft8");
            resp.getWriter().write(html);
            return;
        }
        // 2.从数据库中读数据,看看用户名和密码是否匹配
        UserDao userDao = new UserDao();
        User user = null;
        try {
            user = userDao.selectUserByName(username);
        } catch (SQLException e) {
            e.printStackTrace();
        }
        if(user == null) {
            // 用户不存在
            String html = "<h3>用户名或密码错误!</h3>";
            resp.setContentType("text/html; charset=utf8");
            resp.getWriter().write(html);
            return;
        }
        if(!password.equals(user.getPassword())) {
            // 密码错误
            String html = "<h3>用户名或密码错误!</h3>";
            resp.setContentType("text/html; charset=utf8");
            resp.getWriter().write(html);
            return;
        }
        // 3.用户名和密码都正确,登录成功,需要设置会话
        HttpSession session = req.getSession(true);
        // 此处就把用户对象储存到session中了,下次用户访问其他页面,就可以直接拿到会话
        session.setAttribute("user", user);
        // 4.返回一个重定向相应,能够跳转到博客列表页
        resp.sendRedirect("blog_list.html");
    }

    //通过这个方法,判断用户的登录状态,已登录,返回200,未登录返回403
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws IOException {
        //查询会话是否存在
        HttpSession session = req.getSession(false);
        if(session == null) {
            //会话不存在,未登录状态
            resp.setStatus(403);
            return;
        }
        User user = (User)session.getAttribute("user");
        if(user == null) {
            //会话虽然存在,但是用户对象没有,未登录状态
            resp.setStatus(403);
            return;
        }
        //已经登录了
        //200是默认的状态码,此处不写200也是可以的
        resp.setStatus(200);
        resp.setContentType("application/json;charset=utf8");
        user.setPassword("");//避免密码被返回,我们设置未空
        String respJson = objectMapper.writeValueAsString(user);
        resp.getWriter().write(respJson);
    }

}

5.3创建UserServlet.java

这个类主要用于博客详情页,用于查询指定的博客对应的作者

package api;

import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import model.Blog;
import model.BlogDao;
import model.User;
import model.UserDao;

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.SQLException;

/**
 * Describe:
 * User:lenovo
 * Date:2023-07-10
 * Time:10:26
 */
@WebServlet("/user")
public class UserServlet extends HttpServlet {
    private ObjectMapper objectMapper = new ObjectMapper();

    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws IOException {
        // 1.先读取出blogId
        String blogId = req.getParameter("blogId");
        if(blogId == null || blogId.equals("")) {
            // 直接返回一个 userId 为0的对象,因为最终返回的是一个 json 数据
            // 此处返回 json 格式的对象,如果返回一个html,前端处理会很麻烦
            String respJson = objectMapper.writer().writeValueAsString(new User());
            resp.setContentType("application/json; charset=utf8");
            System.out.println("参数给定的blogId为空");
            return;
        }
        // 2.查询数据库,查询对应的 Blog 对象
        BlogDao blogDao = new BlogDao();
        Blog blog = blogDao.selectOne(Integer.parseInt(blogId));
        if(blog == null) {
            String respJson = objectMapper.writeValueAsString(new User());
            resp.setContentType("application/json; charset=utf8");
            resp.getWriter().write(respJson);
            System.out.println("阐述给定的blogId不存在!");
            return;
        }
        // 3.根据 blog 中 userId,查询作者的信息
        UserDao userDao = new UserDao();
        User user = null;
        try {
            user = userDao.selectUserById(blog.getUserId());
            if(user == null) {
                String respJson = objectMapper.writeValueAsString(new User());
                resp.setContentType("application/json; charset=utf8");
                resp.getWriter().write(respJson);
                System.out.println("该博客对应的作者不存在!");
                return;
            }
        } catch (SQLException e) {
            e.printStackTrace();
        }
        // 4.把user对象返回给页面
        String respJson = objectMapper.writeValueAsString(user);
        resp.setContentType("application/json; charset=utf8");
        resp.getWriter().write(respJson);
    }
}

5.4创建LogoutServlet.java

用于注销账号

package api;

import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.io.IOException;

/**
 * Describe:用于注销功能
 * User:lenovo
 * Date:2023-07-10
 * Time:10:56
 */
@WebServlet("/logout")
public class LogoutServlet extends HttpServlet {
    
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws IOException {
        HttpSession session = req.getSession(false);
        if(session == null) {
            //本身就没有登陆
            resp.sendRedirect("login.html");
            return;
        }
        //如果user存在
        session.removeAttribute("user");
        resp.sendRedirect("login.html");
    }
}

6.总结

这是一个简单的博客系统,我们完成了博客登录页,博客详情页,博客列表页,博客编辑页,注销功能。

这个对于初学者先对比较难,也会发生很多的问题。我们可以通过在控制台打印的方式来确定问题的位置,如

 当然在我们上线服务器的时候,只要进行注释即可

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

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

相关文章

【玩转Linux操作】一文带你明白Shell的判断,循环语句

&#x1f38a;专栏【玩转Linux操作】 &#x1f354;喜欢的诗句&#xff1a;更喜岷山千里雪 三军过后尽开颜。 &#x1f386;音乐分享【如愿】 大一同学小吉&#xff0c;欢迎并且感谢大家指出我的问题&#x1f970; 文章目录 &#x1f354;判断语句⭐单层if&#x1f388;示例 ⭐…

C++ 最长子段和

最大子段和详解_最大字段和_Niteip的博客-CSDN博客 #include <iostream> #include <sstream> #include <vector> #include <string> #include <algorithm> #include <climits> #include <unordered_map> #include <set>using…

ElementUI —— Cascader 级联选择器

前言&#xff1a; 项目中使用Cascader级联选择器&#xff0c;通过递归处理后端接口返回的数据。 function fn(temp) {let newArr [];for (let i 0; i < temp.length; i) {let obj {};obj.value temp[i].name;obj.label temp[i].name;obj.children [];if (temp[i].chil…

Python爬虫实战之原神公告获取

前言 好久不见了吧&#xff0c;博主最近也是成为了准高三&#xff0c;没有太多时间去创作文章了&#xff0c;所以这篇文章很有可能是高考前最后一篇文章了(也不一定&#x1f609;) 言归正传&#xff0c;本次文章主要讲解如何去爬取原神官网的公告(我不玩原神&#xff01;&…

如何在WordPress网站中嵌入TikTok视频(3个简单方法)

您想轻松地将 TikTok 视频嵌入您的 WordPress 网站吗&#xff1f; 如果您已经创建了成功的、病毒式传播的 TikTok&#xff0c;那么将这些视频发布到您的网站也是有意义的。通过这种方式&#xff0c;您只需很少的额外努力就能获得更多的观看次数、参与度和社交媒体关注者。 在…

企业面临数字化转型,有什么建议吗?

数字化转型是一个综合过程&#xff0c;涉及利用数字技术增强业务运营、改善客户体验并推动创新。企业数字化转型的一些建议&#xff1a; 制定清晰的愿景&#xff1a;定义数字化转型目标并创建与业务目标相符的愿景。这将有助于指导数字化并确保它们的驱动目标。 拥抱云计算&am…

盲盒抽奖小程序源码-带H5端可打包APP_带安装教程

1.新建站点。上传后台源码文化到新建站点&#xff0c;解压跟目录&#xff01;&#xff01; 2. 导入数据库文件&#xff0c;修改数据库信息&#xff0c;&#xff08;数据库根目录 .env 文件&#xff09; 3. 修改网站运行目录 《运行目录为/public 》 4. 修改伪静态 《伪静态t…

STM32 Proteus仿真双路0-20V直流电压表TM1637数码管-0061

STM32 Proteus仿真双路0-20V直流电压表TM1637数码管-0061 Proteus仿真小实验&#xff1a; STM32 Proteus仿真双路0-20V直流电压表TM1637数码管-0061 功能&#xff1a; 硬件组成&#xff1a;STM32F103R6单片机 TM1637 4位数码管驱动电路2路0~20V电压测量模块2个电位器输出0-…

微信小程序精选,多样化的功能与便捷体验

白噪音Pro、魔术字体和天天倒计时&#xff0c;这三款微信小程序正越来越受到我们的欢迎。它们各自具有独特的功能和特点&#xff0c;为我们提供了多样化的体验。现在&#xff0c;让我们一起来详细介绍一下这三款小程序。 首先是白噪音Pro。随着生活节奏的加快和压力的增加&…

如何把录音转换成文字免费?用三个方法轻松转文字!

录音转文字的技术为我们的生活带来了诸多便利。例如&#xff0c;一家新闻机构正在进行一项采访&#xff0c;需要记录受访者的观点和信息&#xff0c;他们选择使用录音设备来收集数据&#xff0c;因为这样可以更准确地捕捉受访者的原始反应。然而&#xff0c;手动将录音内容转化…

动态路由介绍

目录 动态路由 协议的划分&#xff1a; 通过协议算法的不同可以分为两类&#xff1a; RIP RIP的基础配置 拓展配置&#xff1a; 1.RIP的手工认证——RIPV2的手工认证 2.RIP的手工汇总 3.RIP的沉默接口 4.RIP的加快收敛 5.RIP的缺省路由 OSPF 动态路由评判标准&…

今天给大家分享几款优质的图片处理软件

图片处理软件是现代生活中不可或缺的一种工具。无论是平面设计、摄影后期还是日常生活中的照片编辑等&#xff0c;都需要借助优质的图片处理软件来完成各种任务。今天&#xff0c;我将向大家介绍几款非常优秀的图片处理软件&#xff0c;它们功能强大、易于操作&#xff0c;可以…

ES trouble shotting

一、背景 KfES 实例不同节点&#xff0c;会出现隔断时间告警&#xff0c;需要kill后恢复。 二、排查 排查是es 2.3.0低版本的bug&#xff0c;LRUQueryCache 初始化后一直在占用着内存没有释放。 2.1 ES 版本 2.2 内存占用情况 2.3 ES 源码 2.4 社区经验 elasticsearch2.3.…

特征融合篇 | YOLOv8 引入渐进特征金字塔网络 AFPN 结构 | 《2023年6月28日最新发表》

论文地址:https://arxiv.org/pdf/2306.15988.pdf 代码地址:https://github.com/gyyang23/AFPN 多尺度特征在目标检测任务中对于编码具有尺度变化的对象非常重要。一种常见的多尺度特征提取策略是采用经典的自顶向下和自底向上的特征金字塔网络。然而,这些方法存在特征信息的…

快手详情API接口jason格式java php

随着移动互联网的快速发展&#xff0c;短视频应用成为越来越多用户获取信息和进行购物的重要途径。作为广告商或电商平台&#xff0c;了解和充分利用快手的商品详情API接口将为您的营销策略带来巨大的潜力 了解快手商品详情API接口 快手的商品详情API接口是一组提供商品相关信息…

初阶C语言——指针

Hello&#xff0c;我们又见面了&#xff0c;时间过的好快啊&#xff0c;转眼间也已经写了这么多份博客了&#xff0c;在接下来的一年里&#xff0c;小编也会认真学习的敲代码&#xff0c;我们一起进步&#xff0c;那今天开始讲我们的指针&#xff0c;指针这一章节在C语言的学习…

node-red安全部署方式-安全登录功能

node-red安全部署方式 一、前期准备二、安全部署三、更多 安装号的node-red&#xff0c;默认是没有用户登陆功能的&#xff0c;每次进入工作界面只需输入服务器ip:端口号即可登陆。但是假如其他人知道了我们的ip地址&#xff0c;岂不是任何人都可以访问我们的服务器呢&#xff…

带你了解Python的重要性,就算做测试也要会Python

名字&#xff1a;阿玥的小东东 学习&#xff1a;Python、C/C 主页链接&#xff1a;阿玥的小东东的博客_CSDN博客-python&&c高级知识,过年必备,C/C知识讲解领域博主 目录 人生苦短&#xff0c;我用 Python 在测试工作中用好 Python 进阶&#xff1a;用Python构建测试…

mysql的各类索引

MySQL的索引分三类&#xff1a;单列索引&#xff08;普通索引、唯一索引、主键索引&#xff09;、多列索引(联合主键,组合索引)、全文索引 一、单列索引&#xff1a;一个索引只包含单个列&#xff0c;但一个表中可以有多个单列索引。 &#xff08;1&#xff09;普通索引(二级…

阿里巴巴最受欢迎的10本书,希望能帮助你开阔眼界

读书是一件充实生活、丰富精神的事情&#xff0c;世界是复杂的&#xff0c;我们可以从书中获得包罗万象的知识&#xff0c;精神体验从未有过的人生。 书荒&#xff1f;不存在的&#xff0c;好书互相分享才能发挥其最大的价值。我们在内部发起了一个“晒一本你在读的书”的活动…