莫张周刘王 发表于 2024-7-11 04:53:56

个人博客系统(前后端分离)

努力经营当下,直至将来明朗!


平凡小孩也要热爱生活!
一、项目简介

个人博客系统采用前后端分离的方法来实现,同时使用了数据库来存储相关的数据,同时使用tomcat进行项目的部署。前端主要有四个页面构成:登录页、列表页、详情页以及编辑页,以上模拟实现了最简单个博客列表页面。其结合后端实现了以下的主要功能:登录、编辑博客、注销、删除博客、以及强制登录等功能。
但是该项目没有设计用户注册功能,只能提前在数据库中存储用户信息后经过校验登录;而且用户头像不能自己设定,在进行前端页面的书写过程中已经将头像的图片写为静态了;而用户信息中的文章数以及分类数也没有在后端中详细实现,直接在前端页面中写为了静态的。
二、项目结果

必须在开着tomcat的情况下才气进行以下页面的操纵。

[*] 登录页面
https://img-blog.csdnimg.cn/b4af0217fa4143c796bd52c02ba4f7b3.png
[*] 列表页面 / 主页
https://img-blog.csdnimg.cn/88ea917518cf4c59ac15de9ce481009a.png
[*] 博客详情页
https://img-blog.csdnimg.cn/c08e7614ad1b4ae6a4d41d54b561ac63.png
[*] 编辑页
https://img-blog.csdnimg.cn/f24910648fec432abf7dd31d3dd5c51c.png
三、项目实现

1. 软件开发的基本流程

① 可行性分析;
② 需求分析:明确程序要解决什么问题,做成啥样,都有啥功能。(实际开发中是产物司理制定的)
③ 概要设计
④ 详细设计
⑤ 编码
⑥ 测试
⑦ 发布
2. 博客系统 需求分析

① 实现博客列表页的展示功能
② 实现博客详情页的表现功能
③ 登录功能(临时不实现注册)
④ 限定用户权限(强制要求登录)
⑤ 表现用户信息
⑥ 实现注销(退出登录)
⑦ 发布博客
⑧ 删除博客
3. 博客系统 概要设计

   (写代码要“谋定而后动”)
实在这里主要是【数据库设计】
当前我们的业务比较简单,只必要两个表:
   ① 博客表blog(blogId,title,content,postTime,userId)
② 用户表user(userId,userName,password) (其中Gitee地址以及文章分类如许的功能先不考虑)
4. 创建maven项目

   注:① auto-increment是从1开始的
② text的大小是64kb,博客内容一样平常不太会凌驾64kb,而博客中的截图不是和文本一起存储的。
5. 编写数据库操纵的代码


[*]引入依靠:servlet3.1.0、mysql5.1.49、jackson2.13.4.1
[*]封装数据库的DataSource(单例模式+线程安全)
除了封装DataSource,把数据库的创建连接、断开连接也都进行封装。
   补:
① ctrl+alt+t:surround功能
② Connection是 java.sql.Connection,不是 java.mysql.Connection

[*]在关闭释放资源的时候,写法一是将三个必要释放的连接分别try…catch, 写法二是三个必要释放的连接只使用 一个try…catch连接。
   写法一更好。
理由:写法一里如果某个环节抛出非常,不影响继续执行后续的close操纵。而写法二一旦出现非常就会进入catch,此时后续的close就执行不到了,会造成资源泄漏。
(直接抛出非常throws也是同理写法二,会造成资源泄漏。)

[*]根据需求创建实体类
一个实体类对象就对应表里的一条记录。
   实体类怎么写?
——表结构怎么写,实体类就怎么写。
    mysql中的datetime和timestamp类型都是在java中使用TimeStamp表示的。

[*]针对上述实体类涉及到的 增删改查 进行进一步的封装,也就是把jdbc代码封装一下。
Dao: Data Access Object
访问数据库的操纵就可以使用这几个Dao对象来进行。
   statement.executeUpdate(); 返回的数据表示影响到几行
6. 进行前后端交互(重点)

让页面发起http哀求,服务器返回http相应。(必要约定好http哀求是啥样的,相应是啥样的)
1)博客列表页:
① 不要写死数据,而是让页面从数据库中获取到当前的博客列表。
   (先将前端的全部相关文件粘贴到webapp目录下)
② 页面在加载的时候,通过ajax发起http哀求,从服务器获取到博客列表数据。
https://img-blog.csdnimg.cn/b6a539cfb3c64d799a2995354946a37a.png
③ 当web出现问题的时候,起首想到的就是“抓包”,看是前端原因还是后端原因。(如果有的没有抓取到就进行强制刷新ctrl+f5)
   注:fiddler中出现的favicon是欣赏器发送的哀求,是获取页面图标的,如果该网站没有图标就会出现404
https://img-blog.csdnimg.cn/f5726e448938446995ab97d090b44553.png
    ① 在前后端分离的程序中,获取页面和获取页面中的数据是分开的哀求。
② 如果是只有页面没有数据,且抓包也抓不到获取数据的哀求,那就说明是前端代码出问题了,前端没有正确发送ajax哀求。
注:方法只有被调用之后才会生效!!
一定要细致!!保证不会出现空指针非常!!
问题以及解决:
① 我们想要呈现的是格式化的时间,但是会发现此时出现的是时间戳!
https://img-blog.csdnimg.cn/6901fcfd21854fa8947864889a8b919c.png
原因:
   通过抓包检察发现服务器返回的相应数据就是一个时间戳
https://img-blog.csdnimg.cn/a3f08ec46dee42b5bc37053dd20d9428.png
服务器代码中,是将从mysql数据库中查询到的时间放到了postTime这个属性中,然后又通过jackson将其转为json字符串返回;即:在转json的过程中,将其变为了时间戳。
https://img-blog.csdnimg.cn/ff4b6548e2264b738309c742f4b8d792.png
解决方法:
   那么jackson是怎样获取到Blog对象中的时间戳的? 通过getter方法来获取的。
https://img-blog.csdnimg.cn/04a54d2f190c4fbeb376102f27e9414d.png
所以就魔改getter方法,让该方法返回一个String,而不是TimeStamp。String就是一个格式化好了的时间日期!
https://img-blog.csdnimg.cn/5470fb1520934209bdc485f04f751e75.png
    ① 这个SimpleDateFormat类可以将时间戳转为格式化的时间!
(使用示例可以参考:SimpleDateFormat类使用)
https://img-blog.csdnimg.cn/d5af25cdbf0e4c5cb5dad5c320ec1b21.png
② 必要把时间戳转成格式化时间,详细啥格式必要在构造方法中进行指定!
③ (参数格式可以自己指定,但是详细字母时不能改变的,每个都有自己的寄义,如MM表示月份,mm表示分钟,详细的参数寄义在使用的时候自己上网确认!)
    https://img-blog.csdnimg.cn/0dbc5eca12754ee7968fb43d5a972049.png
(格式化时间日期)
② 另外,又发现问题:列表中的文章顺序应该是最近发布的在最上面,但是如今是按先发布排上面的顺序来分列的。
https://img-blog.csdnimg.cn/80f6a4013c6c4adeb670e832ff2cedea.png
所以,解决方法:在查询的时候加上个排序。
https://img-blog.csdnimg.cn/1a2b80b7840f44bd8996e733ded508d2.png
③ 此时,如果插入的博客内容比较长的话就会占据很大篇幅的列表页,因为把整个正文篇幅都表现出来了;但是按理来说,博客列表页要表现的是正文的 “摘要”信息。
   https://img-blog.csdnimg.cn/25e76f4c50234f8fa58a70301427d5e2.png
(长文)
解决方法:
针对博客的列表页中的内容进行截断,长度到达一定数值就取出一部分子串。(长度自己规定就ok)
https://img-blog.csdnimg.cn/51e7956178ec479c9218820ac7ebedb3.png
   https://img-blog.csdnimg.cn/4328ec522f82491ca7a0ef619f469a9c.png
(结果)
【注】当我们的程序出现了问题,该怎样动手解决?
   ① 一定要梳理清楚出现问题的代码的流程
② 可以或许找到相关代码 (调试,不是对照着找!!)
2)实现博客详情页
① 点击检察全文就会跳转到详情页,而且看到详情页中对应的博客正文。
② 处理方式:
点击检察全文,此时就会发起一个get哀求,该哀求是在哀求blog_detail.html这个页面;此时还必要告诉服务器我们哀求的是哪个博客!
约定:在哀求页url中加上query string来进行详细哪个博客的标识。(在生成“检察全文”按钮的时候就已经添加了query string进行标识了)
https://img-blog.csdnimg.cn/9e21ff81a8d64c4c82695b35e3f1423a.png
③ 进入博客详情页之后,必要让博客详情页再次发起ajax哀求,向服务器获取到当前blogId对应的博客内容;再由博客详情页将拿到的数据添加到欣赏器页面上。
④ 操纵步调:
1)约定前后端交互接口
在博客详情页中发起ajax哀求,获取到详细的博客内容。
https://img-blog.csdnimg.cn/883ca085b76d423a92c1cd0d5d66594c.png
2)实现服务器代码
按照上述约定来返回数据
3)实现客户端代码
让页面发起的ajax哀求来获取到博客数据
【注】location.search 用来获取query string
https://img-blog.csdnimg.cn/f0d401339b4d437397806f196466de79.png
   (每次修改代码都要重启服务器)
但是会发现当点击“检察全文”后,所跳转的页面还是之前的结果,这是触发了欣赏器的缓存!
   ① 理由:
欣赏器必要通过网络从远程服务器获取到当前的页面数据,可能比较耗时;此时为了提高服从,做法就是让欣赏器把须要的数据进行缓存;下次访问就不必访问网络了,而是直接读取缓存。
② 做法:
所以,为了保证数据从网络上获取就必要进行强制刷新ctrl+f5.
如果发现前端页面有问题,就fn+f12调出控制台检察非常情况。
   补充:
① VS里的编译器是cl.exe, IDEA的编译器是javac… 编译器一样平常都是命令行的。
②IDE是集成开发环境, IDE != IDEA
问题:
   ① 博客正文期待是markdown格式的(毕竟博客编辑页是一个markdown编辑器,提交的数据是markdown格式的,数据库中存储的也是markdown格式的,所以终极表现也应该是markdown格式的结果)
https://img-blog.csdnimg.cn/842ecb9e2f2849cdaf9e7282acdc83e3.png
② 表现结果是纯文本(不符合预期,预期是渲染过的markdown)
https://img-blog.csdnimg.cn/3086de9a21fe4be88fc44bc907bcd1fa.png
解决方法:
使用editor.md这个库来完成渲染。
在blog_detail.html中引入editor.md依靠
https://img-blog.csdnimg.cn/e195e4e28e0142d49a9823f2ba1d5aaa.png
https://img-blog.csdnimg.cn/3afd9cfed7764b27957b3cb863af7c94.png
   https://img-blog.csdnimg.cn/6ea32d386a27405fad9ee7574d784a7c.png
(渲染之后)
如果想要内容的配景表现半透明结果,修改设置一下就ok。
   https://img-blog.csdnimg.cn/e13758773c8b4655ae85af70b0c3bb51.png
(这个结果欠好)
    https://img-blog.csdnimg.cn/27ea89ff80e64a0b84de463ca20d2c10.png
(transparent的意思就是让当前元素完全应用父元素的配景)
3)博客登录
登录逻辑:
   ① 用户访问login.html,输入用户名和暗码
② 点击登录按钮后发起一个哀求,将用户名和暗码提交给服务器
③ 服务器对身份进行验证,验证成功就跳转到博客详情页
① 约定前后端接口
https://img-blog.csdnimg.cn/2a6cd5de3e8e40e8adf8a27338365d12.png
(注:哀求再前端,相应在后端)
② 编写前端代码
   https://img-blog.csdnimg.cn/f289a697ff854f739e218b64b42869ab.png
一定要指定name属性,为了与键值对中的键对应!
https://img-blog.csdnimg.cn/fc47f87f04594c60ad7efe0096661508.png
③ 编写后端代码
LoginServlet
4)实如今博客列表页、详情页和编辑页中强制登录后才气访问。(常见)
业务逻辑:
   在博客列表页、详情页和编辑页中,都在页面加载时发起一个ajax哀求,这个ajax哀求就是从服务器获取当前的登录状态。如果当前是未登录就直接重定向到登录页面,如果是已经登录则不做任那边理。
① 前后端交互接口:
https://img-blog.csdnimg.cn/84596bce288744d08cd6df659f24b8de.png
② 前端代码:判定状态码是200还是403,如果是200就无事发生,403就强行跳转
https://img-blog.csdnimg.cn/5eefd2d3a2a546218ae0dcb317b5757a.png
③ 后端代码:
只是单纯的检察当前用户是否为登录状态,即:获取会话以及里面的user对象,如果能拿到就已经登录过返回200,否则返回403.
https://img-blog.csdnimg.cn/284cf6ce416641d9abda0250b655e2ba.png
   因为 登录限定及跳转 在很多页面中都使用,但是我们没须要进行重复性的工作,所以直接在前端代码中新建一个文件夹js,并新建文件 app.js 来存储这些重复的代码,以此来实现代码的复用。
5)在列表页和详情页中动态表现用户信息
逻辑设定:
   ① 博客列表页:在页面进行加载的同时从服务器获取当前登录的用户信息,并把该信息表现到页面上。
② 博客详情页:在页面进行加载的同时从服务器获取博客作者用户信息,并把该信息表现到页面上。
① 前后端交互接口:
https://img-blog.csdnimg.cn/c251f931e16c4a588a791946b41489f3.png
② 编写后端代码
   https://img-blog.csdnimg.cn/b9048d303e834732889780f363418796.png
(使用了两次sql查询,实在是可以使用一条sql搞定的:联合查询 or 子查询)
③ 编写前端代码
https://img-blog.csdnimg.cn/a7d77eaa94204f7592b6d41a713a154d.png
【小结】写web程序套路
实在以上实现的功能所做的事情都差不多:
   ① 业务逻辑梳理
② 设计前后端交互
③ 编写前端代码:基本上是ajax(发哀求)+ dom(根据哀求表现到页面上)操纵
④ 写后端代码:基本上就是servlet + jdbc + jackson操纵
(前后端编写代码顺序不定)
    补充:
① 图片存入数据库实在存的是图片的路径,而图片是以文件的形式存到硬盘上。
② 不太发起将图片直接存入数据库,图片是二进制数据,对于关系型数据库是不太友好的。
6)注销(退出登录状态)
Windows的注销实在也就是退出登录状态sign out。
业务逻辑:
   ① 在博客列表页/详情页/编辑页的导航栏里都有 注销 按钮,而且我们的实现方式是一个a标签,点击的时候就会给服务器发送一个http哀求(不是ajax,但是如果想要使用ajax做也是OK的)
② 发送的http哀求就是告诉服务器咱们要退出登录了,服务器就会把对话中的user对象给删除,同时重定向到登录页。
③ 注:删除的是会话中的user对象而不是HttpSession对象,因为HttpSession没有一个直接用于删除的方法(Servlet没有提供),虽然可以通过设置逾期时间的方式来删除会话,但是并不是一个好的选择;另外,我们在实现判定登录状态的条件是HttpSession存在&&user存在,所以这里可以直接删除user对象
① 前后端交互接口
https://img-blog.csdnimg.cn/f5c013397bbb4a939fefa4fa1d51cf6f.png
② 前端代码
只必要给a标签的href属性设置个值就行,不必要写任何的js代码。
后端代码:
LogoutServlet
7)发布博客
业务逻辑:
   在博客编辑页中获取到用户提交的数据并生存到数据库中。用户在博客编辑页中会填写标题和正文,在点击“发布文章”后发起一个http哀求,然后服务器收到这些数据后构造一个Blog对象并插入数据库。
    Blog对象:
https://img-blog.csdnimg.cn/8ae2f11d99ab4d1bb45d168e0f9e0048.png
① blogId自动生成
②title和content是用户提交的内容
③ postTime直接就是插入数据库的时间,不消手动指定,即:now()
④ userId:发布文章的时候登陆的用户就是作者,登陆的用户的信息是在HttpSession中的。
① 前后端交互接口:
https://img-blog.csdnimg.cn/539b207b3c7541d3a10a0d3712203bca.png
② 实现服务器代码(相应)
【补充】
正常情况下,可以或许发起POST /blog哀求应该是在已经登录状态下了,那为何还要再次查验是否是已经登录状态呢?
理由:
   ① 万一有手动构造呢?如使用postman直接构造哀求,此时就绕开了登录直接插入博客数据了。
② 构造博客对象是必要知道userId的,此时只有知道了谁在登录才气够知道文章作者(userId)。而该userId就来自与HttpSession对象getAttribute。
③ 前端代码(客户端代码)的实现:
(也不涉及js的编码)
   https://img-blog.csdnimg.cn/5ec4423e07984b3f98733c4b27300099.png
① 当写上< textarea name=”content” style=”display:none”> < /textarea>的时候,用户在页面上输入的markdow内容就可以或许被textarea自动获取到;但是必要给初始化editor.md时加上一个新的属性:saveHTMLtoTextarea: true
https://img-blog.csdnimg.cn/83bbdeec38344f12a37fda0c0c6add56.png
② 此时发现一个问题:Markdown编辑器页面大小缩水了
https://img-blog.csdnimg.cn/1ae5571122d54c0688b510d28a03b333.png
这显然是前端样式的问题,所以去检察前端样式(fn+f12)
https://img-blog.csdnimg.cn/b4c141ce083e480283c404b26934c3fb.png
(发现blog-edit-container正常,但是form那儿就缩水了)
③ 也就是说:form标签没有指定高度,此时自身就缩水,导致内部的子元素也就缩水了。
解决方法:给form指定高度,和父元素一样高就行。
https://img-blog.csdnimg.cn/0923e9d3410b4f57b38499fe24fb759b.png
https://img-blog.csdnimg.cn/9d52d300cc0c4c079837508456163963.png
8)删除博客
业务逻辑:
   ① 作者只能能删除自己的文章,不能删除别人的文章。
② 临时没有管理员这个脚色
③ 在博客详情页导航栏加上 删除按钮,当点击该按钮的时候就会触发删除操纵。是通过a标签href属性发起的一个HTTP GET哀求。
④ 删除的时候会进行校验:如果当前登录的用户就是文章作者才气够真正删除,否则就提示没有删除权限。
① 前后端交互接口:
https://img-blog.csdnimg.cn/e9d11862a7ab4c2aa90399a17fbb5e9e.png
② 实现服务器(后端代码):
大部分代码都是在判定非法情况,这是一个很好的意识。
③ 实现欣赏器(前端)代码:
   ① 直接加个a标签
https://img-blog.csdnimg.cn/618277b9101b48e48ade3abf67890b97.png
② 但是会发现:点击删除的时候url中是没有带上blogId的,这就导致无法删除。
③ 所以:可以在页面加载的时候通过js代码稍微修改一下href属性中的内容,使url中带上blogId。
https://img-blog.csdnimg.cn/c8fd989a545a4a14917905b5f03ae85d.png
https://img-blog.csdnimg.cn/047ab0ebf68e41c7827e5d5b4871f37c.png
③ 注意区分:location.href(完整路径) 和 location.seach(query string)
https://img-blog.csdnimg.cn/be40cccdcc6640af9dbd8d33b6c4e16f.png
    location是dom api中自带的全局对象(js中的全局对象)
四、项目代码


[*] 环境:
IDEA + MySQL + smart tomcat + VSCode
[*] 项目布局
https://img-blog.csdnimg.cn/b0e89d0b4a12491cb908216ed4daa763.png
[*] 项目代码:
Gitee链接:个人博客系统
总结


[*]在实现简单个人博客系统的过程中碰到了很多问题,其中的 前后端交互接口的约定 极其重要!!
[*]只有不断重复、多练习才气更好地理解项目以及实在现。
https://img-blog.csdnimg.cn/bff6315bbc3d46209f934a225d838845.png
   有任何发起以及问题可以 直接私信 或 直接评论 嗷!
欢迎小窗踢踢! or 评论区见!

免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。
页: [1]
查看完整版本: 个人博客系统(前后端分离)