作者
:学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页面,获取新的博客列表信息。