Java个人博客系统--基于Springboot的设计与实现

news2025/1/20 1:39:15


目录

一、项目概述

应用技术

接口实现:

 数据库定义:

数据库建表:

博客表数据库相关操作:

添加项⽬公共模块

加密MD5

页面展示:http://121.41.168.121:8080/blog_login.html

 项目源码:https://gitee.com/li-dot/blogs

二、对博客系统进行自动化测试

测试用例图Docs

 使用Selenium进行测试


一、项目概述

个人博客系统是一个类似CSDN的博客分享平台,可以实现用户注册和登录,个人博客的编写、发布,个人信息的修改等操作。

应用技术

Cookie和Session会话、CSS、Servlet、MySQL、JS、HTML、Spring 框架等。

接口实现:

 数据库定义:

数据库建表:

--建表SQL
create database if not exists `java_blog_spring` charset utf8mb4;
--⽤户表
drop table if exists `java_blog_spring`.`user`;
CREATE TABLE `java_blog_spring`.`user` (
 `id` INT NOT NULL AUTO_INCREMENT,
 `user_name` VARCHAR(128) NOT NULL,
 `password` VARCHAR(128) NOT NULL,
 `github_url` VARCHAR(128) NULL,
 `delete_flag` TINYINT(4) NULL DEFAULT 0,
 `create_time` TIMESTAMP NULL DEFAULT current_timestamp(),
 PRIMARY KEY (`id`),
 UNIQUE INDEX `user_name_UNIQUE` (`user_name` ASC))
ENGINE = InnoDB DEFAULT CHARACTER SET = utf8mb4 COMMENT = '⽤户表';
--博客表
drop table if exists `java_blog_spring`.`blog`;
CREATE TABLE `java_blog_spring`.`blog` (
 `id` INT NOT NULL AUTO_INCREMENT,
 `title` VARCHAR(200) NULL,
 `content` TEXT NULL,
 `user_id` INT(11) NULL,
 `delete_flag` TINYINT(4) NULL DEFAULT 0,
 `create_time` TIMESTAMP NULL DEFAULT current_timestamp(),
 PRIMARY KEY (`id`))
ENGINE = InnoDB DEFAULT CHARSET = utf8mb4 COMMENT = '博客表';
--新增⽤户信息
insert into `java_blog_spring`.`user` (`user_name`, `password`,`github_url
`)values("zhangsan","123456","https://gitee.com");
insert into `java_blog_spring`.`user` (`user_name`, `password`,`github_url
`)values("lisi","123456","https://gitee.com");
insert into `java_blog_spring`.`blog` (`title`,`content`,`user_id`) values
("第⼀篇博客","111我是博客正⽂我是博客正⽂我是博客正⽂",1);
insert into `java_blog_spring`.`blog` (`title`,`content`,`user_id`) values
("第⼆篇博客","222我是博客正⽂我是博客正⽂我是博客正⽂",2);

博客表数据库相关操作:

1. 获取所有博客列表
2. 根据博客Id获取博客详情
3. 插⼊博客
4. 删除博客
5. 根据id查询user信息
6. 根据name查询user信息

......

添加项⽬公共模块

实体层(model) => 实体类
控制器层(controller) =>控制器
服务层(service) => 服务类
持久层(mapper) => mapper
⼯具层(common) => 统⼀返回类, 统⼀异常处理类

加密MD5

页面展示:http://121.41.168.121:8080/blog_login.html

用户名:zhangsan/lisi

密码:123456 

博客登录界面:

博客列表页:

 

 博客详情页:

 写博客页:

 项目源码:https://gitee.com/li-dot/blogs

二、对博客系统进行自动化测试

测试用例图Docs

 使用Selenium进行测试

package BlogTest;

import org.junit.jupiter.api.*;
import org.junit.jupiter.params.ParameterizedTest;
import org.junit.jupiter.params.provider.CsvFileSource;
import org.junit.jupiter.params.provider.CsvSource;
import org.junit.jupiter.params.provider.ValueSource;
import org.openqa.selenium.By;
import org.openqa.selenium.JavascriptExecutor;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.remote.RemoteWebDriverBuilder;

import java.util.concurrent.TimeUnit;

import static java.lang.Thread.sleep;

/**
 * @author Dian
 * Description
 * Date:2023/8/5:23:47
 */
@TestMethodOrder(MethodOrderer.OrderAnnotation.class)
public class BlogCases extends  InitAndEnd{
    /**
     * 登录
     */
    @Order(1)
 @ParameterizedTest //参数化
 @CsvSource("zhangsan,123456")
    void Login(String userName,String password) throws InterruptedException {
     System.out.println(userName);
     System.out.println(password);
        //打开登陆页面
        webDriver.get("http://121.41.168.121:8080/blog_login.html");
        //输入用户名
     webDriver.manage().timeouts().implicitlyWait(3, TimeUnit.SECONDS);
       webDriver.findElement(By.cssSelector("#userName")).sendKeys(userName);
     webDriver.manage().timeouts().implicitlyWait(3, TimeUnit.SECONDS);
       //输入密码
       webDriver.findElement(By.cssSelector("#password")).sendKeys(password);
     webDriver.manage().timeouts().implicitlyWait(3, TimeUnit.SECONDS);
       //点击提交
        webDriver.findElement(By.cssSelector("#submit")).click();
     webDriver.manage().timeouts().implicitlyWait(3, TimeUnit.SECONDS);
        sleep(2000);
        //校验当前登录的用户是不是zhangsan,如果是则测试通过,否则测试不通过
        String user_name = webDriver.findElement(By.cssSelector("h3")).getText();
     webDriver.manage().timeouts().implicitlyWait(3, TimeUnit.SECONDS);
        Assertions.assertEquals(userName,user_name);
    }
    /**
     *博客列表
     */
    @Order(2)
@Test
    void BlogList(){
    webDriver.get("http://121.41.168.121:8080/blog_list.html");
    webDriver.manage().timeouts().implicitlyWait(3, TimeUnit.SECONDS);
    int blog_num = webDriver.findElements(By.cssSelector(".title")).size();
    Assertions.assertNotEquals(0,blog_num);
    String page_title = webDriver.getTitle();
    Assertions.assertEquals(page_title,"博客列表页");

}
/**
 * 博客详情页校验
 */
@Order(3)
@Test
void BlogDetail(){
    //打开列表页
    webDriver.get("http://121.41.168.121:8080/blog_list.html");
    webDriver.manage().timeouts().implicitlyWait(3,TimeUnit.SECONDS);
    //找到查看全文按钮
    webDriver.findElement(By.xpath("/html/body/div[2]/div[2]/div[1]/a")).click();
    webDriver.manage().timeouts().implicitlyWait(3,TimeUnit.SECONDS);
    //获取博客标题
    String blog_title = webDriver.findElement(By.cssSelector("body > div.container > div.right > div:nth-child(1) > div.title")).getText();
    //如果博客正文不为空,测试通过

    //否则测试不通过
Assertions.assertNotNull(blog_title);
}

/**
 * 写博客
 */
@Order(4)
@Test
    void EditBlog() throws InterruptedException {
    // 找到写博客按钮,点击
    webDriver.findElement(By.cssSelector("body > div.nav > a:nth-child(5)")).click();
    webDriver.manage().timeouts().implicitlyWait(3,TimeUnit.SECONDS);

    // 执行js(选中标题输入框,输入字符串)
    ((JavascriptExecutor)webDriver).executeScript("document.querySelector(\"#title\").value =\"自动化测试\"");

    webDriver.manage().timeouts().implicitlyWait(3,TimeUnit.SECONDS);
    webDriver.findElement(By.cssSelector("#submit")).click();
    webDriver.manage().timeouts().implicitlyWait(3, TimeUnit.SECONDS);
    // 校验页面跳转到列表页
    sleep(3000);
    String cur_url = webDriver.getCurrentUrl();
    // 校验第一条博客标题是不是刚刚发布的博客标题
    String first_blog_title = webDriver.findElement(By.cssSelector("body > div.container > div.right > div:nth-child(6) > div.title")).getText();
    webDriver.manage().timeouts().implicitlyWait(3, TimeUnit.SECONDS);
    Assertions.assertEquals("自动化测试",first_blog_title);
}
    /**
     * 删除博客
     */
    @Order(5)
    @Test
    void DeleteBlog(){
        // 找到查看全文按钮并且点击
        webDriver.manage().timeouts().implicitlyWait(3,TimeUnit.SECONDS);
        webDriver.findElement(By.xpath("/html/body/div[2]/div[2]/div[1]/a")).click();
        webDriver.manage().timeouts().implicitlyWait(3,TimeUnit.SECONDS);
        // 找到删除按钮,点击
        webDriver.findElement(By.cssSelector("body > div.container > div.right > div > div.operating > button:nth-child(2)")).click();
        // 校验当前页面是否跳转到博客列表页面
        webDriver.manage().timeouts().implicitlyWait(3,TimeUnit.SECONDS);
        String cur_url = webDriver.getCurrentUrl();
        Assertions.assertEquals("http://121.41.168.121:8080/blog_list.html",cur_url);
        // 获取博客发布是时间
        String blog_release_time = webDriver.findElement(By.xpath("/html/body/div[2]/div[2]/div/div[2]")).getText();
        // 如果博客发布时间 包括2023-06-02测试 不通过
        if(blog_release_time.contains("2023-08-04 15:49:49")){
            System.out.println("博客发布时间:" + blog_release_time);
            System.out.println("测试不通过");
        }else{
            System.out.println("测试通过");
        }
    }
    /**
     * 退出博客
     */
    @Order(6)
    @Test
    void LogOut() throws InterruptedException {
        webDriver.manage().timeouts().implicitlyWait(3, TimeUnit.SECONDS);
        // 找到退出按钮,点击
        webDriver.findElement(By.cssSelector("body > div.nav > a:nth-child(6)")).click();
        webDriver.manage().timeouts().implicitlyWait(3, TimeUnit.SECONDS);
        // 校验页面是否有登录文案
        String login_text= webDriver.findElement(By.cssSelector("body > div.container-login > div > h3")).getText();
        // 如果有登录文案,退出成功(测试用例通过)
        // 否则,退出失败(测试不通过)
        sleep(3000);
        if(login_text.equals("登录")){
            System.out.println("测试通过");
        }else{
            System.out.println("测试不通过");
        }
    }
}

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

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

相关文章

初学 Python 需要安装哪些软件?超级实用,小白必看!

前言 大家早好、午好、晚好吖 ❤ ~欢迎光临本文章 编程这个东西是真的奇妙。 对于懂得的人来说,会觉得这个工具是多么的好用、有趣,而对于小白来说,就如同大山一样。 其实这个都可以理解,大家都是这样过来的。 那么接下来就说…

Spring简述

Sping是什么Spring主要模块IOCDI依赖注入的三种方式 AOP术语 Sping是什么 Spring是一个轻量级的开源框架,主要作用是为了简化开发,它以IOC(控制反转)和AOP(面向切面编程)为内核 Spring主要模块 我们一般…

cocosCreator 之 i18n多语言插件

版本: v3.4.0 环境: Mac 简介 i18n是国际化的简称, 全名:internationalization;取首尾字符i和n,18代表单词中间的字符数目。 该插件不需要产品做太多的改变,通过语言的设置,实现不…

P1194 买礼物(最小生成树)(内附封面)

买礼物 题目描述 又到了一年一度的明明生日了,明明想要买 B B B 样东西,巧的是,这 B B B 样东西价格都是 A A A 元。 但是,商店老板说最近有促销活动,也就是: 如果你买了第 I I I 样东西&#xff0…

【逗老师的PMP学习笔记】6、项目的进度管理

目录 一、规划进度管理1、【关键输出 】进度管理计划 二、定义活动1、【关键工具】拆解2、【关键工具】滚动式规划3、【关键输出】活动清单和活动属性4、【关键输出】里程碑清单 三、排列活动顺序1、【关键工具】紧前关系绘图法2、【关键工具】提前量和滞后量3、【关键输出】项…

Linux 中使用 verdaccio 搭建私有npm 服务器

安装 Node Linux中安装Node 安装verdaccio npm i -g verdaccio安装完成 输入verdaccio,出现下面信息代表安装成功,同时输入verdaccio后verdaccio已经处于运行状态,当然这种启动时暂时的,我们需要通过pm2让verdaccio服务常驻 ygiZ2zec61wsg…

网络编程——深入理解TCP/IP协议——OSI模型和TCP/IP模型:构建网络通信的基石

TCP/IP协议— 一、简介 TCP/IP协议,即传输控制协议/互联网协议,是一组用于在计算机网络中实现通信的协议。它由两个主要的协议组成:TCP(传输控制协议)和IP(互联网协议)。TCP负责确保数据的可靠…

【Linux取经路】冯诺依曼结构体系与操作系统的碰撞

文章目录 一、冯诺依曼体系结构1.1 硬件介绍1.2 内存的重要性 二、操作系统2.1 设计操作系统的目的2.2 操作系统是如何进行管理的? 一、冯诺依曼体系结构 我们现在常见的计算机,如笔记本,以及我们不常见的计算机,如服务器&#x…

Pycharm连接服务器

前提:必须为pycharm专业版才能连接到服务器 以下为pycharm2023专业版 一、连接 系统环境 虚拟环境(前提:已安装anaconda) (1) anaconda环境 (2) 自己创建的虚拟环境 这里为envs下的spotr 二、查看连接情况 选择自动上传

Docker 发布一个springboot项目

文章目录 1、新建SpringBootDemo项目并打包2、使用Dockerfile打包(基础用法)进一步maven源码打包法 3、更进一步(maven插件打包)docker-maven-pluginspring-boot-maven-plugin前提条件本地环境配置项目环境配置maven插件打包运行校…

一文让你了解网络安全和云安全的区别与联系

相信大家对于网络安全和云安全的关系不是很了解,今天小编就和大家来一起聊聊网络安全和云安全的区别与联系,仅供参考哦! 网络安全和云安全的区别 1、两者定义不同。网络安全通常指计算机网络的安全,实际上也可以指计算机通信网络…

同源策略简单解释

浏览器同源策略 什么时同源策略 协议、域名(IP)、端口相同即为同源。浏览器的同源策略是一种约定,是浏览器最核心也是最基本的安全功能,如果浏览器少了同源策略,则浏览器的正常功能可能都会受到影响。 http://192.168.200.131/user/1 https…

全景图!最近20年,自然语言处理领域的发展

夕小瑶科技说 原创 作者 | 小戏、Python 最近这几年,大家一起共同经历了 NLP(写一下全称,Natural Language Processing) 这一领域井喷式的发展,从 Word2Vec 到大量使用 RNN、LSTM,从 seq2seq 再到 Attenti…

【产品经理】高阶产品如何提出有效解决方案?(1方法论+2案例+1清单)

每一件事情总有它的解决方案,在工作中亦是如此,而有效的解决方案,一定是具有系统性的。 有效的解决方案,一定是系统性的解决方案。 什么是系统性解决方案? 从系统结构(或连接关系)入手&#x…

生成2×2 或3*3 混淆矩阵(confusion matrix)的python代码

该代码可以生成22的混淆矩阵。每个矩阵对应的数值可以自行改变。 代码如下: import numpy as np import matplotlib.pyplot as plt# 随机生成值 import numpy as np import matplotlib.pyplot as plt# 创建一个2x2的二分类数据矩阵。这里可以手动改变值 data np…

拨开迷雾:利用全链路消息跟踪揭示系统奥秘

在分布式系统,一次外部请求往往需要内部多个模块,多个中间件,多台机器的相互调用才能完成。在这一系列的调用中,可能有些是串行的,而有些是并行的,排查定位非常困难。 全链路消息分析及全链路消息跟踪可以帮…

C# 简单模拟 程序内部 消息订阅发布功能

文章目录 前言模拟消息订阅发布使用注意事项 前言 我想做个简单的消息发布订阅功能,但是发现好像没有现成的工具类。要么就是Mqtt这种消息订阅发布。但是我只想程序内部进行消息订阅发布,进行程序的解耦。那没办法了,只能自己上了 模拟消息…

yolo-v5学习(使用yolo-v5进行安全帽检测错误记录)

常见错误 跑YOLOv5遇到的问题_runtimeerror: a view of a leaf variable that requi_Pysonmi的博客-CSDN博客 python train.py --img 640 --batch 16 --epochs 10 --data ./data/custom_data.yaml --cfg ./models/custom_yolov5.yaml --weights ./weights/yolov5s.pt 1、梯度…

实例032 动画显示窗体

实例说明 当用户启动程序后,普通的程序窗口都是瞬间显示到屏幕上,这样未免有些生硬。如果窗口能够慢慢的展现在用户面前,将会是什么样的效果?本例设计的是一个动画显示的窗体,该程序运行后,窗体是慢慢的以…

小黑子—JavaWeb:第六章 - Filter、Listener、AJAX与JSON

JavaWeb入门6.0 1. Filter1.1 Filter快速入门1.2 Filter执行流程1.3 Filter拦截路径配置1.4 Filter过滤器链1.5 案例登录验证 2. Listener2.1 ServletContextListener使用 3. AJAX3.1 AJAX 快速入门3.2 案例 验证用户名是否存在3.3 Axios 异步框架3.3.1 Axios 快速入门3.3.2 Ax…