• 用servlet实现无限评论功能


    最近在写博客功能中的无限评论,比如知乎上的,我可以给根评论进行评论,也可以给子评论进行评论,下面是我做的一个简单的例子,分享给大家,希望能帮助各位,也希望可以指出缺点。

    先上图,看功能

    思路:

    1. 点击文章,获取文章的id,例如id为1
    2. 点击以后,查找文章id为1的全部评论,进行遍历(这里用到的是递归,方便观看,如上述,黄的为根评论,回复的是文章;绿的为子评论,回复的是根评论或者是其他子评论)
    3. 一开始刚发布文章肯定没有评论,所以,在最下面是发布评论,是对文章进行评论,使其有根评论,获取其根评论的id。
    4. 在有了根评论后,点击根评论后面的回复按钮,弹出一个回复的div,填写姓名和内容
    5. 点击弹出div的回复,将回复的信息添加到数据库,在进行2步骤,重新遍历;
    6. 点击子评论,同样可以出现回复的div,添加姓名和内容,点击回复按钮,在进行2步骤,遍历。
    7. 这样的缺点:遍历的话,消耗性能比较大(但我就想出来这一种,建议各位可以看看闭包表,这种评论相当于树结构,方便查找,但我脑子笨,没咋看明白)

    评论表:

    前端页面:

    页面比较丑,我只是说功能,大家可以自己去写。

    1 //这个是回复的div
    2 <div class="response_div"></div>

    这个是在js里动态生成的,只是有个父元素去装其他子元素

     //评论的div,装根评论和子评论
    评论:
            <div class="user_comments"></div>
    //发表评论的div,为根评论
    发表评论
    <div> <form id="form" onsubmit="return false" action="###" method="post"> <input id="article_id" type="hidden" name="articleId" value="${requestScope.article.get("ArticleId")}" > <p>个人昵称:<input id="user_name" type="text" name="name"></p> <p> 通知邮箱:<input id="email" type="email" name="email"></p> <p>评论内容:<input id="content" type="text" name="content"></p> <input type="button" value="提交" onclick="ajaxSelectComment()"> </form> </div>

     其他相关在js文件中:


    首先文章里没有评论,那么我在发表评论以后,点击按钮,将评论的信息通过ajax提交到servlet中(这里一开始打算用form表单的action方法直接提交,但后来感觉用ajax好一些,个人想法)

    //发表评论,先获取输入框的内容,将值作为参数传递给servlet,然后返回所有的评论
    function ajaxSelectComment() {
        let articleId=$("#article_id").val();
        let name=$("#user_name").val();
        let email=$("#email").val();
        let content=$("#content").val();
        $.ajax({
            url:"article?action=addComment",
            type:"POST",
            dataType: "json",
            data:{articleId,name,email,content},
            success:function (result) {
                alert("提交成功");
                console.log(result);
                showRootComment(result);
            },
            error:function () {
                alert("请求失败");
            }
        });
    }

    请求后,跳到servlet中

    protected void addComment(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
          //获取对应文章的id,评论的姓名,内容,以及email
            Map<String, String[]> comment = req.getParameterMap();
    //声明service层对象
    ArticleService articleService= new ArticleServicesImpl();
    //调用service层中的方法
    articleService.addComment(Integer.parseInt(comment.get("articleId")[0]),comment.get("name")[0],comment.get("content")[0],comment.get("email")[0]);
    //调用查询全部评论的方法,并将其转换成json格式(这里我将查询全部评论和转成JSON格式封装成了一个方法)
    this.returnJson(resp,this.selectUserComment(comment)); }

    //查询全部评论方法,将Map传入其中,然后获取对应文章的id
    public List<Comment> selectUserComment(Map<String, String[]> parameterMap){
    ArticleService articleService=new ArticleServicesImpl();
    return articleService.selectComment(Integer.parseInt(parameterMap.get("articleId")[0]));
    }

    //将集合转成JSON格式
    public void returnJson(HttpServletResponse resp ,Object object) throws ServletException, IOException{
    //将传过来的数组转化为JSON
    PrintWriter out = resp.getWriter();
    Gson gson=new Gson();
    String jsonComments = gson.toJson(object);//查找总的评论并且转化为数组
    System.out.println(jsonComments);
    out.write(jsonComments);
    out.flush();
    out.close();
    }

    showRootComment(result)方法:

    function showRootComment(result){
        let str="";
        console.log(result);
        $(".user_comments").empty();
        for (let i = 0; i <result.length ; i++) {
            console.log(result.length);
            if(result[i].responseId==0){//说明这个是根评论
                str="<div class='rootResponse'>
    " +"<input type='hidden' name='commentId' value="+result[i].pid+">"+
                    "#"+i+"楼"+"评论时间:"+result[i].publishTime + " | " + result[i].commentName+" <button onclick='responseDiv($(this).prev().val(),$(this).prev())'>回复<button/>
    " +
                    "<div>"+result[i].commentContent+ "</div>
    " +
                    "</div><hr>";
                $(".user_comments").append(str);
              //查询子评论
                digui(result,result[i]);
            }
        }
    }

    查询子评论方法:digui(result,result[i])

    function digui(result,comment) {
        let str='';
        console.log(result+"###"+comment);
        for (let i = 0; i <result.length ; i++) {
            console.log(comment.pid);
            if (result[i].responseId==comment.pid){//那么这个是评论的子id
                str="<div class='ziResponse'>
    " +"<input type='hidden' name='commentId' value="+result[i].pid+">"+
                    "评论时间:"+result[i].publishTime + " | " + result[i].commentName+"<button onclick='responseDiv($(this).prev().val(),$(this).prev())'>111回复<button/>
    " +
                    "<div>"+result[i].commentContent+ "</div>
    " +
                    "</div><hr>";
            //将其子评论div添加到.user_comments div中
    $(".user_comments").append(str); 
    console.log(str);
    digui(result,result[i]);
    } } }

    最后一行递归的作用:在查找到第一个子评论后,查找是否有其他子评论回复当前的子评论,如果有,则继续遍历,如果没有,则跳过


    到这的话,遍历的就ok了,下面我们看如何回复评论而不是回复文章

    每次遍历,都会有一个回复的按钮

    <button onclick='responseDiv($(this).prev().val(),$(this).prev())'>111回复<button/>

    点击回复按钮,

    $(this).prev().val()

    为获取当前元素的同胞元素的值,获取其对应的评论的id

    $(this).prev()
    获取其对应的同胞元素


    点击回复按钮,跳到 responseDiv($(this).prev().val(),$(this).prev())方法
    function responseDiv(responseId,nowElement) {
    //首先将.responsediv移除,因为在点击其他评论的回复时,其他评论的回复div将消失 $(
    ".response").remove(); let str="<div class="response"> " + " <input type="text" name="userName" placeholder="请输入用户姓名" id="user_comment_name"> " + " <input type="text" name="userComment" placeholder="请输入评论内容" id="user_comment"> " + " <input type="button" value="回复" onclick="ajaxResponse("+responseId+")"> " + " </div>"; //将这个回复div添加进这个评论的div中 nowElement.parent().append(str); }

     点击回复,跳到ajaxResponse方法中,找到回复responseId,

    function ajaxResponse(responseId) {
    //点击回复后,将回复的div移除
        $(this).prev().remove();
        //获取回复对应的文章id,回复的姓名,回复的内容
        let articleId=$("#article_id").val();
        let name=$("#user_comment_name").val();
        let content=$("#user_comment").val();
    
        $.ajax({
            url:"article?action=addUserComment",
            type:"POST",
            dataType: "json",
            data:{articleId,name,content,responseId},
            success:function (result) {
                alert("提交回复成功");
    //重新遍历
                showRootComment(result);
            },
            error:function () {
                alert("请求失败");
    
            }
        });
    }///

    servlet添加子评论的方法

      protected void addUserComment(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
            Map<String, String[]> userComment = req.getParameterMap();
            articleService.addResponse(Integer.parseInt(userComment.get("articleId")[0]),userComment.get("name")[0],userComment.get("content")[0],Integer.parseInt(userComment.get("responseId")[0]));
           this.returnJson(resp,this.selectUserComment(userComment));
        }

    添加回复,首先出现一个回复的div,填写回复的信息,点击回复按钮,将回复的内容添加到数据库,然后返回所有的评论,继续遍历,思路基本上就是这样

    service层方法:

     /**
         * 添加的是根评论
         * @param articleId
         * @param name
         * @param content
         * @param email
         */
        @Override
        public void addComment(int articleId, String name, String content, String email) {
                articleDao.addComment(articleId,name,content,email);
            //先查找对应文章的评论有多少
            long commentSum=articleDao.selectCommentsSum(articleId);
            //修改对应文章中评论的数量
            articleDao.insertCommentsSum(commentSum,articleId);
    
        }
       /**
         * 查找对应文章的评论
         * @param articleId
         * @return
         */
        @Override
        public List<Comment> selectComment(int articleId) {
            return  articleDao.selectComment(articleId);
        }
     /**
         * 添加对应文章的评论,子评论
         * @param articleId
         * @param commentName
         * @param commentContent
         * @param responseId
         */
        @Override
        public void addResponse(int articleId,String commentName,String commentContent,int responseId) {
                articleDao.addUserComment( articleId, commentName, commentContent,responseId);
        }

    dao层方法:

    /**
    *查找对应文章的全部评论
    */
     public List<Comment> selectComment(int articleId) {
            List<Comment> comments=null;
            String sql= "SELECT * FROM COMMENT WHERE Article_Id=?";
            try {
                 comments = queryRunner.query(sql, new BeanListHandler<Comment>(Comment.class), articleId);
            } catch (SQLException e) {
                e.printStackTrace();
            }
    
            return comments;
        }
    /**
         * 添加根评论
         * @param articleId
         * @param name
         * @param content
         * @param email
         */
        @Override
        public void addComment(int articleId, String name, String content, String email) {
                String sql="INSERT  INTO COMMENT (Article_Id,CommentName,CommentContent,email) VALUES(?,?,?,?) ";
                Object[] parms={articleId,name,content,email};
            try {
                queryRunner.update(sql,parms);
            } catch (SQLException e) {
                e.printStackTrace();
            }
        }
    /**
         * 添加子评论
         * @param articleId
         * @param commentName
         * @param commentContent
         * @param responseId
         */
        @Override
        public void addUserComment(int articleId,String commentName,String commentContent,int responseId) {
            String sql="INSERT INTO COMMENT (Article_Id,CommentName,CommentContent,ResponseId) VALUES(?,?,?,?)";
            Object[] parms={articleId,commentName,commentContent,responseId};
            try {
                queryRunner.update(sql,parms);
            } catch (SQLException e) {
                e.printStackTrace();
            }
        }

    这就是关于评论的所有操作,如果大家有疑惑或者更好的建议,在评论区留言,看到会立即回复!

  • 相关阅读:
    实现在Android本地视频播放器开发
    敏捷开发的4个中心思想
    PHP如何大幅度提升运行效率? 把它编译成机器码!
    卸载Oracle数据库(有图有真相)
    宁波理工邀请赛 c zoj3185解题报告
    FRG图像文件格式的压缩质量
    另类的文件夹加密(批处理实现)
    代码详查中的自尊心
    [C# 网络编程系列]专题十:实现简单的邮件收发器
    php中获得客户端,服务器ip
  • 原文地址:https://www.cnblogs.com/BLACKJT/p/12630096.html
Copyright © 2020-2023  润新知