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.rhkb.cn/news/81691.html

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

相关文章

根文件系统制作

1.官网下载工具 制作工具&#xff1a;busybox https://busybox.net/downloads/ 2.制作根文件系统 2.1准备工作 a.把压缩包放在FSP1M目录下&#xff0c;并解压 2.2正式开始 2.2.1配置交叉编译工具链 1. 打开Makefile文件 2. 修改ARCH &#xff1f;$(SUBARCH) &#xf…

Yolov5缺陷检测/目标检测 Jetson nx部署Triton server

使用AI目标检测进行缺陷检测时&#xff0c;部署到Jetson上即小巧算力还高&#xff0c;将训练好的模型转为tensorRT再部署到Jetson 上供http或GRPC调用。1 Jetson nx 刷机 找个ubuntu 系统NVIDIA官网下载安装Jetson 的sdkmanager一步步刷机即可。 本文刷的是JetPack 5.1, 其中包…

day03

#ifndef __SEQLIST_H__ #define __SEQLIST_H__#include <stdio.h> #include <string.h> #include <stdlib.h>#define MAX 40 typedef int datatype; typedef struct {datatype data[MAX];int len; }seqlist, *seqlistPtr;//创建顺序表 seqlistPtr list_creat…

vscode连接远程Linux服务器

文章目录 一、环境安装1.1 下载vscode1.2 下载vscode-sever 二、ssh链接2.1 安装Remote-SSH2.2 设置vscode ssh2.3 设置免密登录2.3.1 本地生成公私钥2.3.2 服务器端添加公钥 三、安装插件3.1 vscode安装插件3.1.1 在线安装插件3.1.2.1 下载插件3.1.2.2 安装插件 3.2 vscode-se…

Openlayers实战:判断共享单车是否在电子围栏内

共享单车方便了我们的日常生活,解决了后一公里的行程问题。为了解决共享单车乱放的问题,运营部门规划出一些围栏,配合到电子地图上即为电子围栏,只有放在围栏内才能停车结算,在我们的Openlayers实战示例中,即模拟这一场景。 效果图 源代码 /* * @Author: 大剑师兰特(x…

【Git】Git切换地址

如何切换git代码地址&#xff1f; 1、查看当前远程 url git remote -v执行命令后&#xff0c;可以看见当前有2个URL。 远程 URL 在一般情况下有两个&#xff0c;分别是 fetch 和 push。 fetch URL 是用于从远程仓库获取最新版本的数据。当您运行 git fetch 命令时&#xf…

ThreadPoolExecutor线程池详解

ThreadPoolExecutor线程池详解 1. 背景 项目最近的迭代中使用到了ThreadPoolExecutor线程池&#xff0c;之前都只是知道怎么用&#xff0c;没有了解过线程池的底层原理&#xff0c;项目刚上线&#xff0c;有时间整理一下线程池的用法&#xff0c;学习一下线程池的底层实现与工…

运行 Jmeter 文件生成 HTML 测试报告,我选择 ANT 工具

概述 ant 是一个将软件编译、测试、部署等步骤联系在一起加以自动化的一个工具&#xff0c;大多用于 Java 环境中的软件开发。 在与 Jmeter 生成的 jmx 文件配合使用中&#xff0c;ant 会完成jmx计划的执行和生成jtl文件&#xff0c;并将jtl文件转化为html页面进行查看。 还可…

Node.js |(三)Node.js API:path模块及Node.js 模块化 | 尚硅谷2023版Node.js零基础视频教程

学习视频&#xff1a;尚硅谷2023版Node.js零基础视频教程&#xff0c;nodejs新手到高手 文章目录 &#x1f4da;path模块&#x1f4da;Node.js模块化&#x1f407;介绍&#x1f407;模块暴露数据⭐️模块初体验⭐️暴露数据 &#x1f407;导入文件模块&#x1f407;导入文件夹的…

CAPL - XML和TestModule结合实现测试项可选

目录 目的:是否想实现如下面的功能呢? 一、.can和.cin文件中函数开发

C/C++面试总结

一、关键字static、const、extern、volatile作用 1、const 1.修饰常量 用const修饰的变量是不可变的&#xff0c;修饰后的变量只能使用&#xff0c;不能修改。 2.修饰指针 如果const位于*的左侧&#xff0c;eg&#xff1a;const int* a&#xff0c;则const就是用来修饰指针…

研发工程师玩转Kubernetes——hostPath

有别于《研发工程师玩转Kubernetes——emptyDir》一文中介绍的emptyDir&#xff0c;hostPath可以在同一个Node的不同Pod间共享卷。 下面的清单文件利用了Pod亲和性&#xff0c;让Pod集中到一个Node上。 apiVersion: apps/v1 kind: Deployment metadata:name: hostpath-deploy…

Adobe ColdFusion 反序列化漏洞复现(CVE-2023-29300)

0x01 产品简介 Adobe ColdFusion是美国奥多比&#xff08;Adobe&#xff09;公司的一套快速应用程序开发平台。该平台包括集成开发环境和脚本语言。 0x02 漏洞概述 Adobe ColdFusion存在代码问题漏洞&#xff0c;该漏洞源于受到不受信任数据反序列化漏洞的影响&#xff0c;攻击…

FinClip 支持小程序维度域名配置;桌面端体验活动进行中

FinClip 的使命是使您&#xff08;业务专家和开发人员&#xff09;能够通过小程序解决关键业务流程挑战&#xff0c;并完成数字化转型的相关操作。不妨让我们看看在本月的产品与市场发布亮点&#xff0c;看看是否有助于您实现目标。 产品方面的相关动向&#x1f447;&#x1f…

Kafka概论

前言 任何消息中间件&#xff0c;除了基础组件架构外&#xff0c;核心特性无非三个&#xff0c;消息可靠性、消息模型、吞吐量&#xff0c;本文要聊的正是这些东西&#xff0c;其余诸如API、下载安装、集群搭建等都是死的&#xff0c;而且会随着版本的变动而改变&#xff0c;这…

uni-app 封装api请求

前端封装api请求 前端封装 API 请求可以提高代码的可维护性和重用性&#xff0c;同时使得 API 调用更加简洁和易用。 下面是一种常见的前端封装 API 请求的方式&#xff1a; 创建一个 API 封装模块或类&#xff1a;可以使用 JavaScript 或 TypeScript 创建一个独立的模块或类来…

VoxWeekly|The Sandbox 生态周报|20230731

欢迎来到由 The Sandbox 发布的《VoxWeekly》。我们会在每周发布&#xff0c;对上一周 The Sandbox 生态系统所发生的事情进行总结。 如果你喜欢我们内容&#xff0c;欢迎与朋友和家人分享。请订阅我们的 Medium 、关注我们的 Twitter&#xff0c;并加入 Discord 社区&#xf…

架构实践方法

一、识别复杂度 将主要的复杂度问题列出来&#xff0c;然后根据业务、技术、团队等综合情况进行排序&#xff0c;优先解决当前面临的最主要的复杂度问题。对于按照复杂度优先级解决的方式&#xff0c;存在一个普遍的担忧&#xff1a;如果按照优先级来解决复杂度&#xff0c;可…

【MATLAB第68期】基于MATLAB的LSTM长短期记忆网络多变量时间序列数据多步预测含预测未来(非单步预测)

【MATLAB第68期】基于MATLAB的LSTM长短期记忆网络多变量时间序列数据多步预测含预测未来&#xff08;非单步预测&#xff09; 输入前25个时间&#xff0c;输出后5个时间 一、数据转换 1、原始数据 5列时间序列数据&#xff0c;70行样本 705 数据矩阵结构 2、数据转换 将…

利用awk筛选给定时间范围内的日志

时间戳 什么是时间戳&#xff1f; ​ 时间戳是指格林威治时间自1970年1月1日&#xff08;00:00:00 GMT&#xff09;至当前时间的总秒数。它也被称为Unix时间戳&#xff08;Unix Timestamp&#xff09;。通俗的讲&#xff0c;时间戳是一份能够表示一份数据在一个特定时间点已经存…