【Java EE】-博客系统二(前后端分离)

news2024/9/21 18:39:47

作者:学Java的冬瓜
博客主页:☀冬瓜的主页🌙
专栏:【JavaEE】
分享:
徘徊着的 在路上的 你要走吗
易碎的 骄傲着
那也曾是我的模样
——《平凡之路》

主要内容:显示用户信息、上传头像、新增博客、删除博客、修改博客。

在这里插入图片描述

文章目录

    • 一、显示用户信息
      • 1)列表页显示登录用户信息
      • 2)详情页显示博客作者信息
    • 二、上传头像
      • 1)上传头像
      • 2)显示头像
        • 1> 列表页显示登录用户头像
        • 2> 详情页显示博客作者头像
        • 3> 简述修改geet地址统计博客数量及博客分类
    • 三、新增博客
    • 四、显示删除和编辑按钮
    • 五、删除博客
    • 六、修改博客

一、显示用户信息

分两个子功能:列表页显示登录用户信息;详情页显示博客作者信息。

1)列表页显示登录用户信息

1>约定前后端交互接口
在这里插入图片描述

2>编写前端代码

理解:在blog_list.html中,在写验证登陆时,就把user作为json格式的字符串响应给前端,在这里前端只需要新增一点东西,即验证登录成功后,取出username显示在页面上。
在这里插入图片描述

3>编写后端代码

理解:在loginServlet的doGet方法中,在写验证登陆时,就把user作为json格式的字符串响应给前端,和其他地方的验证登录一样,如果未登录(session为null,或session中没有当前用户的会话),则返回一个userId为null的user对象。如果已经登录,那么就根据userId查询数据库,再响应从数据库中根据userId查出来的user给前端。

2)详情页显示博客作者信息

1>约定前后端交互接口

理解:从博客列表页跳转到博客详情页时,带了博客的id,在发ajax请求时,把博客id带上,到后端去查询该篇博客对应的用户id,再查出该用户写回给前端。
在这里插入图片描述

2>编写前端代码
在blog_detail.html中:
在这里插入图片描述
3>编写后端代码
在AuthorServlet的get方法中:
在这里插入图片描述

二、上传头像

分两个子功能:上传头像、显示头像。

1)上传头像

思路:前端使用file控件将文件上传后,后端需要读取这个上传的文件并把它保存在另外一个路径下,并且得保证这个路径是唯一的(所以用uuid作为另存的文件名),然后需要把路径保存在当前修改头像对应的用户在数据库的用户信息。

1>约定前后端交互接口
在这里插入图片描述

在这里插入图片描述
multipart/form-data请求体格式:
在这里插入图片描述

2>编写前端代码

理解:在card_upload.html页面中,提交POST请求,并给上传的标签input文件加上name属性便于后端使用getPart()方法获取上传的文件。
在这里插入图片描述

3>编写后端代码

在LoadCardServlet的doPost方法中,使用req.getPart()获取上传的文件,然后再获取上传文件的流。生成uuid作为另存文件名(保证文件的唯一,保证多用户同时修改头像不出问题)。
1>并另存该上传文件在web项目中,路径为:路径:/static/upload/uuid.png
2>然后根据session中的会话取出当前登录用户,并把uuid.png保存在数据库对应的用户的信息中。
3>写一个a标签,用于头像上传成功后,跳转到博客列表页面。
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

2)显示头像

思路:使用GET方法,请求获取头像。从数据库中查出这个唯一的路径,并响应给前端(可以使用静态资源配置,我弄了半天没弄出来,等以后有机会再弄),前端将这个路径作为相对路径解析,补全网络路径,去除字符串拼接引号带来的影响。最后将这个路径赋值给对应头像位置img的src属性。

1> 列表页显示登录用户头像

1>约定前后端交互接口
在这里插入图片描述

2>编写前端代码

在blog_list.html页面中,在写验证登陆时,就把user作为json格式的字符串响应给前端blog_list.html,在前端blog_list.html,显示用户名时,只需要新增一处,即验证登录成功后,取出username显示在页面上。在这里插入图片描述
同时验证登陆成功后,如果此时登陆用户的headpPath为null,则直接返回,即:使用默认的头像。如果此时headPath不为null,那么发送请求获取头像,如下图:在这里插入图片描述
后端给响应结果路径:/uploads/uuid.png,在前端这里补满路径,再给img的src赋值,自动获取图像。

3>编写后端代码

通过blog_list.html的获取头像的请求,来到了LoadCardServlet的doGet方法中,(前端传输的地址栏上没有blogId)在这里获取当前登录的用户id,根据当前登录的id去查询数据库,查出uuid.png,并把/uploads加在这个文件名前。写回给前端。
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

问题:这里如果直接从session中取出登录用户,然后直接取出headPath行不行?
理解:不行!因为登陆时,session创建并把我的登录信息保存在session中,但是在这之后我修改了头像,那如果我直接从session里的用户的headPath取出,这个headPath是我头像修改前的路径,就出问题了!
同时因为这里获取用户头像的请求是在checkLogin()方法的检验登陆的回调函数中发起的,所以发起检验请求时,在LoginServlet类中,如果检验登录通过,应当从数据库查出该user,再返回给前端,确保发起获取头像请求的条件成立(即检验请求的响应是user,user的头像路径属性不为null)。在这里插入图片描述

2> 详情页显示博客作者头像

1>约定前后端交互接口
在这里插入图片描述
2>编写前端代码

理解:在blog_detail.html页面中,在发起检查当前状态是否登录的回调函数中,如果返回的user的userId=0,那么当前未登录,需要强制跳转到登陆页面。如果user的的属性headPath为null,那么只需要修改用户名,不需要修改头像。如果user的属性headPath不为null,那就再发起一个获取头像的请求,该请求带上该篇博客blogId以便后端查询到该篇博客对应的作者。回调函数返回/uploads/uuid.png,把它补全为一个网路路径,再赋值给img的src,就可以获取头像。
在这里插入图片描述
在这里插入图片描述在这里插入图片描述

3>编写后端代码
通过前端的请求,来到了LoadCardServlet的doGet方法中,先判断blogId是否为null,为null代表是博客列表页发起的获取头像请求,不为null,则代表是博客详情页发起的获取头像请求,需要通过博客id查数据库找到该篇博客blog,再通过该篇博客的userId属性找到对应作者user,再把对应作者的属性headPath(uuid.png)前加上/uploads/响应给前端。
在这里插入图片描述

在这里插入图片描述

3> 简述修改geet地址统计博客数量及博客分类

补充:个人信息的小卡片:
在这里插入图片描述

  • 注:在小卡片上,还有gitee地址,文章数量,文章分类。修改gitee功能就是修改路径,然后个人文章数量和博客类型,可以由以下思路去实现。
    统计博客数量:后端提供一个查询当前用户的博客数据统计的接口,从数据库blog表查询出来当前用户的博客数量,显示在前端页面上。
    博客分类:再使用一张表flg(类型表),这张表中的类型和博客的关系是多对多关系。需要使用另一张表设置blog表和flag表的外键,来建立相互之间的联系。

三、新增博客

说明:除了登录、注册页面,其他页面(要求强制登录才可访问博客系统),都可以点击导航栏上的写博客,跳转到写博客的页面。
一篇博客,内容包含博客Id,标题title,正文content,发布时间postTime,作者id。在这里博客id可以设置主键自增,发布时间和作者id都可以在后台设置,因此前端只需要输入标题title和正文content即可。

1>约定前后端交互接口
在这里插入图片描述

2>编写前端代码

理解:在blog_edit.html页面中,需要对markdown编辑器进行初始化,调用editormd()方法可完成初始化。点击发布文章,就把title和content提交到后端。
在这里插入图片描述
在这里插入图片描述

3>编写后端代码

理解:点击发表文章,就把title和content发送到了BlogServlet的doPost()方法中。在BlogServlet的doPost()方法中,获取文章标题和正文(主要:获取前先把req的字符集设置成utf8,防止乱码问题),并获取登录会话从而获取到当前登录的userId,同时new TimeStamp()参数是当前时间戳生成时间。然后将title,content,postTime,userId装入一个Blog对象中,再进行数据库插入博客操作。插入成功后,重定向到博客列表页面,列表页面自己再发送ajax请求获取当前博客列表数据,这篇博客就展示到列表页面了。
在这里插入图片描述
在这里插入图片描述

四、显示删除和编辑按钮

说明:
1> 对于博客的删除和编辑来说,都应该是博客作者才有的权限,非作者只能浏览博客。因此这个功能就是为了实现这而写的,具体为:如果当前登录用户和博客作者是一个人,就在前端给出删除和编辑按钮,否则没有这两个按钮。
2> 因为删除、修改博客,需要后端使用blogId去定位要删除博客,因此可以将删除和修改两个按钮放在博客详情页,因为博客列表页到详情页带了blogId,从详情页到删除和修改请求就可以在前端使用location.search带上blogId,很方便。

1>约定前后端交互接口
在这里插入图片描述

2>编写前端代码

理解:在blog_detail.list页面中,发送检查当前登录用户是否是一个人的请求后,后端响应给前端一个json格式的blog字符串。前端jQuery封装的Ajax将它解析为json格式的blog对象(js对象),然后如果userId=0,那么消除两个a标签的样式。如果userId>0,那么就给a标签加上名称和路径,删除的路径是像后端发起一个get请求,编辑则是跳转到blog_edit.html页面,注意两个路径都会带上blogId。
在这里插入图片描述
在这里插入图片描述

3>编写后端代码

理解:在CheckLoginUserAndAuthor类的doGet方法中,从会话session中取出当前登录用户,并通过blogId获取该篇博客从而获取这篇博客的userId(authorId),再和登录用户的id比较,不相等则new一个blog对象,这个对象的成员全部为初始值,要么为null,要么为0,并将这个对象响应给前端。如果authorId和登录用户的id相等,那么直接响应给前端已经从数据库查出的blog对象。
在这里插入图片描述

五、删除博客

1>约定前后端交互接口
在这里插入图片描述

2>编写前端代码

在bolg_detail.html中,当当前登录用户和博客作者是同一个人时,显示了删除按钮,点击这按钮,就触发get请求给后端。
在这里插入图片描述

3>编写后端代码

当当前登录用户和博客作者是同一个人时,点击删除博客按钮,跳转到DeleteBlogServlet的doGet方法中,先获取当前博客的id,然后查询数据库是否有该博客id,有的话最后删除并跳转回blog_list.html页面。
在这里插入图片描述

六、修改博客

1>约定前后端交互接口
获取博客请求:
在这里插入图片描述
修改博客请求:
在这里插入图片描述

2>编写前端代码

说明:在bolg_detail.html中,当当前登录用户和博客作者是同一个人时,显示了编辑按钮,点击这按钮,跳转到blog_edit.html页面,这个跳转的请求我就不解释了,重点在blog_edit.html中怎么讲博客的原来的信息展示在编辑页的markdown文档中。
在blog_edit.html中,判断从其他地方跳转到当前页面时,有没有query string,没有query string,就认为是点击写博客触发跳转到blog_edit.html页面;而如果有query string,就认为是点击编辑按钮触发跳转到blog_edit.html页面。我们刚才也说了,从blog_detail.html页面点击编辑博客会带上博客Id,因此此时是带有blogId,即有query string,因此下面的代码就不是在if条件中进行markdown初始化,而是在else条件中对blogId对应的这篇博客进行markdown编辑页面的信息填充。
在这里插入图片描述
在这里插入图片描述
注意:修改操作至少涉及到三个比较关键的请求:
1>从blog_detail.html跳转到blog_edit.html。
2>将该篇博客信息在markdown编辑器中填充,这里通过发送ajax请求,来在前端获取该篇博客,并将博客信息(title和content)展示在markdown编辑器中。
3> 发布文章的路径修改,并且复用上传博客时的html代码,将发布文章的请求路径修改成edit?blogId="博客Id"
在这里插入图片描述

3>编写后端代码

第一个请求前端可以直接跳转,tomcat自动帮它跳转。
第二个请求,即获取当前博客信息的请求,后端代码就是复用BlogServlet的doGet方法,并通过blogId从数据库查出blog,把blog以json格式的字符串写给前端,这样就可以将该篇编辑的博客的内容写到markdown编辑器上。
第三个请求,即真正的修改的请求,点击发布文章,路径会跳转到EditBlogServlet的Post方法中,该方法会像点击写博客后发布博客那样,只是此时blogId,postTime和userId应当是固定不变的(和原来一样),然后在数据库中只需修改博客标题title和博客正文content。
最后重定向到blog_list.html页面,获取新的博客列表信息。在这里插入图片描述
在这里插入图片描述

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

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

相关文章

Android:设计模式

文章参考来源1 文章参考来源2 文章参考来源3 MVC Model 数据来源,管理业务数据逻辑,读取数据等 View 视图 Controller 单例模式,处理业务逻辑,负责改变Model和View 经典的MVC架构是 用户点击View,View将用户输入转…

springboot详细整合mybatisplus

SpringBoot详细整合mybatisPlus 文章目录 SpringBoot详细整合mybatisPlus一、引入mybatis_plus依赖二、修改mybatis_plus的yml配置三、添加mybatis_plus的其他配置以及包扫描四,修改mybatis的配置(这一步根据实际情况修改) 无奈,一…

三个关键数字变化,剖析中国智能手机市场的趋势及其影响

近期,全球行业分析机构CounterpointResearch公布了《中国智能手机高端市场白皮书》,对中国智能手机市场数据进行详细分析。该报告揭示了几个关键数据,值得深入剖析。 上面的图表展示了中国智能手机市场在2012年至2022年的11年间销量、平均价格…

UE5《Electric Dreams》项目PCG技术解析 之 PCGDemo_Ditch关卡详解

文章目录 前导文章关卡概要PCGGraphPoints From Actor Tag作为PCG的分割工具分层装饰 一些知识点和技巧使用Attribute Operation将属性暂存到临时属性中是否生成碰撞 小结 前导文章 《UE5《Electric Dreams》项目PCG技术解析 之 基于关卡PCGSettings的工作流》《UE5《Electric…

mac系统通过终端连接远程服务器

mac系统通过终端连接远程服务器 1、通过自带终端连接1.1 命令直接连接1.2 方式2——创建连接 2、通过iTerm2连接2.1 方式一:命令直接连接 3. Mac上使用scp命令 1、通过自带终端连接 1.1 命令直接连接 如下:ssh -p 22 root远程IP1.2 方式2——创建连接 …

类Twitter风格的RSS阅读器

本文完成于 2 月中旬,其中的反代还是 frp npm 方案; 什么是 RSS ? RSS 是用 PHP、Laravel、Inertia.js、Tailwind 和 Vue.js 编写的简单的类Twitter 风格的 RSS阅读器,支持 RSS和ATOM 格式。 命令行安装 在群晖上以 Docker 方式安装。 官…

形式化验证,QED: Quick Error Detection Tests for Effective Post-Silicon Validation(二)

目录 一、Article:文献出处(方便再次搜索) (1)作者 (2)文献题目 (3)文献时间 (4)引用 二、Data:文献数据(总结归纳,方便理解&am…

chatgpt赋能python:如何用Python打造一个简单的抽奖程序

如何用Python打造一个简单的抽奖程序 随着互联网的不断发展,抽奖活动已经成为了各种营销活动的必备环节,因此如何快速便捷地实现一个抽奖程序也变得尤为重要。本文将介绍如何使用Python打造一个简单的抽奖程序。 一、抽奖程序的工作原理 抽奖程序的核…

Vue使用vue-3d-model组件预览3D三维文件、立体文件,支持旋转、自动播放

实现效果 Tips:先泼个冷水,这个预览3D组件有个致命的缺陷——不能设置材质、皮肤文件的目录路径,必须要和3d文件放在同一个目录,如果项目是用hash模式(url后面会有/#/这种井号),就会导致无法读取根目录的材质文件。所以推荐了解下…

LabVIEW利用相机开发零件处理和检查系统

LabVIEW利用相机开发零件处理和检查系统 为了将自动化运用于飞机发动机轮机机翼的去毛刺和检查流程,设计了一个系统,该系统使用六轴机器人操作抖动,并结合两个关键操作。首先,使用专门选定的工具对机翼进行去毛刺,以去…

ssh 端口转发

本地转发 ssh -L -CTfN 9527:remote_server_ip:23 ssh_server_ipL 本地转发模式C 压缩数据T 禁用模拟终端f 后台运行N 不执行远程指令, 常用于仅做端口转发 在local_server上开启本地转发模式之后 。ssh_server就会出现2端的TCP链接。然后所有发向9527端口TCP数据…

ASCII、Unicode、UTF-8、GBK、全角/半角

入门小菜鸟,希望像做笔记记录自己学的东西,也希望能帮助到同样入门的人,更希望大佬们帮忙纠错啦~侵权立删。 目录 一、定义 1、ASCII 2、Unicode 3、UTF-8 4、GB2312 5、GBK 6、\u和\x 7、全角和半角 二、相互转化 1、str 与 ASCI…

[acwing周赛复盘] 第 110 场周赛20230701

[acwing周赛复盘] 第 110 场周赛20230701 总结5044. 求和1. 题目描述2. 思路分析3. 代码实现 5045. 三角形数1. 题目描述2. 思路分析3. 代码实现 5046. 智商药1. 题目描述2. 思路分析3. 代码实现 六、参考链接 总结 状态不对,把自己写懵了。T1 模拟币T2 对向双指针…

关于Linux同步机制知识点整理

在Linux系统中,同步机制是操作系统中非常重要的一部分,以下是一些基本要点: 互斥锁 互斥锁是一种「独占锁」,比如当线程 A 加锁成功后,此时互斥锁已经被线程 A 独占了,只要线程 A 没有释放手中的锁&#…

梁宁:VisionPro、GPT、Web3三件套齐备,元宇宙开启

本文内容整理自图灵社区对谈栏目直播,主题为 ChatGPT 真需求,从产品的第一性原理解析。 上篇内容回顾:梁宁:为什么中国没有像 ChatGPT 和 Vision Pro 这样的创新产品? 梁宁,产品战略专家,曾任湖…

chatgpt赋能python:如何在Python中安装PIL

如何在Python中安装PIL Python Imaging Library(PIL)是一款用于处理图像的Python库,它提供了各种图像处理功能,包括大小调整、旋转、裁剪等等。如果你需要在你的Python项目中处理图像,那么PIL是一个不错的选择。 步骤…

DBeaver连接GaussDB

DBeaver 官网:https://dbeaver.io/打开DBeaver,点击菜单栏 “数据库”>“驱动管理” 点击“新建” 填入下面内容: 驱动名称:GS 驱动类型:Generic 类名:org.postgresql.Driver URL模板:jdbc…

Linux:LNMP上搭建discuz论坛(源码安装)

LNMP环境 Linux :LNMP(源码包安装)_鲍海超-GNUBHCkalitarro的博客-CSDN博客 discuz论坛 准备好源码包 LNMP环境正常 yum -y install unzip unzip Discuz_X3.3_SC_UTF8.zip # unzip 源码包名称 mv upload/ /usr/local/nginx/html/tarro…

信号链噪声分析13

文章目录 概要整体架构流程技术名词解释技术细节小结 概要 提示:这里可以添加技术概要 接 触 ADC 或 DAC 时您一定会碰到这个经常被引用的公式,用于计算转换器理论信噪 比(SNR)。与其盲目地相信表象,不如从根本上了解其来源,因为…

Shell中的流程控制(if/case/for/while)

文章目录 Shell中的流程控制(if/case/for/while)1 if判断1.1 单分支1.2 多分支 2. case语句3 for循环3.1 第一种写法 (())3.2 第二种写法 in 4 while循环4.1 demo14.2. demo2测试let Shell中的流程控制(if/case/for/while) 1 if判…