后端(四):博客系统项目

咱们在这里实现的是后端项目,前端代码就提一提,不全做重点介绍,在开始讲解这个博客系统项目之前,我们先看看这个项目的前端界面:

登录界面:

个人主页:

 博客详情页:

  写博客页:

 注销(回到登录页面):

编写博客系统后端操作

1. 准备工作

  1. 创建项目
  2. 引入依赖
  3. 创建必要目录

1. 创建项目

我们重新创建一个Maven项目,名叫blog_system

2. 引入依赖

我们该项目有几个必要的依赖,

  • 首先我们肯定是基于 Servlet 写代码的,所以 Servlet 一定需要引入。
  • 其次,我们这个项目不止有后端,还有前端,所以前后端之间会进行交互,其中后端要拿到前端传入的数据进行解析,这里解析就需要用到  jackson  (这个可以根据彼此之间的约定来确定究竟需要用到啥);我们这里约定就用 jackson  
  • 最后,我们最终的数据一定是保存在 数据库 中的,所以需要用到 JDBC ,我本机上用的又是 mysql 所以还需要引入 mysql 依赖。

我引入的版本如下:

3. 创建必要目录

上一章聊到的 web.xml 是每个项目都必须要用到的,这里再次提醒一下,随后就把我们前端的代码引入进来,如下图:

前端的代码放入在 webapp  目录之下就好。

具体的前端代码如下:

blog_system/src/main/webapp · wjm的码云/Projects

此外,我们在创建一个 sql 文件,该文件就存我们要对 数据库 初始化基本的操作;如建表,建库啥的。

2. 数据库设计

我们需要在这里 设计数据库结构,我们一共有几张表啊;每个表的数据是啥啊?

我们主要是针对需要储存的部分进行设计数据表。

其主要存储的就是 用户信息个人博客信息

用户信息

user:userId,username,password(还可以设置头像,用户的邮箱等等,这里设置的简单一点)

个人博客信息

blog:博客id,标题,正文,userId,发布时间

其中,具体的信息可以自己约定,这里为了方便,简单一点。

编写 数据库代码:

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

随便创建一个库,把字符集设置为 utf8 ,其次:

一般在创建表之前都会删一下,以防之前数据有残留,数据库一定是部署在一个新的机器上才会进行操作。

每次在新的机器上都需要操作一遍,故此我们将建好的数据库保存在.db文件下

3.  创建 博客类对象和 用户对象

我们先创建一个包,将数据库的封装和需要创建的实体类都存放在这里(包名可以随便起):

针对上述数据库设计的表,我们需要设计两个相对应的类。

一个叫做 Blog 类,一个叫做 User 类,分别对应 个人博客信息 用户信息

Blog 类

博客表的设计如下:

博客id,标题,正文,userId,发布时间

故此,我们类的设计也一样:

而后,加上 set 和 get 方法:

唯一一点需要注意的是:

User 类

用户表的设计如下:

user:userId,username,password

 步骤也和上面的 Blog 类一样:

4. 数据库的封装

这一步就是连接数据库:

我们在哪些地方可能会用到 数据库呢?

  • 把一个 Blog 对象插入到数据库中
  • 查询 blog 表中所有的博客数据
  • 指定一个博客id 来查询对应的博客
  • 指定 博客id 来删除博客
  • 通过用户id 来查询用户
  • 通过用户名来查询用户

我们将其分为两类,一个是 博客相关的,一个是与用户相关的

在做这两个类之前,我们还需要写一个JDBC,通过这个类,封装数据库的连接操作:

DBUtil

就是经典的连接数据的操作;我们这里将 DataSource 设置为单例的(这里可以设置为其他的):

省的每次都需要去重新连一遍,这里封装好,其他需要就直接调用就好了。

除了连接数据库,还必须带有关闭连接的方法,光连接不断开连接,会造成连接空耗,后面的连接又无法进来,这就造成了资源的极大浪费

所以,关闭连接是必须的:

 既然创建好了,就可以调用,所以还有一个 getConnection 方法:

具体的代码连接如下:

blog_system/src/main/java/module/DBUtil.java · wjm的码云/Projects - 码云 - 开源中国 (gitee.com)

UserDao

DAO全称Data Access Object,意思是数据访问对象.在java服务器开发的三层架构中分成控制层(Controller),表示层(service),数据访问层(dao),数据访问层专门负责跟数据库进行数据交互.

selectUserById:

selectUserByName:

 这个方法几乎和上述ById 一样,只是有微调

BlogDao

根据上述可能会用到的四种情况分别设计相应的方法:

  1.   把一个 Blog 对象插入到数据库中
  2.   查询 blog 表中所有的博客数据
  3.  指定一个博客 id 来查询对应的博客
  4.  指定博客id 来删除 博客

我们先来个最简单的删除操作;

删除

我们的大致思路就是根据 博客id 来删除某篇博客:

查询单篇博客

 大致思路就是:从数据库中根据这篇博客的 id 找到,在new 一个Blog 对象,将找到的数据都放到这个 Blog 对象上去,最后返回这个对象:

 找不到就返回 null;

查询所有博客

大致思路就是:按照时间的顺序,将博客呈现到页面上 

我们需要而外注意这一段:

这里给博客进行了一个截取 

如果是这种正文很短的那就不需要截取, 

类似于这种长的,不截取页面会一口气呈现出来。

这就和上面查询单片博客的操作类似。

插入

 就是个JDBC + sql 操作

 我们从上述多个方法中可以看到,JDBC 其实都不难,就是啰嗦, Connection 等 每个方法都要出现一次,这也是后面框架必学的原因,框架就很好的简化了这些步骤。

5. 前后端交互实现的逻辑

因为这一步开始编写后端代码了,所以我们在创建一个新的包,名字随便起,主要是和数据库 代码的以示区分

博客列表页

展示博客列表

1)约定前后端交互接口

 2)编写后端代码

 写一个 Servlet,主要是用来处理一类 HTTP 请求,加上 Servlet 都需要继承 HttpServlrt 父类,再加上一个 WebServlet 注解(描述了哪个路径和这个类相关)。

创建一个 Servlet 来处理相对应的请求

 我们当前的请求是这样的:

 可以通过修改id的请求来跳转页面

 不传入 id 就默认是加载所有的 博客。

 3)编写前端代码

构造 ajxa 请求,按照上述约定,发送 http 请求

 前端代码要做的事,就是根据咱们当前这个页面的结构构造出来的,页面是啥样,前端就怎么构造

前端部分可以不理解,我们重点还是在后端代码上。

登录功能

输入用户名 和 密码,点击登录就可以实现登录功能。

期望:点击登录之后,给后端发送一个http 请求,后端接收到请求以后,作出一些处理逻辑(包括验证用户名和密码啥的)

一般这一段的逻辑大部分都是进行 验伪 操作 。

1)约定前后端交互接口

2)编写后端代码

创建一个 Servlet 来处理 login 的请求

如果全段传过来的用户名带有中文,此时的代码拿到的 username 可能是乱码,需要提前设置一下编码方式:

 事实上,每个网站在处理验伪的过程中都不会告诉你具体是哪一块 出错了,而是直接给你返回一个用户名或密码错误,防止你猜对。

 当然啦,我们在编写后端,为了方便自己找 bug 还是可以以示区分的:

验证完用户名密码以后,我们将其保存在会话中,现在在很多大的电商平台等都是这么设置的,例如:淘宝。

我们在网页上浏览淘宝时都需要扫码登陆,着就是个会话,没有这个会话你就无法继续访问,于是他就会弹出一个对话框,必须登录...

我们这里也设置一个会话,让服务器保存当前用户的一些数据~

会话就可以理解为一个哈希表,灭个用户(每个客户端)都会对应到这个表里的一个键值对。其中键是一个字符串,sessionId(唯一的字符串),其中值是 HttpSession对象。

此后,我们其他的页面功能都需要添加一个验证 会话是否存在的功能,此功能不存在就回到登录页面,重新登录。

3)编写前端代码

此外,我们还需要编写判断登录的代码:

强制要求用户登录,检查用户的登录信息

我们在我们这项目中设定:

当用户访问 博客列表页、详情页、编辑页 的时候,必须要是登陆的状态,如果未登录就跳转到登录页面。

当用户访问 博客列表页、详情页、编辑页 的时候,发起一个 ajax 请求,用户获取当前的用户信息是否以登录。

1)约定前后端交互接口

2)编写后端代码

我们就写在 登录代码一起好了,反正都是两个方法,一个是 get 一个是 Post

3)编写前端代码

页面要通过 ajax 发起请求,获取登录状态信息

首次运行的时候,好像没有触发到这里的检查登录功能,大概率是浏览器缓存导致的,可以试着打开 Fiddler 并强制 刷新的时候,此时检查 登录 的功能就生效了。

因为我们在多个页面都用到了这个功能,所以我们可以单独写在一个 js 文件中,在需要到的页面调用一下即可。

 显示用户信息

1)约定前后端交互接口

在博客列表页,此处显示的是登录的用户的信息 :

在博客详情页,显示的是作者的信息 :

 在博客列表页中,要获取到登录用户 的信息,我们可以用上面 前端中 getLoginStatus 方法,让这个方法在登录成功之后就将 之前的用户信息给返回来。

2)编写后端代码

这里的代码就是上面 “会话” 代码的后半段:

当然,我这里只是返回了 用户名,至于其他的我这里暂时都没实现,后期空闲下来,我会继续完善这个博客系统(后期就不是在使用 Servlet 实现了,而是基于框架)。

3)编写前端代码

这个代码就是在 博客详情页代码中调用一下  getLoginStatus 方法就好。

博客详情页 

针对 博客详情页进行处理,详情页这里显示的是当前文章的作者信息,先根据 blogId ,查询到文章的对象,进一步拿到 作者 id,再根据 这个 id 查询作者名字,最终显示到页面上

1)约定前后端交互接口

 2)编写后端代码

我们新创建一个 Servlet 处理上述情况:

再获取信息的时候,我们绝大部分代码都在处理 验伪的操作:

用户退出功能(注销)

服务器收到这个 get请求,就可以把当前用户的 会话 中的 user 对象删除掉

 

1)约定前后端交互接口

2)编写后端代码

实现发布博客

此后,服务器就可以保存上述数据到数据库中,接下来后续就可以在博客列表页和博客详情页中看到 刚才的新博客

 1)约定前后端交互接口

  2)编写后端代码

 从请求中拿到标题和正文,从会话中拿到用户的登录信息和登录状态(作者id),并且获取到时间

前端代码这里就不展示了。

到这一个功能实现上述基本的功能就都实现了。

完整的代码我放在了我的码云下:

blog_system · wjm的码云/Projects - 码云 - 开源中国 (gitee.com)

我这个项目内置了一个 md 编辑器 ;  editor.md 这个包下的东西可以去下载:

链接:https://pan.baidu.com/s/1I3Kh2X0Xp1sygRU69qkRCg 
提取码:1234

直接将它拖入 你的idea 即可。

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

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

相关文章

再见 Spring Boot 1.X ,Spring Boot 2.X 走向舞台中心

2019年8月6日,Spring 官方在其博客宣布,Spring Boot 1.x 停止维护,Spring Boot 1.x 生命周期正式结束。 其实早在2018年7月30号,Spring 官方就已经在博客进行过预告,Spring Boot 1.X 将维护到2019年8月1日。 1.5.x 将会…

【Java】重写compareTo()方法给对象数组排序

我们先给一个数组排序,我们肯定用的是Arrays.sort()方法: public class test2 {public static void main(String[] args) {int[] arr{3,5,4,6,9,8,1};System.out.println(Arrays.toString(arr));System.out.println("---------");Arrays.sort…

【C语言初阶】指针的运算or数组与指针的关系你了解吗?

🎬 鸽芷咕:个人主页 🔥 个人专栏:《快速入门C语言》《C语言初阶篇》 ⛺️生活的理想,就是为了理想的生活! 文章目录 📋 前言💬 指针运算💭 指针-整数💭 指针-指针💭 指针…

【Java基础教程】(四十二)多线程篇 · 上:多进程与多线程、并发与并行的关系,多线程的实现方式、线程流转状态、常用操作方法解析~

Java基础教程之多线程 上 🔹本节学习目标1️⃣ 线程与进程🔍关于多进程、多线程、并发与并行之间的概念关系? 2️⃣ 多线程实现2.1 继承 Thread 类2.2 实现 Runnable 接口2.3 多线程两种实现方式的区别2.4 利用 Callable 接口实现多线程2.5 …

数学建模学习(4):TOPSIS 综合评价模型及编程实战

一、数据总览 需求:我们需要对各个银行进行评价,A-G为银行的各个指标,下面是银行的数据: 二、代码逐行实现 清空代码和变量的指令 clear;clc; 层次分析法 每一行代表一个对象的指标评分 p [8,7,6,8;7,8,8,7];%每一行代表一个…

为Android构建现代应用——设计原则

为Android构建现代应用——设计原则 - 掘金 state”是声明性观点的核心 在通过Compose或SwiftUI等框架设计声明性视图时,我们必须明确的第一个范式是State(状态)。UI组件结合了它的图形表示(View)和它的State(状态)。UI组件中发生变化的任何属性或数据都可以…

RuoYi-VUE : make sure to provide the “name“ option

前言 略 错误 错误原因 theme-picker 组件未被注册。 解决 src/App.vue代码恢复成若依的代码即可。&#xff08;PS&#xff1a;不知道代码被谁修改了&#xff09; 缺少这一段&#xff1a; <script> import ThemePicker from "/components/ThemePicker";…

hive基础

目录 DDL&#xff08;data definition language&#xff09; 创建数据库 创建表 hive中数据类型 create table as select建表 create table like语法 修改表名 修改列 更新列 替换列 清空表 关系运算符 聚合函数 字符串函数 substring:截取字符串 replace :替换…

C进阶:内存操作函数

内存操作函数 memcpy 头文件&#xff1a;string.h 基本用途&#xff1a;进行不相关&#xff08;不重叠的内存&#xff09;拷贝。 函数原型&#xff1a;void* memcpy(void* destination,//指向目标数据的指针 const void* source,//指向被拷贝数据的指针 size_t num);//拷贝的数…

分布式光伏电站监控及集中运维管理-安科瑞黄安南

前言&#xff1a;今年以来&#xff0c;在政策利好推动下光伏、风力发电、电化学储能及抽水蓄能等新能源行业发展迅速&#xff0c;装机容量均大幅度增长&#xff0c;新能源发电已经成为新型电力系统重要的组成部分&#xff0c;同时这也导致新型电力系统比传统的电力系统更为复杂…

【数据挖掘】时间序列的傅里叶变换:用numpy解释的快速卷积

一、说明 本篇告诉大家一个高级数学模型&#xff0c;即傅里叶模型的使用&#xff1b; 当今&#xff0c;傅里叶变换及其所有变体构成了我们现代世界的基础&#xff0c;为压缩、通信、图像处理等技术提供了动力。我们从根源上理解&#xff0c;从根本上应用&#xff0c;这是值得付…

HTML5——基础知识及使用

HTML 文件基本结构 <html><head><title>第一个页面</title></head><body>hello world</body> </html> html 标签是整个 html 文件的根标签(最顶层标签).head 标签中写页面的属性.body 标签中写的是页面上显示的内容.title 标…

实现外部缓存-Redis

目录 实现 RedisTemplate RedisTemplate的序列化 RedisSerializer 创建Redis缓存配置类 测试使用 创建配置类 创建注解测试实体 创建配置文件 创建单元测试类进行测试 实现 RedisTemplate XXXTemplate 是 Spring 的一大设计特色&#xff0c;其中&#xff0c;RedisTe…

Mybatis操作数据库执行流程的先后顺序是怎样的?

MyBatis是一个支持普通SQL查询、存储及高级映射的持久层框架&#xff0c;它几乎消除了JDBC的冗余代码。使Java开发人员可以使用面向对象的编程思想来操作数据库。对于MyBatis的工作原理和操作流程的理解&#xff0c;我们先来看下面的工作流程图。 MaBatis的工作流程 在上图中…

element的el-upload实现多个图片上传以及预览与删除

<el-form-itemlabel"实验室照片:"prop"labUrlList"v-if"ruleForm.labHave"><el-upload:action"urlUpload":headers"loadHeader"list-type"picture-card":file-list"ruleForm.labUrlList"class…

【el-tree查询并高亮】vue使用el-tree组件,搜索展开并选中对应节点,高亮搜索的关键字,过滤后高亮关键字,两种方法

第一种&#xff08;直接展开并高亮关键字&#xff09; 效果图这样的&#xff0c;会把所有的有这些关键字的节点都展开 代码&#xff1a; 这里的逻辑就是通过递归循环把所有和关键字匹配的节点筛选出来 然后通过setCheckedKeys方法把他展开选中 然后通过filterReal把关键字高亮…

数据库redis作业

数据库redis作业 redis9种数据类型的基本操作 redis持久化&#xff1a;分别启用rdb和aof&#xff0c;并查看是否有对应文件生成 作业1&#xff1a;redis9种数据类型的基本操作 1、key操作 key * #查询所有的key keys *exists 参数 #参数&#xff1a;key #判断该key是否存…

【ADS】ADS复制原理图或版图到另一个工程

直接Ctrl CCtrl V无法粘贴 可以先导入要复制的工程 加入工程&#xff0c;复制完后在勾掉工程

单独在文件中打开allure生成的index.html报告时却显示为loading

【问题描述】&#xff1a;单独在文件中打开allure生成的index.html报告时显示为loading&#xff0c;如下图&#xff1a; 【问题定位】&#xff1a;其实在allure-report下index.html文件是不能直接打开的&#xff0c;出现页面都是loading的情况&#xff0c;这是因为直接allure报…

Rust 数据类型 之 类C枚举 c-like enum

目录 枚举类型 enum 定义和声明 例1&#xff1a;Color 枚举 例2&#xff1a;Direction 枚举 例3&#xff1a;Weekday 枚举 类C枚举 C-like 打印输出 强制转成整数 例1&#xff1a;Weekday 枚举 例2&#xff1a;HttpStatus 枚举 例3&#xff1a;Color 枚举 模式匹配…