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

news2024/10/3 4:29:34

10.实现强制要求登陆

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

1.添加拦截器

public class LoginInterceptor implements HandlerInterceptor {
    @Override
    public 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 {

    @Autowired
    private LoginInterceptor loginInterceptor;
    @Override
    public 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.实现服务端代码

    @Autowired
    private 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.coloradmin.cn/o/836045.html

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

相关文章

程序员私活渠道揭,探索项目接单秘

对于程序员来说&#xff0c;接私活是很正常的事情&#xff0c;在工作闲暇时间利用业余时间来赚点零花钱还是非常不错的&#xff0c;但是如果能一边接私活一边提高自己的水平那就更好了。 这里给大家的建议就是&#xff0c;可以接一些稍微有难度但是在自己能力范围的项目&#x…

自动化测试:封装入口文件

1自动生成测试报告&#xff0c;start_dir是要找入口文件的相对目录。测试用例有规律的话&#xff0c;pattern可以批量执行&#xff08;通过相同的开头*&#xff09; start_dir 是要执行的测试文件所在的目录&#xff0c;pattern可以理解为具体的执行测试的文件 2所有的底层操…

C++stack_queue

stack_queue 容器适配器stack详解栈适配器栈模拟实现 队列详解队列适配器queue模拟实现 容器适配器 除了顺序容器外&#xff0c;标准库还定义了三个顺序容器适配器:stack(栈),queue(队列),priority_queue(优先队列)。适配器是标准库中的一个通用概念。容器&#xff0c;迭代器和…

Android Jetpack

Jetpack 是一个由多个库组成的套件&#xff0c;可帮助开发者遵循最佳实践、减少样板代码并编写可在各种 Android 版本和设备中一致运行的代码&#xff0c;让开发者可将精力集中于真正重要的编码工作。 1.基础组件 &#xff08;1&#xff09;AppCompat&#xff1a;使得支持较低…

了解政策法规和行业规范,可以帮助写作人员更好地理解公文要求和标准

了解政策法规和行业规范&#xff0c;可以帮助写作人员更好地理解公文要求和标准。 政策法规和行业规范是公文写作的重要参考依据&#xff0c;包括相关法律法规、行业标准和制度规定等。了解这些规范和标准可以帮助写作人员更好地掌握公文的表达要求和规范要求&#xff0c;以确保…

跨境选品怎么选?建议独立站卖家收下这份利基产品查找攻略!

跨境电商平台现在可谓是火热发展中&#xff0c;独立站出海风口&#xff0c;其实选择的机会还真不少&#xff0c;相比国内电商的发展势头&#xff0c;看得出来&#xff0c;未来跨境电商的大门&#xff0c;对你而言&#xff0c;敞开着。选品这事儿&#xff0c;就像你上战场前挑选…

linux_驱动_iic总线获取si7006温湿度

应用层si7006.c #include<stdio.h> #include <sys/types.h> #include <sys/stat.h> #include <fcntl.h> #include <unistd.h> #include <stdlib.h> #include <string.h> #include <sys/ioctl.h> #include <arpa/inet.h>…

学生信息管理系统springboot学校学籍专业数据java jsp源代码mysql

本项目为前几天收费帮学妹做的一个项目&#xff0c;Java EE JSP项目&#xff0c;在工作环境中基本使用不到&#xff0c;但是很多学校把这个当作编程入门的项目来做&#xff0c;故分享出本项目供初学者参考。 一、项目描述 学生信息管理系统springboot 系统3权限&#xff1a;超…

C语言 函数指针详解

一、函数指针 1.1、概念 函数指针&#xff1a;首先它是一个指针&#xff0c;一个指向函数的指针&#xff0c;在内存空间中存放的是函数的地址&#xff1b; 示例&#xff1a; int Add(int x&#xff0c;int y) {return xy;} int main() {printf("%p\n",&Add);…

Linux tcpdump 命令详解

简介 用简单的话来定义tcpdump&#xff0c;就是&#xff1a;dump the traffic on a network&#xff0c;根据使用者的定义对网络上的数据包进行截获的包分析工具。 tcpdump可以将网络中传送的数据包的“头”完全截获下来提供分析。它支持针对网络层、协议、主机、网络或端口的…

MPLS(下)

LDP --- 标签分发协议 --- 主要应用在MPLS的控制层面 MPLS控制层面需要完成的工作主要就是分配标签和传递标签。分配标签的前提是本地路由表中得先存在标签&#xff0c;传递标签的前提也是得先具备路由基础。所以&#xff0c;LDP想要正常工作&#xff0c;则需要IGP作为基础。 …

Docker实战-操作Docker容器实战(一)

导语   在之前的分享中&#xff0c;我们介绍了关于如何去操作Docker镜像&#xff0c;下面我们来看看如何去操作容器。 简单来讲&#xff0c;容器是镜像运行的一个实例&#xff0c;与镜像不同的是镜像只能作为一个静态文件进行读取&#xff0c;而容器是可以在运行时进行写入操…

嵌入式的日常工作内容是什么?

1、看器件文档 2、找供应商要资料 3、打电话或微信联系供应商了解技术或器件细节 4、忍受门外汉领导连环夺命吹&#xff0c;因为他们不懂技术&#xff0c;只会问进度 5、写技术文档 6、跟硬件工程师联合测试&#xff0c;查看电路板未工作状态各种问题。有时还要自己手动DI…

tomcat通用回显

​Tomcat架构简析 tomcat的架构图 Server:整个tomcat启动的时候只有一个server Service:一个server中包含了多个service,表示服务 **Container:**容器,可以看作是一个servlet容器,包含一些Engine,Host,Context,Wraper等,访问的路径什么的就存放在这里 Engine -- 引擎 Host …

搞个个人博客,纯学习想找个纯html模板咋就这难

以前做毕业设计的时候老想找一些不掺杂后端代码的前端模板。 可是下载下来&#xff0c;不是php就是python后台的。看又看不懂&#xff0c;想换语言就必须先把里面的后台代码拿掉。 就很像买了个精装的二手房&#xff0c;白白多花了砸墙钱。 就比如&#xff0c;想做个带菜单的…

编写SPI_Master驱动程序_新方法

编写SPI_Master驱动程序_新方法 文章目录 编写SPI_Master驱动程序_新方法一. SPI驱动框架1.1 总体框架1.2 怎么编写SPI_Master驱动1.2.1 编写设备树1.2.2 编写驱动程序 二、 编写程序2.1 数据传输流程2.2 写代码 致谢 参考资料&#xff1a; 内核头文件&#xff1a;include\lin…

vsphere6.5 创建数据中心、集群和添加主机

1、新建数据中心&#xff0c;在入门页面选择创建数据中心&#xff0c;名称可以自定义。 2、创建完成数据中心后就可以添加主机和创建集群了。 3、新建一个集群&#xff0c;并打开DRS和HA功能&#xff0c;这两个功能的一些其他选项可以在创建完成后进一步设置&#xff0c;关于EV…

我能“C“——扫雷游戏

一.前言&#xff1a; 扫雷游戏&#xff0c;一款经典的游戏&#xff0c;没玩过的话也可以试着玩一玩&#xff0c;这样对写扫雷游戏这个小游戏的化是会有一个很好的思路的。那么本片博客就来介绍如何实现扫雷游戏的具体步骤。扫雷游戏链接&#x1f449; 扫雷游戏网页版 - Minesw…

人工智能在推动生产力上的分析

像ChatGPT这样的大型语言模型正在成为强大的工具&#xff0c;不仅可以提高工人的生产力&#xff0c;还可以提高创新率&#xff0c;为经济增长的显著加速奠定基础。作为一项通用技术&#xff0c;人工智能将影响广泛的行业&#xff0c;促进对新技能的投资&#xff0c;改变业务流程…

DWG图纸在SOLIDWORKS软件里如何使用?

经常有工程师咨询DWG图纸在SOLIDWORKS软件里如何使用&#xff0c;其实这涉及到DWG图纸在SOLIDWORKS软件里的重用问题&#xff0c;SOLIDWORKS支持对DWG图纸的重用&#xff0c;常用的有三种方法&#xff1a; 1.作为原始DWG图纸查看作为原始DWG图纸查看是指使用SOLIDWORKS软件直接…