Comment module of springboot personal blog system

Personal blog system development is briefly divided into five modules

  1. Homepage

  2. Login function

  3. Comment management

  4. Article management

  5. Email management

A complete blog system, the front-end page can display and publish comments, comment users can reply to each other, and the back-end can manage the comment content. Due to limited space, the article comments of this project will implement functions such as front-end comment display and comment publishing.

This issue introduces to you the comment management module

1.Business processing layer implementation

When viewing article details, the Mapper interface file for the Comments operation database has been written. Here, the related business of comment management is processed directly from the Service business layer.

(1) Write Service layer interface method

Write a method to publish article comments in the comment business interface file ICommentService. The sample code is as follows.

 // User comments
      public void pushComment(Comment comment) {<!-- -->
(2) Write Service layer interface implementation class method

Implement the new comment publishing method in the comment business layer interface implementation class CommentServicelmpl. The sample code is as follows.

 // User comments
    @Override
    public void pushComment(Comment comment) {
        commentMapper.pushComment(comment);
        //Update article comment data volume
        Statistic statistic = statisticMapper.selectStatisticWithArticleId(comment.getArticleId());
        statistic.setCommentsNum(statistic.getCommentsNum() + 1);
        statisticMapper.updateArticleCommentsWithId(statistic);
    }

In the above code, in the comment publishing method of CommentServicelmpl, the comment data publishing operation is first performed, and then
Zhou used the relevant methods of the statistical interface file statisticMapper to statistically update the number of article comment information.

2. Request processing layer implementation

2.1 Create a user comment management control class CommentController under the com.itheima.web.client package, and compile
The corresponding request control method is as follows.
package com.itheima.web.client;

import com.itheima.model.ResponseData.ArticleResponseData;
import com.itheima.model.domain.Comment;
import com.itheima.service.ICommentService;
import com.itheima.utils.MyUtils;
import com.vdurmont.emoji.EmojiParser;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.core.userdetails.User;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;

import javax.servlet.http.HttpServletRequest;
import java.util.Date;


/**
 * @version 1.0
 * @Author LDX
 * @Date 2023/11/3 17:02
 * @annotation
 */

@Controller
@RequestMapping("/comments")
public class CommentController {
    private static final Logger logger = LoggerFactory.getLogger(CommentController.class);

    @Autowired
    private ICommentService commentServcieImpl;

    // Post comment operation
    @PostMapping(value = "/publish")
    @ResponseBody
    public ArticleResponseData publishComment(HttpServletRequest request, @RequestParam Integer aid, @RequestParam String text) {
        //Remove js script
        text = MyUtils.cleanXSS(text);
        text = EmojiParser.parseToAliases(text);
        // Get the current logged in user
        User user=(User) SecurityContextHolder.getContext().getAuthentication().getPrincipal();
        //Encapsulate comment information
        Comment comments = new Comment();
        comments.setArticleId(aid);
        comments.setIp(request.getRemoteAddr());
        comments.setCreated(new Date());
        comments.setAuthor(user.getUsername());
        comments.setContent(text);
        try {
            commentServcieImpl.pushComment(comments);
            logger.info("Posted comment successfully, corresponding article id: " + aid);
            return ArticleResponseData.ok();
        } catch (Exception e) {
            logger.error("Failed to post comment, corresponding article id: " + aid + "; Error description: " + e.getMessage());
            return ArticleResponseData.fail();
        }
    }
}

2.2 The publishComment() method is used to publish comments and handle requests with the path “/comments/publish*. If the user posts a comment, the user’s comment information will first be obtained and encapsulated, then the comment information will be inserted into the database, and finally based on The database operation result prompts the user whether the comment was successfully posted.

3. Implement front-end page functions

3.1 Open the comments.html file in the client folder to realize the display of comments on the front-end page. The core code of comments.html on the article comment page is as follows.

<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org" th:fragment="comments"
      xmlns:sec="http://www.thymeleaf.org/thymeleaf-extras-springsecurity5">
<body>
<div th:if="${article}!=null">
    <div th:id="${article.id ?: 0}" class="comment-container">
        <div id="comments" class="clearfix">
            <div th:if="${article.allowComment}">
                <span class="response">
                    <form name="logoutform" th:action="@{/logout}" method="post"></form>
                    <th:block sec:authorize="isAuthenticated()">
                        Hello, <a data-no-instant="" sec:authentication="name"></a>
                        If you want to <a href="javascript:document.logoutform.submit();">Logout</a> ?
                    </th:block>
                    <th:block sec:authorize="isAnonymous()">
                        If users want to comment, please <a th:href="@{/login}" title="Login" data-no-instant="">Log in</a>!
                    </th:block>
                </span>
                <div sec:authorize="isAuthenticated()">
                    <form id="comment-form" class="comment-form" role="form" onsubmit="return TaleComment.subComment();">
                        <input type="hidden" name="aid" id="aid" th:value="${article.id}"/>
                        <input type="hidden" th:name="${_csrf.parameterName}" th:value="${_csrf.token}"/>
                        <textarea name="text" id="textarea" class="form-control" placeholder="The above information can be empty, but the comment cannot be empty!"
                                  required="required" minlength="5" maxlength="2000"></textarea>
                        <button type="submit" class="submit" id="misubmit">Submit</button>
                    </form>
                </div>
            </div>
            <!-- Display other comments in pagination -->
            <div th:if="${comments}">
                <ol class="comment-list">
                    <th:block th:each="comment :${comments.list}">
                        <li th:id="'li-comment-' + ${comment.id}" class="comment-body comment-parent comment-odd">
                            <div th:id="'comment-' + ${comment.id}">
                                <div class="comment-view" onclick="">
                                    <div class="comment-header">
                                        <!--Set character avatar and name-->
                                        <img class="avatar" th:src="@{/assets/img/avatars.jpg}" height="50"/>
                                        <a class="comment-author" rel="external nofollow" th:text="${comment.author}" />
                                    </div>
                                    <!-- Comment content -->
                                    <div class="comment-content">
                                        <span class="comment-author-at"></span>
                                        <p th:utext="${commons.article(comment.content)}"></p>
                                    </div>
                                    <!-- Date of comment -->
                                    <div class="comment-meta">
                                        <time class="comment-time" th:text="${commons.dateFormat(comment.created)}"></time>
                                        <a sec:authorize="isAuthenticated()" th:if="${comment.author}!= ${session.SPRING_SECURITY_CONTEXT.authentication.principal.username}" href="javascript:void(0 )" style="color: #1b961b">
                                             & amp;nbsp; & amp;nbsp; & amp;nbsp; & amp;nbsp; & amp;nbsp;Reply
                                        </a>
                                    </div>
                                </div>
                            </div>
                        </li>
                    </th:block>
                </ol>
                <!-- Paginate comments -->
                <div class="lists-navigator clearfix">
                    <ol class="page-navigator">
                        <!-- 2 Judge and display the previous page -->
                        <th:block th:if="${comments.hasPreviousPage}">
                            <li class="prev"><a th:href="'?cp=' + ${comments.prePage} + '#comments'">Previous page</a></li>
                        </th:block>
                        <!-- Determine and display the middle page -->
                        <th:block th:each="navIndex : ${comments.navigatepageNums}">
                            <th:block th:if="${comments.pages} <= 5">
                                <li th:class="${comments.pageNum}==${navIndex}?'current':''">
                                    <a th:href="'?cp=' + ${navIndex} + '#comments'" th:text="${navIndex}"></a>
                                </li>
                            </th:block>
                            <th:block th:if="${comments.pages} > 5">
                                <li th:if="${comments.pageNum <=3 & amp; & amp; navIndex <= 5}" th:class="${comments.pageNum}==${navIndex}?' current':''">
                                    <a th:href="'?cp=' + ${navIndex} + '#comments'" th:text="${navIndex}"></a>
                                </li>
                                <li th:if="${comments.pageNum >= comments.pages-2 & amp; & amp; navIndex > comments.pages-5}" th:class="${comments.pageNum}== ${navIndex}?'current':''">
                                    <a th:href="'?cp=' + ${navIndex} + '#comments'" th:text="${navIndex}"></a>
                                </li>
                                <li th:if="${comments.pageNum >=4 & amp; & amp; comments.pageNum <= comments.pages-3 & amp; & amp; navIndex >= comments.pageNum-2 & amp; & amp; navIndex <= comments.pageNum + 2}" th:class="${comments.pageNum}==${navIndex}?'current':''">
                                    <a th:href="'?cp=' + ${navIndex} + '#comments'" th:text="${navIndex}"></a>
                                </li>
                            </th:block>
                        </th:block>
                        <!-- Judge and display the next page -->
                        <th:block th:if="${comments.hasNextPage}">
                            <li class="next"><a th:href="'?cp=' + ${comments.nextPage} + '#comments'">Next page</a></li>
                        </th:block>
                    </ol>
                </div>
            </div>
        </div>
    </div>
</div>
</body>
<div th:replace="comm/tale_comment::tale_comment"></div>
</html>
Mainly uses the sec* and th* attributes to manage and control the comment box and obtain and display the comment list.

In the comment publishing box control, only logged in users can view the comment box and post comments. In lines 22-23 of the cform> form posted in the comment, a hidden field “cinput type=’hidden” thiname=’Y{_csrt,parameterName)\ is added for CSRF Token authentication during CSRF defense. ” th:value=”y(_csrf.token)”/>”.
Use the th:replace attribute at the bottom of the comments.html page, and call the TaleComment.subComment() method in the comm/tale_comment page in the comment publishing

form to make a comment publishing request. Open tale_comment.htm1 in the common folder to view the content as shown below.

<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org" th:fragment="tale_comment" >
<body>
<script type="text/javascript">
    /*<![CDATA[*/
    (function () {
        window.TaleComment = {
            subComment: function () {
                    $.ajax({
                    type: 'post',
                    url: '/comments/publish',
                    data: $('#comment-form').serialize(),
                    async: false,
                    dataType: 'json',
                    success: function (result) {
                        if (result & amp; & amp; result.success) {
                            window.alert("Comment submitted successfully!");
                            window.location.reload();
                        } else {
                            window.alert("The comment exceeds the maximum length limit of 200 words")
                            if (result.msg) {
                                alert(result.msg);
                            }
                        }
                    }
                });
                return false;
            }
        };
    })();
</script>
</body>
</html>

In the above file, Ajax is used to send a POST request, and the result returned by the request is encapsulated in result. According to the result
If different prompt messages are displayed on the page.

4. Effect display

Start the project for testing. After the project is started successfully, first log in and enter an article details page; then, at the bottom of the article
Post comments in the comment box to test the effect

The results are as shown in the figure