基于 Spring Boot 博客系统开发(六)

news2024/11/24 14:35:22

基于 Spring Boot 博客系统开发(六)

本系统是简易的个人博客系统开发,为了更加熟练地掌握 SprIng Boot 框架及相关技术的使用。🌿🌿🌿
基于 Spring Boot 博客系统开发(五)👈👈

文章详情页实现

在Controller类中,编写处理HTTP请求的方法来获取文章详情并返回视图。
HomeController.java

	@RequestMapping("/article/{id}")
    public String article(@PathVariable Long id,Model model){
        Article article = articleService.getById(id);
        if(article == null){
            return "error/404";
        }
        model.addAttribute("article",article);
        return "client/article";
    }

修改视图中代码。article.html

<title th:text="${article.title}">函数式接口</title>
    <article class="main-content post-page">
        <div class="post-header">
            <h1 class="post-title" itemprop="name headline" th:text="${article.title}">函数式接口</h1>
            <div class="post-data">
                <time datetime="2018-12-01" itemprop="datePublished"  >发布于 [[${article.created}]]</time>
            </div>
        </div>
        <br />
        <div id="post-content" class="post-content content" th:utext="${@textUtils.md2Html(article.content)}"></div>
    </article>

渲染后效果
在这里插入图片描述

文章评论实现

评论用户登录渲染

用户评论前需要进行登录

<span th:if="${@loginUtils.isLogin()}" class="response">
     Hello,<a data-no-instant="" th:text="${@loginUtils.getLoginUser().username}">admin</a>
     如果你想 <a href="/logout">注销</a> ?
</span>
<span th:unless="${@loginUtils.isLogin()}" class="response">
        用户想要评论,请先<a href="/login" title="登录" target="_blank" data-no-instant="">登录</a>!
</span>

LoginUtils.java

@Component
public class LoginUtils {

    @Autowired
    public HttpServletRequest request;

    public boolean isLogin(){
        Object loginUser = request.getSession().getAttribute("loginUser");
        return loginUser!=null;
    }

    public User getLoginUser(){
        Object loginUser = request.getSession().getAttribute("loginUser");
        if(loginUser instanceof User){
            return (User)loginUser;
        }
        return null;
    }
}

用户登录前渲染效果:
在这里插入图片描述
用户登录后渲染效果:
在这里插入图片描述

评论列表渲染

创建CommentController.java,查询指定文章ID的评论列表并分页,以JSON格式返回。
这里注意要写@ResponseBody

@Controller
@RequestMapping("/comment")
public class CommentController {

    @Autowired
    private ICommentService commentService;

    @RequestMapping("/list")
    @ResponseBody
    public PageInfo<Comment> list(Long articleId,@RequestParam(defaultValue = "1") Integer pageNum){
        PageHelper.startPage(pageNum,3);
        QueryWrapper<Comment> query = new QueryWrapper<>();
        query.eq("article_id",articleId);
        List<Comment> list = commentService.list(query);
        PageInfo<Comment> page = new PageInfo<>(list);
        return page;
    }
}

前端代码,需要引入JQ。由于之前有统一引入到公共JS里了,所以这里不需要引入。
引入JQ

<script src="/assets/js/jquery.min.js"></script>

HTML中添加文章ID

 <form id="comment-form" class="comment-form" role="form" >
       <input type="hidden" name="articleId" id="aid" th:value="${article.id}">
       <textarea name="content" id="textarea" class="form-control" placeholder="以上信息可以为空,评论不能为空哦!" required="required" minlength="5" maxlength="2000"></textarea>
       <button type="button" class="submit" id="misubmit">提交</button>
</form>

编写渲染评论列表的JS脚本。这里没有使用模板技术,采用原生文本拼接。

 <script type="text/javascript">
        function loadComment(pageNum){
            $.ajax({
                type: 'get',
                url: '/comment/list',
                data: {articleId:$("#aid").val(),pageNum:pageNum},
                async: true,
                dataType: 'json',
                success: function (result) {
                    console.log(result)
                    let templates = '';
                    $.each(result.list,function (i,o){
                        // 渲染模板
                       templates += '<li id="li-comment-15" class="comment-body comment-parent comment-odd">\n' +
                            '                                <div id="comment-15">\n' +
                            '                                    <div class="comment-view" οnclick="">\n' +
                            '                                        <div class="comment-header">\n' +
                            '                                            <!--设置人物头像和名称-->\n' +
                            '                                            <img class="avatar" src="/assets/img/avatars.jpg" height="50">\n' +
                            '                                            <a class="comment-author" rel="external nofollow">'+o.author+'</a>\n' +
                            '                                        </div>\n' +
                            '                                        <!-- 评论内容 -->\n' +
                            '                                        <div class="comment-content">\n' +
                            '                                            <span class="comment-author-at"></span>\n' +
                            '                                            <p></p><p>'+o.content+'</p>\n' +
                            '    <p></p>\n' +
                            '                                        </div>\n' +
                            '                                        <!-- 评论日期 -->\n' +
                            '                                        <div class="comment-meta">\n' +
                            '                                            <time class="comment-time">'+o.created+'</time>\n' +
                            '\n' +
                            '                                        </div>\n' +
                            '                                    </div>\n' +
                            '                                </div>\n' +
                            '                            </li>';
                    })
                    $(".comment-list").html(templates);

                    let pageText = '';
                    $.each(result.navigatepageNums,function (i,o){
                        pageText +=
                            '<li class="'+(o==result.pageNum?'current':'')+'">' +
                            '<a>'+o+'</a>' +
                            '</li>';
                    });
                    $(".page-navigator").html(pageText);
                    $(".page-navigator a").click(function (){
                        let pageNum = $(this).text();
                        loadComment(parseInt(pageNum));
                    });
                }
            });
        }
        loadComment(1);
    </script>

渲染效果:
在这里插入图片描述

评论提交实现

后端 CommentController 添加评论方法

@Controller
@RequestMapping("/comment")
@Slf4j
public class CommentController {

    @Autowired
    private ICommentService commentService;

    @RequestMapping("/list")
    @ResponseBody
    public PageInfo<Comment> list(Long articleId,@RequestParam(defaultValue = "1") Integer pageNum){
        PageHelper.startPage(pageNum,3);
        QueryWrapper<Comment> query = new QueryWrapper<>();
        query.eq("article_id",articleId);
        List<Comment> list = commentService.list(query);
        PageInfo<Comment> page = new PageInfo<>(list);
        return page;
    }

    @Autowired
    private LoginUtils loginUtils;

    @PostMapping("/add")
    @ResponseBody
    public AjaxResult add(Comment comment, HttpServletRequest request){
        comment.setCreated(new Date()); //实体created 属性修改成Date类型
        comment.setIp(request.getRemoteAddr());
        User loginUser = loginUtils.getLoginUser();
        if(loginUser == null){
            return new AjaxResult(-1,"请先登录");
        }
        comment.setAuthor(loginUser.getUsername());
        try {
            commentService.save(comment);
            return AjaxResult.success();
        }catch (Exception e){
            log.error(e.getMessage());
        }
       return  AjaxResult.error();
    }

}

创建AjaxResult 用于返回异步状态结果
AjaxResult.java

@Data
public class AjaxResult {

    private int code = 0;
    private String msg ="操作成功" ;
    private Object data;

    public AjaxResult() {
    }

    public AjaxResult(int code, String msg) {
        this.code = code;
        this.msg = msg;
    }

    public AjaxResult(int code, String msg, Object data) {
        this.code = code;
        this.msg = msg;
        this.data = data;
    }
    public static AjaxResult success(){
        return new AjaxResult();
    }
    public static AjaxResult error(){
        return new AjaxResult(-1,"未知错误");
    }
}

前端提交的HTML

  <div>
        <form id="comment-form" class="comment-form" role="form"  >
             <input type="hidden" name="articleId" id="aid" th:value="${article.id}">
             <textarea name="content" id="textarea" class="form-control" placeholder="以上信息可以为空,评论不能为空哦!" required="required" minlength="5" maxlength="2000"></textarea>
             <button type="button" class="submit" id="misubmit">提交</button>
        </form>
  </div>

提交评论的JS脚本

 $("#misubmit").click(function (){

                $.ajax({
                    type: 'post',
                    url: '/comment/add',
                    data: {articleId:$("#aid").val(),content:$("#textarea").val()},
                    async: false,
                    dataType: 'json',
                    success: function (result) {
                        if(result.code == 0){
                            alert("评论成功");
                            window.location.reload();
                        }else{
                            alert(result.msg)
                        }
                    }
                });
            });
成功提交评论效果:

在这里插入图片描述

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

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

相关文章

商标不做检索分析,直接申请通过率很低!

今天有个网友拿到驳回通知书找到普推知产老杨&#xff0c;让分析驳回通过率如何&#xff0c;他主要两个文字商标和两个图形商标&#xff0c;文字商标都是两个字的&#xff0c;两个字的商标名称基本都有相同或高近&#xff0c;引用了好几个高度近似&#xff0c;直接做驳回复审通…

Unity 性能优化之光照优化(七)

提示&#xff1a;仅供参考&#xff0c;有误之处&#xff0c;麻烦大佬指出&#xff0c;不胜感激&#xff01; 文章目录 前言一、测试目的一、实时光源是什么&#xff1f;二、开始测试1.场景中只有一个光照的数值情况2.添加4个点光源后4.结果 总结 前言 实时光源数量越多&#x…

【前端】创建跳动字符效果的前端技术实现

创建跳动字符效果的前端技术实现 在前端开发中&#xff0c;动态视效能够显著增强用户体验。本文介绍一种实现字符跳动效果的技术方案&#xff0c;通过简单的HTML、CSS和JavaScript代码&#xff0c;你可以为网页文本添加生动的交互动画。这种效果可以用于吸引用户注意、增强品牌…

<网络安全>《77 概念讲解<第十课 物联网常用协议-(近距离通信)感应层协议>》

协议简称全称名称内容说明RFIDRadio Frequency Identification射频识别阅读器与标签之间进行非接触式的数据通信&#xff0c;达到识别目标的目的。RFID的应用非常广泛&#xff0c;典型应用有动物晶片、汽车晶片防盗器、门禁管制、停车场管制、生产线自动化、物料管理。完整的RF…

SQLI-labs-第十三关和第十四关

目录 第十三关 1、判断注入点 2、判断当前数据库 3、爆表名 4、爆字段名 5、爆值 第十四关 1、判断注入点 知识点&#xff1a;POST方式的单引号和括号闭合错误,报错注入 第十三关 思路&#xff1a; 1、判断注入点 使用Burpsuite抓包 首先加入一个单引号&#xff0c;…

【管理篇】管理三步曲:团队建设(二)

目录标题 如何着手团队建设提升个人能力1、要提升员工的什么能力2、提升员工个人能力的初衷是什么&#xff1f;3、如何达成上述目标4、应该如何激发员工学习的动力和意愿呢5、关于提升员工的能力&#xff0c;有两个信念特别重要&#xff1a; 提升员工的工作意愿和积极性1、管理…

2024年中国AI大模型产业发展报告,洞见下一个智能时代!

人民网财经研究院、至顶科技联合发布的《开启智能新时代&#xff1a;2024年中国AI大模型产业发展报告》,全面梳理了我国AI大模型产业的发展背景、现状、应用案例、面临的挑战以及未来趋势。报告指出,AI大模型是全球科技竞争的新高地、未来产业的新赛道、经济发展的新引擎,在我国…

HIVE统计WordCount

HIVE WORDCOUNT 目录 HIVE WORDCOUNT 一、WORDCOUNT 1.我们先创建一个新的数据库 2.创建表并插入数据 3.统计WORDCOUNT 4.UNION ALL 用法 5.WITH AS 用法 1.WORDCOUNT 1&#xff09;我们先创建一个新的数据库 create database learn3;use learn3; 2&#xff09;创建表…

Docker 入门篇(六)-- idea 打包 docker 镜像流程

环境准备&#xff1a; idea 环境&#xff1a;IntelliJ IDEA 2021.3.1 (Ultimate Edition)docker 版本&#xff1a;v. 26.1.0准备 springboot jar 文件 &#xff1a;target/DockerDemo-0.0.1-SNAPSHOT.jardocker 可视化管理工具 portainer &#xff1a;v2.6.0 一. 配置docker远…

node.js+vue3 实现

目录 一、node.jsvue3 1.1 node安装 1.2 node.jsvue3预期 二、项目及程序代码 2.1 创建项目 2.2 Node.js 服务器 (server.js) 2.3 public/index.html 2.4 src/main.js 2.5 src/App.vue 2.6 vue.config.js 三、编译实现 3.1 安装必要的依赖 3.2 运行Node.js服务器 …

04-25 周四 FastBuild重构实践-TLS、全局捕获异常、一键配置

04-25 周四 FastBuild重构实践 时间版本修改人描述04-25V0.1宋全恒新建文档2024年5月6日14:33:16V1.0宋全恒完成文档撰写 简介 由于 04-22 周日 阿里云-瑶光上部署FastBuild过程(配置TLS、自定义辅助命令)描述了重新部署一个FastBuild实例的过程&#xff0c;通过阅读这个&…

ADS过孔---过孔建模自动化

当前快速建模的方法有两类&#xff1a;一是脚本自动化&#xff0c;也就是今天要分享的方法&#xff0c;但该方法需要工程师有基本的脚本编辑能力&#xff0c;然后根据自己的需要去修改&#xff0c;难度较大一点点&#xff1b;二是参数化建模&#xff0c;也就是在GUI界面输入相应…

基于 Spring Boot 博客系统开发(七)

基于 Spring Boot 博客系统开发&#xff08;七&#xff09; 本系统是简易的个人博客系统开发&#xff0c;为了更加熟练地掌握 SprIng Boot 框架及相关技术的使用。&#x1f33f;&#x1f33f;&#x1f33f; 基于 Spring Boot 博客系统开发&#xff08;六&#xff09;&#x1f…

远程连接是什么?

远程连接是指通过网络连接两个或多个设备&#xff0c;实现远程访问、控制或传输数据的技术。它在现代科技发展中起到了重要作用&#xff0c;使得我们可以随时随地与远程设备进行交互、管理和操作。 天联组网是一种高效的远程连接解决方案&#xff0c;它因为操作简单、跨平台应用…

算法(C++

题目&#xff1a;螺旋矩阵&#xff08;59. 螺旋矩阵 II - 力扣&#xff08;LeetCode&#xff09;&#xff09; 给你一个正整数 n &#xff0c;生成一个包含 1 到 n2 所有元素&#xff0c;且元素按顺时针顺序螺旋排列的 n x n 正方形矩阵 matrix 。 示例 1&#xff1a; 输入&am…

IT养生知识之:子午流注

《子午流注口诀》 肺寅大卯胃辰宫&#xff0c; 脾巳心午小未中&#xff0c; 申膀酉肾心包戌&#xff0c; 亥焦子胆丑肝通。 何为子午流注&#xff1f; 子午流注是中医圣贤发现的一种规律&#xff0c;中医认为人体中十二条经脉对应着每日的十二个时辰&#xff0c;由于时辰在…

计算机网络4——网络层8 软件定义网络 SDN

文章目录 一、介绍1、简介2、原理3、案例1&#xff09;普通2&#xff09;负载均衡的例子3&#xff09;防火墙的例子 二、控制层面1、特征2、层次 一、介绍 1、简介 SDN的概念最初由斯坦福大学N.McKeown于2009年首先提出。当时还只是在学术界进行探讨的一种新的网络体系结构。…

springboot+mp自动生成没有实体类

mybatisX版本冲突问题 一开始我的MyBatisX版本是1.6.1-3,使用mybatis-plus一直不能正常生成实体类 将MyBatisX的版本换成了1.5.7就可以了 MyBatisX版本更换 1.将原有的MyBatisX卸载后重新安装一个新的版本 2.选择一个合适的版本,这里我选的是1.5.7 下载完成后自己选择一个…

css实现上下左右对勾选中状态角标

&#x1f365;左上角 &#x1f365;右上角 &#x1f365;左下角 &#x1f365;右下角: &#x1f365;左上角: .blueBackground {position: relative;border: 1px solid #91c7f3;background: #F0F8FF !important;&:after {content: "";position: absolute;top:…

【Java从入门到精通】Java 重写(Override)与重载(Overload)

重写(Override) 重写&#xff08;Override&#xff09;是指子类定义了一个与其父类中具有相同名称、参数列表和返回类型的方法&#xff0c;并且子类方法的实现覆盖了父类方法的实现。 即外壳不变&#xff0c;核心重写&#xff01; 重写的好处在于子类可以根据需要&#xff0c…