SpringBoot项目-个人博客系统的实现【下】

10.实现强制要求登陆

当用户访问 博客列表页和 博客详情页时, 如果用户当前尚未登陆, 就自动跳转到登陆页面

1.添加拦截器

public class LoginInterceptor implements HandlerInterceptor {@Overridepublic boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {// 获取登录信息HttpSession session = request.getSession(false);if (session == null || session.getAttribute(Constant.USER_NAME_SESSION) == null) {response.setStatus(401);return false;}return true;}
}

2.将登陆拦截器添加到系统配置当中去

@Configuration
public class AppConFig implements WebMvcConfigurer {@Autowiredprivate LoginInterceptor loginInterceptor;@Overridepublic void addInterceptors(InterceptorRegistry registry) {// 将登陆拦截器添加到系统配置中registry.addInterceptor(loginInterceptor)// 表示拦截所有路径.addPathPatterns("/**")// 放过登陆页面.excludePathPatterns("/user/login");}
}

3.修改客户端代码

在blog_list和blog_detail页面添加下面的代码

statusCode: {401: function () {alert("请先登录");location.assign("blog_login.html");}}

测试成功

在这里插入图片描述

11.实现显示⽤户信息(博客列表页面)

目前左边部分显示的用户信息是写死的,我们需要从后端来获取数据动态的显示

1.约定前后端交互接口

在博客列表页
【请求】

  1. user/getUserInfo

【响应】

  1. [200]
  • [200]返回数据成功,显示当前登录用户信息
  • [-1] 表示未登录
  • [401]没有权限访问
  1. [error]访问出现错误,打印异常信息

2.修改登录功能,登陆成功后添加session

在这里插入图片描述

3.实现服务端代码

  1. 服务端需要根据session返回当前登录用户的信息
  2. 前端根据拿到的数据渲染在页面上
    @RequestMapping("/getUserInfo")public Result  getUserInfo(HttpServletRequest request, HttpServletResponse response) {// 判断登录有拦截器去做HttpSession session = request.getSession(false);if (session == null || session.getAttribute(Constant.USER_NAME_SESSION) == null) {response.setStatus(401);return Result.fail(-1,"用户未登录");}User user = (User) session.getAttribute(Constant.USER_NAME_SESSION);return Result.success(user);}

4.实现客户端代码

⽬前⻚⾯的⽤户信息部分是写死的. 形如:
在这里插入图片描述
我们期望这个信息可以随着⽤户登陆⽽发⽣改变.

  • 如果当前⻚⾯是博客列表⻚, 则显示当前登陆⽤户的信息.
  • 如果当前⻚⾯是博客详情⻚, 则显示该博客的作者⽤户信息
getUserInfo()
function getUserInfo() {$.ajax({type: "get",url: "/user/getUserInfo",success: function (result) {if (result.code == 200 && result.data != null) {$(".left .card h3").text(result.data.userName);$(".left .card a").attr("href", result.data.githubUrl);}},error: function () {console.log("后端返回失败");}});}

5.显示成功

在这里插入图片描述

12.显示用户信息(博客详情页)

1.约定前后端交互接口

在博客详情页
【请求】

  1. user/getAuthorInfo"+location.search

【响应】

  1. [200]
  • [200]返回数据成功,显示当前博客作者信息
  • [-1] 表示博客id不合法
  • [-2] 表示当前博客作者已经注销
  • [401]没有权限访问(这里不需要重复判断)
  1. [error]访问出现错误,打印异常信息

2.在userService添加方法

    /*** 根据blogId获取作者信息* @param blogId* @return*/public User getUserInfoByBlogId(Integer blogId) {Blog blog = blogMapper.selectByBlogId(blogId);User user = userMapper.selectById(blog.getUserId());user.setPassWord("");return user;}

3.实现服务端代码

    @Autowiredprivate UserService userService;private BlogService blogService;@RequestMapping("/getAuthorInfo")public Result getAuthorInfo(Integer blogId) {if (blogId == null || blogId <= 0) {return Result.fail(-1,"博客id不合法");}User user = userService.getUserInfoByBlogId(blogId);if (user == null) {return Result.fail(-2, "用户已注销");}return Result.success(user);}

4.实现前端代码

        //显示当前登录⽤户的信息function getAuthorInfo() {$.ajax({type: "get",url: "/user/getAuthorInfo"+location.search,success: function (result) {if (result.code == 200 && result.data != null) {$(".left .card h3").text(result.data.userName);$(".left .card a").attr("href", result.data.githubUrl);}},error: function (err) {}});}getAuthorInfo();

5.显示成功

在这里插入图片描述

13.实现发布博客

1.约定前后端交互接口

在博客详情页
【请求】

1.blog/add
?title=" “&content=” "…

【响应】

  1. [200]
  • [200]返回数据成功,表示添加成功,跳转至博客列表界面
  • [-1] 表示标题或正文不可为空
  • [-2] 表示用户未登录
  • [-3] 表示添加失败,稍后重试
  • [401]没有权限访问
  1. [error]访问出现错误,打印异常信息

2.实现服务端代码

    /*** 添加博客* @param title* @param content* @return*/@RequestMapping("/add")public Result add(HttpServletRequest request, String title, String content) {// 判空if (!StringUtils.hasLength(title) || !StringUtils.hasLength(content)) {return Result.fail(-1,"标题或正文不能为空");}// 获取当前登录用户信息// 因为添加了拦截器,走到这里一定登陆了User user = (User) request.getSession(false).getAttribute(Constant.USER_NAME_SESSION);// 还是判空以下if (user == null) {return Result.fail(-2,"用户未登录");}Blog blog = new Blog();blog.setUserId(user.getId());blog.setContent(content);blog.setUserId(user.getId());blog.setTitle(title);Integer row = blogService.insertBlog(blog);if (row == 1) {return Result.success("添加成功");}return Result.fail(-3,"添加失败,稍后重试");}

3.实现前端代码

    <script type="text/javascript">$(function () {var editor = editormd("editor", {width: "100%",height: "550px",path: "blog-editormd/lib/"});});function submit() {$.ajax({type: "post",url: "/blog/add",data: {"title": $("#title").val(),"content": $("#content").val()},success: function (result) {if (result != null && result.code == 200) {alert("发布成功,即将跳转博客列表界面");location.href = "blog_list.html";} else{alert(result.msg);return;}},error: function () {console.log("后端返回失败");},statusCode: {401: function () {alert("请先登录");location.assign("blog_login.html");}}});}</script>

4.显示成功


在这里插入图片描述
我们发现博客列表是正序显示的,我们把它改成倒叙,
sql语句查询的时候按照时间降序排列

5.修改博客列表显示

    /*** 查询所有未删除的博客.按照时间降序排列* @return*/@Select("select id, title, content, user_id, create_time from blog where delete_flag = 0 order by create_time desc;")List<Blog> selectAllBlog();

6.博客列表倒序显示正常

在这里插入图片描述

14.实现删除/编辑博客

在博客详情页,判断本篇博客是否是当前登录用户所写
如果是,显示编辑和删除按钮

1.动态显示按钮

给Blog类添加一个属性,loginUser为1,说明本篇博客是否是当前登录用户所写,返回博客信息的同时返回这个属性,根据属性的值来判断是否添加按钮

1.修改服务端代码

1.给Blog类新型加一个字段


@Data
public class Blog {private Integer id;private String title;private String content;private Integer userId;private Integer deleteFlag;// 本篇博客是否是当前登录用户所写private Integer loginUser;private Date createTime;public String getCreateTime() {return DateUtil.format(createTime);}
}

2.修改BlogController

    @RequestMapping("/getBlogDetails")public Result getDetails(HttpServletRequest request, Integer blogId) {// 判合法if (blogId == null || blogId <= 0) {return Result.fail(-1,"博客不存在");}Blog blog = blogService.selectByBlogId(blogId);if (blog == null) {return Result.fail(-1,"博客不存在");}// 获取当前登录用户User user = (User) request.getSession(false).getAttribute(Constant.USER_NAME_SESSION);if (user.getId().equals(blog.getUserId())) {blog.setLoginUser(1);}return Result.success(blog);}

3.实现前端代码

        $.ajax({type: "get",url: "/blog/getBlogDetails" + location.search,success: function (result) {console.log(result);if (result.code == 200 && result.data != null) {$(".title").text(result.data.title);$(".date").text(result.data.createTime);editormd.markdownToHTML("content", {markdown: result.data.content,});//显示更新, 删除按钮if (result.data.loginUser == 1) {var html = "";html += '<div class="operating">';html += '<button onclick="window.location.href=\'blog_update.html'+location.search+'\'">编辑</button>';html += '<button onclick="deleteBlog()">删除</button>';html += '</div>';$(".content").append(html);}} else {alert(result.msg);}},error: function () {console.log('访问出错');},statusCode: {401: function () {location.assign("blog_login.html");}}});

4.编辑和删除按钮显示成功

在这里插入图片描述

2.实现编辑博客

1.约定前后端交互接口

【请求】

1.blog/update
?title=" “&content=” “&blogId=” "…

【响应】

  1. [200]
  • [200]返回数据成功,表示更新成功,跳转至博客列表界面
  • [-1] 表示标题或正文不可为空
  • [-2] 表示用户未登录
  • [-3] 表示更新失败,稍后重试
  • [401]没有权限访问
  1. [error]访问出现错误,打印异常信息

2.后端代码实现

    /*** 编辑博客* @param title* @param content* @param blogId* @return*/@RequestMapping("/update")public Result update(String title, String content, Integer blogId) {// 判空if (!StringUtils.hasLength(title) || !StringUtils.hasLength(content)) {return Result.fail(-1,"标题或正文不能为空");}Blog blog = new Blog();blog.setTitle(title);blog.setContent(content);blog.setId(blogId);Integer row = blogService.updateBlog(blog);if (row == 1) {return Result.success("更新成功");}return Result.fail(-3,"更新失败,稍后重试");}

4.编辑功能实现成功

在这里插入图片描述

3.实现前端代码

    <script type="text/javascript">getBlogInfo();function submit() {$.ajax({type: "post",url: "/blog/update",data: {"title": $("#title").val(),"content": $("#content").val(),"blogId": $("#blogId").val()},success: function (result) {if (result != null && result.code == 200) {alert("更新成功,跳转至博客列表界面")location.href = "blog_list.html";} else {alert(result.msg);return;}},error: function () {console.log("后端返回失败");},statusCode: {401: function () {alert("请先登录");location.assign("blog_login.html");}}});}function getBlogInfo() {$.ajax({type: "get",url: "/blog/getBlogDetails" + location.search,success: function (result) {if (result != null && result.code == 200 && result.data != null) {console.log(result);$("#title").val(result.data.title);$("#content").html(result.data.content);$("#blogId").val(result.data.id);}}});}$(function () {var editor = editormd("editor", {width: "100%",height: "550px",path: "blog-editormd/lib/"});});</script>

3.实现删除博客

1.约定前后端交互接口

【请求】

1.blog/delete
blogId=" "…
【响应】

  1. [200]
  • [200]返回数据成功,表示删除成功,跳转至博客列表界面
  • [-1] 表示博客不存在
  • [-2] 表示用户未登录
  • [-3] 表示删除失败,稍后重试
  • [401]没有权限访问
  1. [error]访问出现错误,打印异常信息

2.后端代码实现

    @RequestMapping("/delete")public Result deleteBlog(Integer blogId) {if (blogId == null || blogId <= 0) {return Result.fail(-1,"博客不存在");}Blog blog = new Blog();blog.setId(blogId);blog.setDeleteFlag(1);Integer row = blogService.updateBlog(blog);if (row == 1) {return Result.success("删除成功");}return Result.fail(-3,"删除失败,稍后重试");}

3.前端代码实现

function deleteBlog() {$.ajax({type: "post",url: "/blog/delete" + location.search,success: function (result) {if (result != null && result.code == 200 && result.data) {alert("删除成功, 即将跳转⾄博客列表⻚");location.href = "blog_list.html"} else {alert(result.msg);}},error: function () {console.log('访问出错');},statusCode: {401: function () {location.assign("blog_login.html");}}});}

4.删除功能实现成功

在这里插入图片描述

15.实现退出登录功能

1.约定前后端交互接口

【请求】

1.blog/loginout
【响应】

  1. [200]
  • [200]返回数据成功,表示退出成功,跳转至登录界面
  • [401]没有权限访问
  1. [error]访问出现错误,打印异常信息

2.后端代码实现

    @RequestMapping("/logout")public Result logout(HttpServletRequest request) {HttpSession session = request.getSession(false);if (session != null || session.getAttribute(Constant.USER_NAME_SESSION) != null) {session.removeAttribute(Constant.USER_NAME_SESSION);}return Result.success("退出成功");}

3.前端代码实现

function logout() {$.ajax({type: "get",url: "/user/logout",success: function (result) {location.assign("blog_login.html");},error: function () {console.log('访问出错');},statusCode: {401: function () {location.assign("blog_login.html");}}})
}

4.推出功能实现成功在这里插入图片描述

自此,博客系统就已经全部完成了,
希望能对大家有所帮助~~

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

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

相关文章

解决Linux下PyCharm无法新建文件

一、问题描述 如图&#xff0c;在Ubuntu Linux系统中使用pycharm管理项目时&#xff0c;提示无法新建.py源文件&#xff1a; 二、问题解决 将问题定性为文件夹&#xff08;目录&#xff09;权限问题&#xff0c;在终端中打开项目文件夹的上级目录&#xff0c;将整个项目目录的…

全志F1C200S嵌入式驱动开发(应用程序开发)

【 声明:版权所有,欢迎转载,请勿用于商业用途。 联系信箱:feixiaoxing @163.com】 我们在开发soc驱动的时候,很多情况下也要验证下当前的驱动功能是否正确。当然除了验证驱动功能之外,我们还要编写业务代码和流程代码。这中间就和各行各业有关了,有的是算法,有…

你还不快来学习怎么翻译视频中的英语吗

年轻人纪逸是一个对世界充满好奇心的视频爱好者。每当他看到令人激动的视频时&#xff0c;总是忍不住想要将它与更多人分享。然而&#xff0c;有一天&#xff0c;他遇到了一个困扰&#xff1a;他发现了一段精彩的外语视频&#xff0c;但自己并不懂那种语言&#xff01;他犯了愁…

动态规划01: 斐波那契数列模型

第 N 个泰波那契数&#xff08;easy&#xff09; 题目链接: 1137. 第 N 个泰波那契数 题目描述: 泰波那契序列 Tn 定义如下&#xff1a; T0 0, T1 1, T2 1, 且在 n > 0 的条件下 Tn3 Tn Tn1 Tn2 给你整数 n&#xff0c;请返回第 n 个泰波那契数 Tn 的值。 示例 1&…

k8s-服务发现service和ingress

回到目录 service用于集群内部应用的网络调用&#xff0c;处理东西流量 ingress用于集群外部用户访问内部服务&#xff0c;处理南北流量 一 kube-proxy三种代理模式 kubernetes集群中有三层网络&#xff0c;一类是真实存在的&#xff0c;例如Node Network、Pod Network,提供真…

Node.js究竟是什么?初学者指南

如果你正在考虑使用JavaScript进行后端开发&#xff0c;你会听到“Node.js”这个术语。Node通常与开发功能强大的web服务器联系在一起。 但 Node.js 究竟是什么&#xff1f;它是和 Angular 一样的 JavaScript 框架吗&#xff1f;它是一种编程语言吗&#xff1f;它是 JavaScrip…

中国中医中药元宇宙 中药材价格缘何“狂飙”

◇相比去年同期&#xff0c;有超200个常规品种涨幅高于50%&#xff0c;25个常用大宗药材涨幅超200%&#xff0c;个别品种甚至涨价4至9倍 ◇在中药材价格普遍高涨的情况下&#xff0c;部分市场仓库库存数量也较多&#xff0c;出现囤积居奇倾向 ◇“不少游资和热钱涌入中药材市场…

Spring Boot + Vue3前后端分离实战wiki知识库系统<十一>--文档管理功能开发三

文档内容的显示&#xff1a; 在上一次Spring Boot Vue3前后端分离实战wiki知识库系统&#xff1c;十&#xff1e;--文档管理功能开发二文档管理模块还差文档的显示木有完成&#xff0c;所以接下来先将这块模块给收尾了。 增加单独获取内容的接口&#xff1a; 概述&#xff…

设计模式、Java8新特性实战 - List<T> 抽象统计组件

一、背景 在日常写代码的过程中&#xff0c;针对List集合&#xff0c;统计里面的某个属性&#xff0c;是经常的事情&#xff0c;针对List的某个属性的统计&#xff0c;我们目前大部分时候的代码都是这样写&#xff0c;每统计一个变量&#xff0c;就要定义一个值&#xff0c;且…

ATTCK实战系列-红队评估 (红日靶场3)Vulnstack三层网络域渗透靶场

文章目录 环境配置靶场介绍靶场设置 外网渗透信息收集端口扫描目录扫描 漏洞发现与利用获取ssh账号密码&#xff0c;登录centos 提权 内网渗透建立代理内网信息收集smb暴破&#xff0c;获取本地管理员密码 横向移动使用psexec模块上线msf 环境配置 靶场介绍 靶场地址 http:/…

剑指Offer 20.表示数值的字符串

20.表示数值的字符串 题目 官方地址 代码&#xff08;正则表达式&#xff09; public boolean isNumeric (String str) {if (str null || str.length() 0)return false;return new String(str).matches("[-]?\\d*(\\.\\d)?([eE][-]?\\d)?"); }在给定的代码…

PCIE链路信息

目录 简介&#xff1a; 目的&#xff1a; 详情&#xff1a; 简介&#xff1a; PCIe有很多寄存器&#xff0c;也有很多控制&#xff0c;包括链路状态信息&#xff0c;上一节我们讲到了PCie的链路训练&#xff0c;这节文章将继续学习PCIe相关知识。 目的&#xff1a; 从设计…

【Python从小白到高手】---函数基础

个人主页&#xff1a;平行线也会相交 欢迎 点赞&#x1f44d; 收藏✨ 留言✉ 加关注&#x1f493;本文由 平行线也会相交 原创 收录于专栏【Python小白从入门到精通】&#x1f388; 本专栏旨在分享学习Python的一点学习心得&#xff0c;欢迎大家在评论区讨论&#x1f48c; 目录…

iPhone 6透明屏是什么?原理、特点、优势

iPhone 6透明屏是一种特殊的屏幕技术&#xff0c;它能够使手机屏幕变得透明&#xff0c;让用户能够透过屏幕看到手机背后的物体。 这种技术在科幻电影中经常出现&#xff0c;给人一种未来科技的感觉。下面将介绍iPhone 6透明屏的原理、特点以及可能的应用。 iPhone 6透明屏的原…

本地 shell无法连接centos 7 ?

1、首先检查是否安装ssh服务&#xff1b; yum list installed | grep openssh-server# 没有安装尝试安装下 yum install openssh-server 2、检查ssh服务是否开启 systemctl status sshd.service# 未开启&#xff0c;开启下 systemctl start sshd.service # 将sshd 服务添…

socker套接字

1.打印错误信息 2.socketaddr_in结构体 结构体&#xff1a; &#xff08;部分库代码&#xff09; (宏中的##) 3.manual TCP: SOCK_STREAM &#xff1a; 提供有序地&#xff0c;可靠的&#xff0c;全双工的&#xff0c;基于连接的流式服务 UDP: 面向数据报

406 · 和大于S的最小子数组

链接&#xff1a;LintCode 炼码 - ChatGPT&#xff01;更高效的学习体验&#xff01; 题解&#xff1a;同向双指针 九章算法 - 帮助更多程序员找到好工作&#xff0c;硅谷顶尖IT企业工程师实时在线授课为你传授面试技巧 class Solution { public:/*** param nums: an array …

【maven】构建项目前clean和不clean的区别

其实很简单&#xff0c;但是百度搜了一下&#xff0c;还是没人能简单说明白。 搬用之前做C项目时总结结论&#xff1a; 所以自己在IDE里一遍遍测试程序能否跑通的时候&#xff0c;不需要clean&#xff0c;因为反正还要改嘛。 但是这个项目测试好了&#xff0c;你要打成jar包给…

element-tree-line el-tree 添加结构线 添加虚线

概览&#xff1a;给element组件添加上虚线&#xff0c;通过使用插件element-tree-line 参考连接&#xff1a; 参考别人的博客 安装插件&#xff1a; # npm npm install element-tree-line -S # yarn yarn add element-tree-line -S main.js全局注册引入插件&#xff1a; imp…

Python批量查字典和爬取双语例句

最近&#xff0c;有网友反映&#xff0c;我的批量查字典工具换到其它的网站就不好用了。对此&#xff0c;我想说的是&#xff0c;互联网包罗万象&#xff0c;网站的各种设置也有所不同&#xff0c;并不是所有的在线字典都可以用Python爬取的。事实上&#xff0c;很多网站为了防…