博客项目(八)——博客页面后台

一.页面介绍

在之前的项目一文章中,提到了功能划分。我们知道了用户有两种情况,管理员和一般用户。也知道了这两种用户可以完成什么功能。而博客页面就是要把这些功能经过后台处理显示在前台。

这个博客页面的规划参照了一些博客,例如CSDN的规划。我们将这个主页上需要的导航进行拆分,确保每个JSP完成不同的任务,可以在不同的页面进行引用。

1.1 公共页面framework.jsp

在这个页面中会显示站点基本信息,和引入侧边栏和博客页脚页面。

<%@ page language="java" contentType="text/html; charset=UTF-8"
         pageEncoding="UTF-8" %>
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>
<%@ taglib uri="http://java.sun.com/jsp/jstl/fmt" prefix="fmt" %>
<%@ taglib uri="http://java.sun.com/jsp/jstl/functions" prefix="fn" %>
<%@ taglib prefix="rapid" uri="http://www.rapid-framework.org.cn/rapid" %>
<!DOCTYPE html>
<html lang="zh-CN">
<head>
    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta http-equiv="Cache-Control" content="max-age=72000"/>
    <meta name="viewport"
          content="width=device-width, initial-scale=1.0, minimum-scale=1.0, maximum-scale=1.0, user-scalable=no">
    <!-- 上述3个meta标签*必须*放在最前面,任何其他内容都*必须*跟随其后! -->
    <meta name="applicable-device" content="pc,mobile">
    <meta name="MobileOptimized" content="width"/>
    <meta name="HandheldFriendly" content="true"/>
    <link rel="shortcut icon" href="/img/logo.png">
    <rapid:block name="description">
        <meta name="description" content="${options.optionMetaDescrption}"/>
    </rapid:block>
    <rapid:block name="keywords">
        <meta name="keywords" content="${options.optionMetaKeyword}"/>
    </rapid:block>
    <rapid:block name="title">
        <title>
                ${options.optionSiteTitle}-${options.optionSiteDescrption}
        </title>
    </rapid:block>
    <link rel="stylesheet" href="/css/style.css">
    <link rel="stylesheet" href="/plugin/font-awesome/css/font-awesome.min.css">

    <rapid:block name="header-style">

    </rapid:block>
</head>
<body>
<div id="page" class="site" style="transform: none;">

    <%@ include file="part/header.jsp" %>
    <div id="content" class="site-content" style="transform: none;">
        <rapid:block name="left"></rapid:block>
        <rapid:block name="right">
            <%@ include file="part/sidebar-1.jsp" %>
        </rapid:block>
    </div>
    <div class="clear"></div>
    <rapid:block name="link"></rapid:block>
    <%@ include file="part/footer.jsp" %>

</div>

<script src="/js/jquery.min.js"></script>
<script src="/js/superfish.js"></script>
<script src='/js/sticky.js'></script>
<script src="/js/script.js"></script>
<script src="/plugin/layui/layui.all.js"></script>


<rapid:block name="footer-script"></rapid:block>

</body>
</html>

1.2 侧边栏页面

因为每个页面的侧边栏页面不同,所以有许多侧边栏页面。

sidebar1.jsp:正文右边侧边栏。包含搜索框,显示热评文章(文章在后台是链接形式,可以发送请求,跳转到这个页面),显示所有标签(同文章一样,可以进行点击查看,查看的是这个标签下的所有文章),显示随机文章(也可以点击查看)。

<%--
    一般用于正文侧边栏:
   包括 搜索,热评文章,所有标签,随机文章
--%>

<%@ page language="java" contentType="text/html; charset=UTF-8"
         pageEncoding="UTF-8" %>
<%--博客主体-右侧侧边栏 start--%>
<div id="sidebar" class="widget-area all-sidebar"
     style="position: relative; overflow: visible; box-sizing: border-box; min-height: 1px;">

    <%--搜索框--%>
    <aside class="widget widget_search">
        <div class="searchbar">
            <form method="get" id="searchform1" action="/search">
                    <span> <input type="text" value="" name="keywords" id="s1" placeholder="输入搜索内容" required="">
                        <button type="submit" id="searchsubmit1">搜索</button>
                    </span>
            </form>
        </div>
        <div class="clear"></div>
    </aside>
    <%--搜索框--%>

    <%--热评文章 start--%>
    <aside class="widget hot_comment" >
        <h3 class="widget-title">
            <i class="fa fa-bars"></i>热评文章
        </h3>
        <div id="hot_comment_widget">
            <ul>
                <c:forEach items="${mostCommentArticleList}" var="m">
                    <li>
                        <a href="/article/${m.articleId}" rel="bookmark" title=" (${m.articleCommentCount}条评论)">
                                ${m.articleTitle}
                        </a>
                    </li>
                </c:forEach>
            </ul>
        </div>
        <div class="clear"></div>
    </aside>
    <%--热评文章 end--%>

    <%--所有标签 start--%>
    <aside class="widget">
        <h3 class="widget-title">
            <i class="fa fa-bars"></i>所有标签
        </h3>
        <div class="tagcloud">
            <c:forEach items="${allTagList}" var="t">
                <a href="/tag/${t.tagId}"
                   class="tag-link-129 tag-link-position-1"
                   style="font-size: 14px;">
                        ${t.tagName}
                </a>
            </c:forEach>
            <div class="clear"></div>
        </div>
        <div class="clear"></div>
    </aside>
    <%--所有标签 end--%>

    <%--博客主体-右侧侧边栏-随机文章 start--%>
    <aside id="random_post-7" class="widget random_post wow fadeInUp" data-wow-delay="0.3s">
        <h3 class="widget-title">
            <i class="fa fa-bars"></i>随机文章
        </h3>
        <div id="random_post_widget">
            <ul>
                <c:forEach items="${randomArticleList}" var="r">
                    <li>
                        <a href="/article/${r.articleId}" rel="bookmark">
                                ${r.articleTitle}
                        </a>
                    </li>
                </c:forEach>
            </ul>
        </div>
        <div class="clear"></div>
    </aside>
    <%--博客主体-右侧侧边栏-近期文章 end--%>

</div>
<%--博客主体-右侧侧边栏 end--%>

siderbar2.jsp:首页右边侧边栏。包含显示站点信息(头像,标题,内容,文章数和留言数),显示网站概况(文章总数,留言总数,分类数量,标签数量,浏览总数和最后更新),显示所有标签,显示最新评论(点击跳转到文章下的评论)。

<%--
    一般用于首页侧边栏:
    包括 关于本站,网站概况,热评文章,所有标签,随机文章 等小工具

--%>
<%@ page language="java" contentType="text/html; charset=UTF-8"
         pageEncoding="UTF-8" %>
<%--博客主体-右侧侧边栏 start--%>
<div id="sidebar" class="widget-area all-sidebar"
     style="position: relative; overflow: visible; box-sizing: border-box; min-height: 1px;">

    <%--关于本站 start--%>
    <aside class="widget about">
        <h3 class="widget-title">
            <i class="fa fa-bars"></i>关于本站
        </h3>
        <div id="feed_widget">
            <div class="feed-about">
                <div class="about-main">
                    <div class="about-img">
                        <img src="${options.optionAboutsiteAvatar}"
                        alt="QR Code">
                    </div>
                    <div class="about-name">${options.optionAboutsiteTitle}</div>
                    <div class="about-the">
                        ${options.optionAboutsiteContent}
                    </div>
                </div>
                <div class="clear"></div>

                <div class="about-inf">
                    <span class="about-pn">文章 ${siteBasicStatistics[0]} </span>
                    <span class="about-cn">留言 ${siteBasicStatistics[1]} </span>
                </div>
            </div>
        </div>
        <div class="clear"></div>
    </aside>
    <%--关于本站 start--%>

    <%--网站概况 start--%>
    <aside id="php_text-22" class="widget php_text">
        <h3 class="widget-title">
            <i class="fa fa-bars"></i>网站概况
        </h3>
        <div class="textwidget widget-text">
            <ul class="site-profile">
                <li><i class="fa fa-file-o"></i> 文章总数:${siteBasicStatistics[0]} 篇</li>
                <li><i class="fa fa-commenting-o"></i> 留言数量:${siteBasicStatistics[1]} 条</li>
                <li><i class="fa fa-folder-o"></i> 分类数量:${siteBasicStatistics[2]} 个</li>
                <li><i class="fa fa-tags"></i> 标签总数:${siteBasicStatistics[3]} 个</li>
                <li><i class="fa fa-link"></i> 链接数量:${siteBasicStatistics[4]} 个</li>
                <li><i class="fa fa-eye"></i> 浏览总量:${siteBasicStatistics[5]} 次</li>
                <li><i class="fa fa-pencil-square-o"></i> 最后更新:
                    <span style="color:#2F889A">
                                        <fmt:formatDate value="${lastUpdateArticle.articleUpdateTime}" pattern="yyyy年MM月dd日"/>

                                   </span>
                </li>
            </ul>
        </div>
        <div class="clear"></div>
    </aside>
    <%--网站概况 end--%>

    <%--所有标签 start--%>
    <aside class="widget">
        <h3 class="widget-title">
            <i class="fa fa-bars"></i>所有标签
        </h3>
        <div class="tagcloud">
            <c:forEach items="${allTagList}" var="tag">
                <a href="/tag/${tag.tagId}"
                   class="tag-link-129 tag-link-position-1"
                   style="font-size: 14px;">
                        ${tag.tagName}
                </a>
            </c:forEach>
            <div class="clear"></div>
        </div>
        <div class="clear"></div>
    </aside>
    <%--所有标签 end--%>


    <%--最新评论 start--%>
    <aside id="recent_comments-2" class="widget recent_comments wow fadeInUp" data-wow-delay="0.3s"><h3
            class="widget-title"><i class="fa fa-bars"></i>近期评论</h3>
        <div id="message" class="message-widget">
            <ul>
                <c:forEach items="${recentCommentList}" var="r">
                <li style="border: none;">
                    <a href="/article/${r.commentArticleId}/#anchor-comment-${r.commentId}"  rel="external nofollow">
                        <%--<img alt="" src="${r.commentAuthorAvatar}" class="avatar avatar-64 photo" height="64" width="64">--%>
                        <span class="comment_author">
                            <strong>${r.commentAuthorName}</strong>
                        </span>
                            ${r.commentContent}
                    </a>
                </li>
                </c:forEach>
            </ul>
        </div>
        <div class="clear"></div>
    </aside>
    <%--最新评论 end--%>

</div>



<%--博客主体-右侧侧边栏 end--%>

siderbar3.jsp:正文侧边栏。包含搜索框,显示热评文章。

<%--
    一般用于正文侧边栏:
    包括 搜索,热评文章
--%>

<%@ page language="java" contentType="text/html; charset=UTF-8"
         pageEncoding="UTF-8" %>
<%--博客主体-右侧侧边栏 start--%>
<div id="sidebar" class="widget-area all-sidebar"
     style="position: relative; overflow: visible; box-sizing: border-box; min-height: 1px;">

    <%--搜索框--%>
    <aside class="widget widget_search">
        <div class="searchbar">
            <form method="get" id="searchform1" action="/search">
                    <span> <input type="text" value="" name="keywords" id="s1" placeholder="输入搜索内容" required="">
                        <button type="submit" id="searchsubmit1">搜索</button>
                    </span>
            </form>
        </div>
        <div class="clear"></div>
    </aside>
    <%--搜索框--%>

    <%--热评文章 start--%>
    <aside class="widget hot_comment" >
        <h3 class="widget-title">
            <i class="fa fa-bars"></i>热评文章
        </h3>
        <div id="hot_comment_widget">
            <ul>
                <c:forEach items="${mostCommentArticleList}" var="m">
                    <li>
                        <a href="/article/${m.articleId}" rel="bookmark" title=" (${m.articleCommentCount}条评论)">
                                ${m.articleTitle}
                        </a>
                    </li>
                </c:forEach>
            </ul>
        </div>
        <div class="clear"></div>
    </aside>
    <%--热评文章 end--%>



</div>
<%--博客主体-右侧侧边栏 end--%>

1.3 顶部导航header.jsp

博客的顶部部分:登录/进入后台(判断Session中有没有User,有的话,显示进入后台,否则显示登录),顶部菜单(还记得之前的管理员后台添加菜单时,就有这个选项),主要菜单,搜索。

<%--
    博客顶部部分
    包括:顶部菜单,主要菜单(包括搜索按钮),面包屑
--%>
<%@ page language="java" contentType="text/html; charset=UTF-8"
         pageEncoding="UTF-8" %>

<%--导航 start--%>
<header id="masthead" class="site-header">
    <%--顶部菜单 start--%>
    <nav id="top-header">
        <div class="top-nav">
            <div class="user-login">
                <c:choose>
                    <c:when test="${sessionScope.user==null}">
                        <a href="/admin">登录</a>
                    </c:when>
                    <c:otherwise>
                        <a href="/admin">进入后台</a>
                    </c:otherwise>
                </c:choose>
            </div>
            <div class="menu-topmenu-container">
                <ul id="menu-topmenu" class="top-menu">
                    <c:forEach items="${menuList}" var="m">
                        <li class="menu-item">
                            <c:if test="${m.menuLevel==1}">
                                <a href="${m.menuUrl}" >
                                    <i class="${m.menuIcon}"></i>
                                    <span class="font-text">${m.menuName}&nbsp;</span>&nbsp;
                                </a>
                            </c:if>
                        </li>
                    </c:forEach>
                </ul>
            </div>
        </div>
    </nav><!-- #top-header -->
    <%--顶部菜单 end--%>

    <%--主要菜单 satrt--%>
    <div id="menu-box">
        <div id="top-menu">
                <span class="nav-search">
                    <i class="fa fa-search"></i>
                </span>
            <div class="logo-site"><h1 class="site-title">
                <a href="/" title="${options.optionSiteTitle}">${options.optionSiteTitle}</a>
            </h1>
                <p class="site-description">${options.optionSiteDescrption}</p>
            </div><!-- .logo-site -->
            <div id="site-nav-wrap">
                <div id="sidr-close">
                    <a href="#sidr-close" class="toggle-sidr-close">×</a>
                </div>
                <nav id="site-nav" class="main-nav">
                    <a href="#sidr-main" id="navigation-toggle" class="bars">
                        <i class="fa fa-bars"></i>
                    </a>
                    <div class="menu-pcmenu-container">
                        <ul id="menu-pcmenu" class="down-menu nav-menu sf-js-enabled sf-arrows">

                            <li>
                                <a href="/">
                                    <i class="fa-home fa"></i>
                                    <span class="font-text">首页</span>
                                </a>
                            </li>

                            <c:forEach items="${allCategoryList}" var="category">
                                <c:if test="${category.categoryPid==0}">
                                    <li>
                                        <a href="/category/${category.categoryId}">
                                            <i class="${category.categoryIcon}"></i>
                                            <span class="font-text">${category.categoryName}&nbsp;</span>
                                        </a>
                                        <ul class="sub-menu">
                                            <c:forEach items="${allCategoryList}" var="cate">
                                                <c:if test="${cate.categoryPid==category.categoryId}">
                                                    <li>
                                                        <a href="/category/${cate.categoryId}" target="_blank">${cate.categoryName}</a>
                                                    </li>
                                                </c:if>
                                            </c:forEach>
                                        </ul>
                                    </li>
                                </c:if>
                            </c:forEach>
                            <%--主要菜单其余部分--%>
                            <c:forEach items="${menuList}" var="m">
                                <c:if test="${m.menuLevel == 2}">
                                    <li>
                                        <a href="${m.menuUrl}">
                                            <i class="${m.menuIcon}"></i>
                                            <span class="font-text">${m.menuName}&nbsp;</span>
                                        </a>
                                    </li>
                                </c:if>
                            </c:forEach>
                        </ul>
                    </div>
                </nav>
            </div>
            <div class="clear"></div>
        </div><!-- #top-menu -->
    </div><!-- #menu-box -->
    <%--主要菜单 satrt--%>

</header><!-- #masthead -->
<%--导航 end start--%>

<%--搜索框 start--%>
<div id="search-main">
    <div class="searchbar">
        <form method="get" id="searchform" action="/search" accept-charset="UTF-8">
            <span>
                <input type="text" value="" name="keywords" id="s" placeholder="输入搜索内容"required="">
                <button type="submit" id="searchsubmit">搜索</button>
            </span>
        </form>
    </div>
    <div class="clear"></div>
</div>
<%--搜索框 end--%>

<rapid:block name="breadcrumb"></rapid:block>

1.4 博客页脚

<%--
    博客页脚部分
--%>
<%@ page language="java" contentType="text/html; charset=UTF-8"
         pageEncoding="UTF-8" %>

<%--页脚 start--%>
<footer id="colophon" class="site-footer" role="contentinfo">
    <div class="site-info">
        <p style="text-align: center;">Copyright © 2020
            <a href="/" target="_blank" rel="noopener noreferrer">${options.optionSiteTitle}</a>
            All rights reserved.
            <a target="_blank" href="/map" >
                <span class="font-text">站点地图</span>
            </a>
        </p>
    </div>
    <!-- .site-info -->
</footer><!-- .site-footer -->
<%--页脚 end--%>

1.5 分页

<c:if test="${pageInfo.pages > 1}">
    <nav class="navigation pagination" role="navigation">
        <div class="nav-links">
            <c:choose>
                <c:when test="${pageInfo.pages <= 3 }">
                    <c:set var="begin" value="1"/>
                    <c:set var="end" value="${pageInfo.pages }"/>
                </c:when>
                <c:otherwise>
                    <c:set var="begin" value="${pageInfo.pageNum-1 }"/>
                    <c:set var="end" value="${pageInfo.pageNum + 2}"/>
                    <c:if test="${begin < 2 }">
                        <c:set var="begin" value="1"/>
                        <c:set var="end" value="3"/>
                    </c:if>
                    <c:if test="${end > pageInfo.pages }">
                        <c:set var="begin" value="${pageInfo.pages-2}"/>
                        <c:set var="end" value="${pageInfo.pages }"/>
                    </c:if>
                </c:otherwise>
            </c:choose>
                <%--上一页 --%>
            <c:choose>
                <c:when test="${pageInfo.pageNum eq 1 }">
                    <%--当前页为第一页,隐藏上一页按钮--%>
                </c:when>
                <c:otherwise>
                    <a class="page-numbers" href="${pageUrlPrefix}=${pageInfo.pageNum-1}">
                        <span class="fa fa-angle-left"></span>
                    </a>
                </c:otherwise>
            </c:choose>
                <%--显示第一页的页码--%>
            <c:if test="${begin >= 2 }">
                <a class="page-numbers" href="${pageUrlPrefix}=1">1</a>
            </c:if>
                <%--显示点点点--%>
            <c:if test="${begin  > 2 }">
                <span class="page-numbers dots">...</span>
            </c:if>
                <%--打印 页码--%>
            <c:forEach begin="${begin }" end="${end }" var="i">
                <c:choose>
                    <c:when test="${i eq pageInfo.pageNum }">
                        <a class="page-numbers current">${i}</a>
                    </c:when>
                    <c:otherwise>
                        <a class="page-numbers" href="${pageUrlPrefix}=${i}">${i}</a>
                    </c:otherwise>
                </c:choose>
            </c:forEach>
                <%-- 显示点点点 --%>
            <c:if test="${end < pageInfo.pages-1}">
                <span class="page-numbers dots">...</span>
            </c:if>
                <%-- 显示最后一页的数字 --%>
            <c:if test="${end < pageInfo.pages }">
                <a href="${pageUrlPrefix}=${pageInfo.pages}">${pageInfo.pages}</a>
            </c:if>
                <%--下一页 --%>
            <c:choose>
                <c:when test="${pageInfo.pageNum eq pageInfo.pages }">
                    <%--到了尾页隐藏,下一页按钮--%>
                </c:when>
                <c:otherwise>
                    <a class="page-numbers" href="${pageUrlPrefix}=${pageInfo.pageNum+1}">
                        <span class="fa fa-angle-right"></span>
                    </a>
                </c:otherwise>
            </c:choose>

        </div>
    </nav>
    <%--分页 end--%>
</c:if>

二.拦截器

在跳转到博客主页的时候,显示出的页面有什么菜单信息等。这些信息如果是放在响应跳转请求中实现,那么跳转到其他页面的时候,还需要查询这些信息。为了方便起见,我们使用SpringMVC的拦截器进行处理,在处理请求之前,准备资源数据,然后将这些数据当做请求属性放入WebRequest,这样即使进行不断的页面跳转,也会显示信息。

package com.test.ssm.blog.interceptor;

//拦截器

import com.test.ssm.blog.entity.Article;
import com.test.ssm.blog.entity.Category;
import com.test.ssm.blog.entity.Menu;
import com.test.ssm.blog.entity.Options;
import com.test.ssm.blog.enums.ArticleStatus;
import com.test.ssm.blog.enums.LinkStatus;
import com.test.ssm.blog.service.*;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.ArrayList;
import java.util.List;

@Component
public class HomeResourceInterceptor implements HandlerInterceptor {

    @Autowired
    private ArticleService articleService;
    @Autowired
    private CategoryService categoryService;
    @Autowired
    private TagService tagService;
    @Autowired
    private LinkService linkService;
    @Autowired
    private OptionsService optionsService;
    @Autowired
    private MenuService menuService;

    /**
     * 在请求处理之前,该方法主要是用于准备资源数据的,然后可以把他它们当做请求属性放在WebRequest
     * @param httpServletRequest
     * @param httpServletResponse
     * @param o
     * @return
     * @throws Exception
     */

    @Override
    public boolean preHandle(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o) throws Exception {
      //菜单显示

        List<Menu> menuList=menuService.listMenu();
        httpServletRequest.setAttribute("menuList",menuList);
      //分类
        List<Category> categoryList=categoryService.listCategory();
        httpServletRequest.setAttribute("allCategoryList",categoryList);

        //获得网站概况
        List<String> siteBasicStatistics=new ArrayList<>();
        siteBasicStatistics.add(articleService.countArticle(ArticleStatus.PUBLISH.getValue())+"");
        siteBasicStatistics.add(articleService.countArticleComment()+"");
        siteBasicStatistics.add(categoryService.countCategory()+"");
        siteBasicStatistics.add(tagService.countTag()+"");
        siteBasicStatistics.add(linkService.countLink(LinkStatus.NORMAL.getValue())+"");
        siteBasicStatistics.add(articleService.countArticleView()+"");
        httpServletRequest.setAttribute("siteBasicStatistics",siteBasicStatistics);

        //最后更新的文章
        Article lastUpdateArticle=articleService.getLastUpdateArticle();
        httpServletRequest.setAttribute("lastUpdateArticle",lastUpdateArticle);

        //页脚显示(显示博客基本信息Options)
        Options options=optionsService.getOptions();
        httpServletRequest.setAttribute("options",options);
        return true;
    }

    @Override
    public void postHandle(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o, ModelAndView modelAndView) throws Exception {

    }

    @Override
    public void afterCompletion(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o, Exception e) throws Exception {

    }
}

一定记得这个拦截器要在SpringMVC的配置文件进行配置:

    <!--6.拦截器-->
    <mvc:interceptors>
        <!--只要进行请求,就进行拦截,获取网站基本信息-->
        <mvc:interceptor>
            <mvc:mapping path="/**"/>
            <bean class="com.test.ssm.blog.interceptor.HomeResourceInterceptor"/>
        </mvc:interceptor>
        <mvc:interceptor>
            <mvc:mapping path="/admin"/>
            <bean class="com.test.ssm.blog.interceptor.SecurityInterceptor"/>
        </mvc:interceptor>
 
    </mvc:interceptors>

三.文章详细信息显示

3.1 文章详情JSP页面

这个除了显示文章信息和侧边栏之外,最重要的就是显示文章下的评论。当你是在登录下的状态去回复评论的时候,下面就会显示用户信息去回复。如果不是以博主的身份进行评论,则需要输入自己的信息(这个部分的Controller操作会在后面讲到,现在就是说明下页面显示)。

<%@ page language="java" contentType="text/html; charset=UTF-8"
         pageEncoding="UTF-8" %>
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>
<%@ taglib uri="http://java.sun.com/jsp/jstl/fmt" prefix="fmt" %>
<%@ taglib uri="http://java.sun.com/jsp/jstl/functions" prefix="fn" %>
<%@ taglib prefix="rapid" uri="http://www.rapid-framework.org.cn/rapid" %>
<rapid:override name="title">
    <title>${article.articleTitle}</title>
</rapid:override>

<rapid:override name="header-style">
    <rapid:override name="header-style">
        <link rel="stylesheet" href="${pageContext.request.contextPath}/css/highlight.css">
        <style>
            .entry-title {
                background: #f8f8f8;
            }
        </style>
    </rapid:override>
</rapid:override>

<rapid:override name="breadcrumb">
    <%--面包屑导航 start--%>
    <nav class="breadcrumb">
        <a class="crumbs" href="/">
            <i class="fa fa-home"></i>首页
        </a>
        <c:choose>
            <c:when test="${article.categoryList != null && article.categoryList.size() > 0}">
                <c:forEach items="${article.categoryList}" var="c">
                    <i class="fa fa-angle-right"></i>
                    <a href="/category/${c.categoryId}">
                            ${c.categoryName}
                    </a>
                </c:forEach>
            </c:when>
            <c:otherwise>
                <i class="fa fa-angle-right"></i>
                <a>未分类</a>
            </c:otherwise>
        </c:choose>
        <i class="fa fa-angle-right"></i>
        正文
    </nav>
    <%--面包屑导航 end--%>
</rapid:override>


<rapid:override name="left">
    <%--博客主体-左侧文章正文 start--%>
    <div id="primary" class="content-area">
        <main id="main" class="site-main" role="main">
            <article class="post" id="articleDetail" data-id="${article.articleId}">
                <header class="entry-header">
                    <h1 class="entry-title">
                            ${article.articleTitle}
                    </h1>
                </header><!-- .entry-header -->
                <div class="entry-content">
                    <div class="single-content">
                            ${article.articleContent}
                    </div>
                    <div class="clear"></div>
                    <div id="social">
                        <div class="social-main">
                            <span class="like">
                                <a href="javascript:;" data-action="ding" data-id="1" title="点赞"
                                   class="favorite" onclick="increaseLikeCount()">
                                    <i class="fa fa-thumbs-up"></i>赞
                                    <i class="count"
                                       id="count-${article.articleId}">${article.articleLikeCount}</i>
                                </a>
                            </span>
                            <div class="shang-p">
                                <div class="shang-empty"><span></span></div>
                                <span class="shang-s">
                                    <a onclick="PaymentUtils.show();" style="cursor:pointer">赏</a>
                                </span>
                            </div>
                            <div class="share-sd">
                                        <span class="share-s" style="margin-top: 25px!important;">
                                            <a href="javascript:void(0)" id="share-s" title="分享">
                                                <i class="fa fa-share-alt"></i>分享
                                            </a>
                                        </span>
                                <div id="share">
                                    <ul class="bdsharebuttonbox bdshare-button-style1-16" data-bd-bind="1503997585792">
                                        <li><a title="更多" class="bds_more fa fa-plus-square" data-cmd="more"
                                               onclick="return false;" href="#"></a></li>
                                        <li><a title="分享到QQ空间" class="fa fa-qq" data-cmd="qzone" onclick="return false;"
                                               href="#"></a></li>
                                        <li><a title="分享到新浪微博" class="fa fa-weibo" data-cmd="tsina"
                                               onclick="return false;" href="#"></a></li>
                                        <li><a title="分享到腾讯微博" class="fa fa-pinterest-square" data-cmd="tqq"
                                               onclick="return false;" href="#"></a></li>
                                        <li><a title="分享到人人网" class="fa fa-renren" data-cmd="renren"
                                               onclick="return false;" href="#"></a></li>
                                        <li><a title="分享到微信" class="fa fa-weixin" data-cmd="weixin"
                                               onclick="return false;" href="#"></a></li>
                                    </ul>
                                </div>
                            </div>
                            <div class="clear"></div>
                        </div>
                    </div>

                    <footer class="single-footer">
                        <ul class="single-meta">
                            <c:if test="${sessionScope.user!=null}">
                                <li class="edit-link">
                                    <a target="_blank" class="post-edit-link"
                                       href="/admin/article/edit/${article.articleId}">编辑</a>
                                </li>
                            </c:if>
                            <li class="comment">
                                <a href="/article/${article.articleId}#comments"
                                   rel="external nofollow">
                                    <i class="fa fa-comment-o"></i>
                                    <i class="comment-count">${commentList.size()}</i>
                                </a>
                            </li>
                            <li class="views">
                                <i class="fa fa-eye"></i> <span
                                    class="articleViewCount">${article.articleViewCount}</span>
                                views
                            </li>
                            <li class="r-hide">
                                <a href="javascript:pr()" title="侧边栏">
                                    <i class="fa fa-caret-left"></i>
                                    <i class="fa fa-caret-right"></i>
                                </a>
                            </li>
                        </ul>
                        <ul id="fontsize">
                            <li>A+</li>
                        </ul>
                        <div class="single-cat-tag">
                            <div class="single-cat">所属分类:
                                <c:forEach items="${article.categoryList}" var="c">
                                    <a href="/category/${c.categoryId}">
                                            ${c.categoryName}
                                    </a>
                                </c:forEach>
                            </div>
                        </div>
                    </footer><!-- .entry-footer -->


                    <div class="clear"></div>
                </div><!-- .entry-content -->
            </article><!-- #post -->

                <%--所属标签 start--%>
            <div class="single-tag">
                <ul class="" data-wow-delay="0.3s">
                    <c:forEach items="${article.tagList}" var="t">
                        <li>
                            <a href="/tag/${t.tagId}" rel="tag"
                               style="background:#666666">
                                    ${t.tagName}
                            </a>
                        </li>
                    </c:forEach>
                </ul>
            </div>
                <%--所属标签 end--%>


                <%--版权声明 start--%>
            <div class="authorbio wow fadeInUp">
                <img alt="${article.user.userNickname}" src="${article.user.userAvatar}"
                     class="avatar avatar-64 photo" height="64" width="64">
                <ul class="postinfo">
                    <li></li>
                    <li><strong>版权声明:</strong>本站原创文章,于<fmt:formatDate
                            value="${article.articleCreateTime}"
                            pattern="yyyy-MM-dd"/>,由
                        <strong>
                                ${article.user.userNickname}
                        </strong>
                        发表。
                    </li>
                    <li class="reprinted"><strong>转载请注明:</strong>
                        <a href="/article/${article.articleId}"
                           rel="bookmark"
                           title="本文固定链接 /article/${article.articleId}">
                                ${article.articleTitle} | ${options.optionSiteTitle}</a>
                    </li>
                </ul>
                <div class="clear"></div>
            </div>
                <%--版权声明 end--%>

                <%--相关文章 start--%>
            <div id="single-widget">
                <div class="wow fadeInUp" data-wow-delay="0.3s">
                    <aside id="related_post-2" class="widget">
                        <h3 class="widget-title">
                            <span class="s-icon"></span>相关文章
                        </h3>
                        <div id="related_post_widget">
                            <ul>
                                <c:forEach items="${similarArticleList}" var="s">
                                    <li>
                                        <a href="/article/${s.articleId}">${s.articleTitle}</a>
                                    </li>
                                </c:forEach>
                            </ul>
                        </div>
                        <div class="clear"></div>
                    </aside>
                        <%--猜你喜欢 start--%>
                    <aside id="hot_post-8" class="widget hot_post">
                        <h3 class="widget-title"><span class="s-icon"></span>猜你喜欢</h3>
                        <div id="hot_post_widget">
                            <ul>
                                <c:forEach items="${mostViewArticleList}" var="m">
                                    <li>
                                        <a href="/article/${m.articleId}">
                                                ${m.articleTitle}
                                        </a>
                                    </li>
                                </c:forEach>
                            </ul>
                        </div>
                        <div class="clear"></div>
                    </aside>
                        <%--猜你喜欢 end--%>
                </div>
                <div class="clear"></div>
            </div>
                <%--相关文章 end--%>

                <%--上一篇下一篇 start--%>
            <nav class="nav-single">
                <c:choose>
                    <c:when test="${preArticle!=null}">
                        <a href="/article/${preArticle.articleId}" rel="next">
                            <span class="meta-nav">
                                <span class="post-nav">上一篇
                                 <i class="fa fa-angle-left"></i>
                                </span>
                                <br>${preArticle.articleTitle}
                            </span>
                        </a>
                    </c:when>
                    <c:otherwise>
                              <span class="meta-nav">
                                    <span class="post-nav">
                                        没有了<br>
                                    </span>已是第一篇文章
                                </span>
                    </c:otherwise>
                </c:choose>
                <c:choose>
                    <c:when test="${afterArticle!=null}">
                        <a href="/article/${afterArticle.articleId}" rel="next">
                            <span class="meta-nav">
                                <span class="post-nav">下一篇
                                 <i class="fa fa-angle-right"></i>
                                </span>
                                <br>${afterArticle.articleTitle}
                            </span>
                        </a>
                    </c:when>
                    <c:otherwise>
                            <span class="meta-nav">
                                <span class="post-nav">
                                    没有了<br>
                                </span>已是最后文章
                             </span>
                    </c:otherwise>
                </c:choose>

                <div class="clear"></div>
            </nav>
                <%--上一篇下一篇 end--%>

                <%--评论区域 start--%>
            <div class="scroll-comments"></div>
            <div id="comments" class="comments-area">
                <div id="respond" class="comment-respond">
                    <h3 id="reply-title" class="comment-reply-title"><span id="reply-title-word">发表评论</span>
                        <a rel="nofollow" id="cancel-comment-reply-link"
                           href="/article/${article.articleId}#respond"
                           style="">取消回复</a>
                    </h3>
                    <form id="comment_form" method="post">
                        <c:if test="${sessionScope.user!=null}">
                            <div class="user_avatar">
                                <img alt="努力"
                                     src="${sessionScope.user.userAvatar}"
                                     class="avatar avatar-64 photo" height="64" width="64">
                                登录者:${sessionScope.user.userNickname}
                                <br> <a href="javascript:void(0)" onclick="logout()">登出</a>
                                <input type="hidden" name="commentRole" value="1">
                                <input type="hidden" name="commentAuthorName"
                                       value="${sessionScope.user.getUserNickname()}">
                                <input type="hidden" name="commentAuthorEmail"
                                       value="${sessionScope.user.getUserEmail()}">
                                <input type="hidden" name="commentAuthorUrl" value="${sessionScope.user.getUserUrl()}">
                            </div>
                        </c:if>
                        <p class="comment-form-comment">
                            <textarea id="comment" name="commentContent" rows="4" tabindex="1" required></textarea>
                        </p>
                        <div id="comment-author-info">
                            <input type="hidden" name="commentPid" value="0">
                            <input type="hidden" name="commentPname" value="">
                            <c:if test="${sessionScope.user == null}">
                                <input type="hidden" name="commentRole" value="0">
                                <p class="comment-form-author">
                                    <label for="author_name">
                                        昵称<span class="required">*</span>
                                    </label>
                                    <input type="text" name="commentAuthorName" id="author_name" class="" value=""
                                           tabindex="2" required>
                                </p>
                                <p class="comment-form-email">
                                    <label for="author_email">
                                        邮箱<span class="required">*</span>
                                    </label>
                                    <input type="email" name="commentAuthorEmail" id="author_email" class="" value=""
                                           tabindex="3" required>
                                </p>
                                <p class="comment-form-url">
                                    <label for="author_url">网址</label>
                                    <input type="url" name="commentAuthorUrl" id="author_url" class="" value=""
                                           tabindex="4">
                                </p>
                            </c:if>
                        </div>
                        <div class="clear"></div>
                        <p class="form-submit">
                            <input id="submit" name="submit" type="submit" tabindex="5" value="提交评论">
                            <input type="hidden" name="commentArticleId"
                                   value="${article.articleId}" id="article_id">
                            <input type="hidden" name="commentPid" id="comment_pid" value="0">
                        </p>
                    </form>
                </div>

                <ol class="comment-list">
                    <c:set var="floor" value="0"/>
                    <c:forEach items="${commentList}" var="c">
                        <c:if test="${c.commentPid == 0}">
                            <c:set var="floor" value="${floor + 1}"/>
                            <li class="comments-anchor">
                                <ul id="anchor-comment-${c.commentId}"></ul>
                            </li>
                            <li class="comment">
                                <div id="div-comment-${c.commentId}" class="comment-body">
                                    <div class="comment-author vcard">
                                        <img class="avatar" src="${c.commentAuthorAvatar}" alt="avatar"
                                             style="display: block;">
                                        <strong>${c.commentAuthorName} </strong>
                                        <c:if test="${c.commentRole == 1}">
                                            <i class="fa fa-black-tie" style="color: #c40000;"></i>
                                            <span class=""
                                                  style="margin-top: 2px!important;color: #c40000;font-size: 13px;;"><b>博主</b></span>
                                        </c:if>
                                        <span class="comment-meta commentmetadata">
                                            <span class="ua-info" style="display: inline;">
                                                <br>
                                                <span class="comment-aux">
                                                    <span class="reply">
                                                        <a rel="nofollow" class="comment-reply-link" href="#respond"
                                                           onclick="replyComment()">回复
                                                        </a>
                                                    </span>
                                                    <fmt:formatDate value="${c.commentCreateTime}"
                                                                    pattern="yyyy年MM月dd日 HH:mm:ss"/>&nbsp;
                                                    <c:if test="${sessionScope.user != null}">
                                                        <a href="javascript:void(0)"
                                                           onclick="deleteComment(${c.commentId})">删除</a>
                                                        <a class="comment-edit-link"
                                                           href="/admin/comment/edit/${c.commentId}"
                                                           target="_blank">编辑</a>
                                                    </c:if>
                                                    <span class="floor"> &nbsp;${floor}楼 </span>
                                                </span>
                                            </span>
                                        </span>
                                        <p>
                                            <c:if test="${c.commentPid!=0}">
                                                <span class="at">@ ${c.commentPname}</span>
                                            </c:if>
                                                ${c.commentContent}
                                        </p>
                                    </div>
                                </div>
                                <ul class="children">
                                    <c:set var="floor2" value="0"/>
                                    <c:forEach items="${commentList}" var="c2">
                                        <c:if test="${c.commentId == c2.commentPid}">
                                            <c:set var="floor2" value="${floor2+1}"/>
                                            <li class="comments-anchor">
                                                <ul id="anchor-comment-${c2.commentId}"></ul>
                                            </li>
                                            <li class="comment">
                                                <div id="div-comment-${c.commentId}" class="comment-body">
                                                    <div class="comment-author vcard">
                                                        <img class="avatar" src="${c2.commentAuthorAvatar}" alt="avatar"
                                                             style="display: block;">
                                                        <strong>${c2.commentAuthorName} </strong>
                                                        <c:if test="${c2.commentRole==1}">
                                                            <i class="fa fa-black-tie" style="color: #c40000;"></i>
                                                            <span class=""
                                                                  style="margin-top: 2px!important;color: #c40000;font-size: 13px;;"><b>博主</b></span>
                                                        </c:if>
                                                        <span class="comment-meta">
                                                    <span class="ua-info" style="display: inline;">
                                                    <br>
                                                    <span class="comment-aux">
                                                        <span class="reply">
                                                            <a rel="nofollow" class="comment-reply-link" href="#respond"
                                                               onclick="replyComment()">回复
                                                            </a>
                                                        </span>
                                                        <fmt:formatDate value="${c2.commentCreateTime}"
                                                                        pattern="yyyy年MM月dd日 HH:mm:ss"/>&nbsp;
                                                        <c:if test="${sessionScope.user != null}">
                                                            <a href="javascript:void(0)"
                                                               onclick="deleteComment(${c2.commentId})">删除</a>
                                                            <a class="comment-edit-link"
                                                               href="/admin/comment/edit/${c2.commentId}"
                                                               target="_blank">编辑</a>
                                                        </c:if>
                                                        <span class="floor"> &nbsp;${floor2}层 </span>
                                                    </span>
                                                </span>
                                                    </span>
                                                        <p>
                                                            <c:if test="${c2.commentPid!=0}">
                                                                <c:if test="${c2.commentPid!=0}">
                                                                    <span class="at">@ ${c2.commentPname}</span>
                                                                </c:if>
                                                                ${c2.commentContent}
                                                            </c:if>
                                                        </p>
                                                    </div>
                                                </div>
                                            </li>
                                        </c:if>
                                    </c:forEach>
                                </ul>
                            </li>
                        </c:if>
                    </c:forEach>
                </ol>
            </div>
                <%--评论框 end--%>

        </main>
        <!-- .site-main -->
    </div>
    <%--博客主体-左侧文章正文end--%>
</rapid:override>


<%--侧边栏 start--%>
<rapid:override name="right">
    <%@include file="../Public/part/sidebar-1.jsp" %>
</rapid:override>
<%--侧边栏 end--%>

<rapid:override name="footer-script">
    <script src="${pageContext.request.contextPath}/js/jquery.cookie.js"></script>

    <script type="text/javascript">

        $(document).ready(function () {
            if ($('#author_name').val() == '') {
                var author = localStorage.getItem("author");
                $("#author_name").val(author == 'undefined' ? '' : author);
            }
            if ($('#author_email').val() == '') {
                var email = localStorage.getItem("email");
                $("#author_email").val(email == 'undefined' ? '' : email);
            }
            if ($('#author_url').val() == '') {
                var url = localStorage.getItem("url");
                $("#author_url").val(url == 'undefined' ? '' : url);
            }
        });

        var articleId = $("#articleDetail").attr("data-id");
        increaseViewCount(articleId);
        layui.code({
            elem: 'pre',//默认值为.layui-code
            // skin: 'notepad', //如果要默认风格,不用设定该key。
            about: false
        });

    </script>

</rapid:override>


<%@ include file="../Public/framework.jsp" %>

3.2 ArticleController

3.2.1 文章详情页显示

这个就是基本的查询信息,放入Model中。

@Controller
public class ArticleController {

    @Autowired
    private ArticleService articleService;
    @Autowired
    private CommentService commentService;
    @Autowired
    private UserService userService;
    @Autowired
    private TagService tagService;
    @Autowired
    private CategoryService categoryService;


    //文章详情页显示
    @RequestMapping(value = "article/{articleId}")
    public String getArticleDetailPage(@PathVariable("articleId")Integer articleId, Model model){
        //文章信息
        Article article=articleService.getArticleByStatusAndId(ArticleStatus.PUBLISH.getValue(),articleId);
        if(article==null)
        {
            return "Home/Error/404";
        }
        //用户信息
        User user=userService.getUserById(article.getArticleUserId());
        article.setUser(user);
        model.addAttribute("article",article);

        //评论列表
        List<Comment> commentList=commentService.listCommentByArticleId(articleId);
        model.addAttribute("commentList",commentList);

        //相关文章
        List<Integer> categoryIds=articleService.listCategoryIdByArticleId(articleId);
        List<Article> similarArticleList=articleService.listArticleByCategoryIds(categoryIds,5);
        model.addAttribute("similarArticleList",similarArticleList);

        //测你喜欢
        List<Article> mostViewArticleList=articleService.listArticleByViewCount(5);
        model.addAttribute("mostViewArticleList",mostViewArticleList);

        //获取下一篇文章
        Article afterArticle=articleService.getAfterArticle(articleId);
        model.addAttribute("afterArticle",afterArticle);

        //获取上一篇文章
        Article preArticle=articleService.getPreArticle(articleId);
        model.addAttribute("preArticle",preArticle);

        //侧边栏
        //标签列表显示
        List<Tag> allTagList=tagService.listTag();
        model.addAttribute("allTagList",allTagList);

        //获得随机文章
        List<Article> randomArticleList=articleService.listRandomArticle(8);
        model.addAttribute("randomArticleList",randomArticleList);

        //获得热评文章

        List<Article> mostCommentArticleList=articleService.listArticleByCommentCount(8);
        model.addAttribute("mostCommentArticleList",mostCommentArticleList);

        return "Home/Page/articleDetail";
    }

3.2.2 点赞

JSP页面:

 <script type="text/javascript">

     ...

        var articleId = $("#articleDetail").attr("data-id");
        increaseViewCount(articleId);
        layui.code({
            elem: 'pre',//默认值为.layui-code
            // skin: 'notepad', //如果要默认风格,不用设定该key。
            about: false
        });

    </script>

Ajax方法是:这个会在浏览器的Cookie中创建一个标识viewId,当从第一次其他页面点入这个文章的时候,Cookie中的viewId便是null,就可以进行下面的ajax请求方法。便可以防止在这个页面刷新后增加浏览量。只要传递过来的文章Id和这个viewId不同,便说明是从其他页面过来的可以进行增加浏览量。

//文章浏览量+1
function increaseViewCount(articleId) {
    if ($.cookie("viewId") != articleId || $.cookie("viewId") == null) {
        $.ajax({
            async: false,
            type: "POST",
            url: "/article/view/" + articleId,
            dataType: 'json',
            contentType: 'application/json',
            success: function (data) {
                $(".articleViewCount").html(data);
                $.cookie(
                    "viewId",
                    articleId,//需要cookie写入的业务
                    {
                        "path": "/", //cookie的默认属性
                    }
                );
            },
            error: function () {
                alert("获取数据出错!");
            },
        });
    }
}

这个就是文章的点赞功能。

//点赞添加
    @RequestMapping(value = "/article/like/{id}",method = RequestMethod.POST)
    @ResponseBody
    public String increaseLikeCount(@PathVariable("id")Integer id)
    {
        Article article=articleService.getArticleByStatusAndId(ArticleStatus.PUBLISH.getValue(),id);
        Integer articleCount=article.getArticleLikeCount()+1;
        article.setArticleLikeCount(articleCount);
        articleService.updateArticle(article);
        return JSON.toJSONString(articleCount);
    }

3.3.3 文章访问量增加

JSP页面:

   <a href="javascript:;" data-action="ding" data-id="1" title="点赞"
                                   class="favorite" onclick="increaseLikeCount()">
                                    <i class="fa fa-thumbs-up"></i>赞
                                    <i class="count"
                                       id="count-${article.articleId}">${article.articleLikeCount}</i>
                                </a>

Ajax方法:这个处理方式和增加浏览量的处理方式是一样的。都是想Cookie中放入一个likeId。当第一次点击这个赞的时候,就可以进行请求,同时将文章ID放入likeId中,防止在这个页面无限次点赞。

//点赞+1
function increaseLikeCount() {
    if ($.cookie("likeId") != articleId || $.cookie("likeId") == null) {
        $.ajax({
            async: false,
            type: "POST",
            url: "/article/like/" + articleId,
            dataType: 'json',
            contentType: 'application/json',
            success: function (data) {
                $(".count").html(data);
                $.cookie(
                    "likeId",
                    articleId,//需要cookie写入的业务
                    {
                        "path": "/", //cookie的默认属性
                    }
                );
            },
            error: function () {
                //alert("获取数据出错!");
            },
        });
    }
}

Controller层:


    //文章访问数量增加
    @RequestMapping(value = "/article/view/{id}", method = {RequestMethod.POST})
    @ResponseBody
    public String increaseViewCount(@PathVariable("id")Integer id){
        Article article = articleService.getArticleByStatusAndId(ArticleStatus.PUBLISH.getValue(), id);
        Integer articleCount = article.getArticleViewCount() + 1;
        article.setArticleViewCount(articleCount);
        System.out.println(articleCount);
        articleService.updateArticle(article);
        return JSON.toJSONString(articleCount);
    }

3.3 页面显示

文章详情页显示:

目前博主是在登录的状态下,评论部分是这样显示的:

未登录的时候:

四.根据分类查询文章列表

在之前的后台页面中,文章列表的表格中会显示分类列表,管理员后台:

一般用户后台:

 

博客主页的菜单显示:

在点击文章进来后,会显示这个文章所属的分类层次:

可以看到这些页面都有这个分类的显示,可以进行点击,点击后就会跳转到显示这个分类下所有文章的页面。

4.1 分类下文章列表JSP页面

<%@ page language="java" contentType="text/html; charset=UTF-8"
         pageEncoding="UTF-8" %>
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>
<%@ taglib uri="http://java.sun.com/jsp/jstl/fmt" prefix="fmt" %>
<%@ taglib uri="http://java.sun.com/jsp/jstl/functions" prefix="fn" %>
<%@ taglib prefix="rapid" uri="http://www.rapid-framework.org.cn/rapid" %>

<rapid:override name="description">
    <meta name="description" content="${category.categoryName}"/>
</rapid:override>
<rapid:override name="keywords">
    <meta name="keywords" content="${category.categoryName}"/>
</rapid:override>
<rapid:override name="title">
    <title>${category.categoryName}</title>
</rapid:override>

<%--面包屑导航 start--%>
<rapid:override name="breadcrumb">
    <nav class="breadcrumb">
        <a class="crumbs" href="/">
            <i class="fa fa-home"></i>首页</a>
        <i class="fa fa-angle-right"></i>
        <c:choose>
            <c:when test="${category != null}">
                <a href="/category/${category.categoryId}">${category.categoryName}</a>
                <i class="fa fa-angle-right"></i> 文章
            </c:when>
            <c:otherwise>
                该分类不存在
            </c:otherwise>

        </c:choose>

    </nav>
</rapid:override>
<%--面包屑导航 end--%>


<rapid:override name="left">
    <%--博客主体-左侧正文 start--%>
    <div id="primary" class="content-area">
        <main id="main" class="site-main">
            <c:choose>
                <c:when test="${pageInfo != null}">
                    <c:choose>
                        <c:when test="${pageInfo.list.size() != 0}">
                            <%--文章列表-start--%>
                            <c:forEach items="${pageInfo.list}" var="a">

                                <article class="post">

                                    <figure class="thumbnail">
                                        <a href="/article/${a.articleId}">
                                            <img width="280" height="210"
                                                 src="/img/thumbnail/random/img_${a.articleId%15}.jpg"
                                                 class="attachment-content size-content wp-post-image"
                                                 alt="${a.articleTitle}">
                                        </a>
                                        <span class="cat">
                                                    <a href="/category/${category.categoryId}">${category.categoryName}</a>
                                                </span>
                                    </figure>

                                    <header class="entry-header">
                                        <h2 class="entry-title">
                                            <a href="/article/${a.articleId}" rel="bookmark">
                                                    ${a.articleTitle}
                                            </a>
                                        </h2>
                                    </header><!-- .entry-header -->

                                    <div class="entry-content">
                                        <div class="archive-content">
                                                ${a.articleSummary}...
                                        </div>
                                        <span class="title-l"></span>
                                        <span class="new-icon">
                                                    <c:choose>
                                                        <c:when test="${a.articleStatus == 2}">
                                                            <i class="fa fa-bookmark-o"></i>
                                                        </c:when>
                                                        <c:otherwise>
                                                            <jsp:useBean id="nowDate"
                                                                         class="java.util.Date"/> <%--当前时间--%>
                                                            <c:set var="interval"
                                                                   value="${nowDate.time - a.articleCreateTime.time}"/><%--时间差毫秒数--%>
                                                            <fmt:formatNumber value="${interval/1000/60/60/24}"
                                                                              pattern="#0"
                                                                              var="days"/><%--取天数整数--%>
                                                            <c:if test="${days <= 7}">NEW</c:if>
                                                        </c:otherwise>
                                                    </c:choose>
                                                </span>
                                        <span class="entry-meta">
                                                    <span class="date">
                                                         <fmt:formatDate value="${a.articleCreateTime}"
                                                                         pattern="yyyy年MM月dd日"/>
                                                        &nbsp;&nbsp;
                                                    </span>
                                                    <span class="views">
                                                        <i class="fa fa-eye"></i>
                                                            ${a.articleViewCount} views
                                                    </span>
                                                    <span class="comment">&nbsp;&nbsp;
                                                        <a href="/article/${a.articleId}#comments"
                                                           rel="external nofollow">
                                                          <i class="fa fa-comment-o"></i>
                                                            <c:choose>
                                                                <c:when test="${a.articleCommentCount==0}">
                                                                    发表评论
                                                                </c:when>
                                                                <c:otherwise>
                                                                    ${a.articleCommentCount}
                                                                </c:otherwise>
                                                            </c:choose>
                                                        </a>
                                                    </span>
                                                </span>
                                        <div class="clear"></div>
                                    </div><!-- .entry-content -->
                                    <span class="entry-more">
                                            <a href="/article/${a.articleId}"
                                               rel="bookmark">阅读全文
                                            </a>
                                        </span>
                                </article>
                            </c:forEach>
                            <%--文章列表-end--%>
                        </c:when>
                        <c:otherwise>
                            <section class="no-results not-found">
                                <div class="post">
                                    <p>该分类目前还没有文章!</p>
                                    <br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br>
                                </div>
                            </section>
                        </c:otherwise>
                    </c:choose>
                </c:when>
                <c:otherwise>
                    <section class="no-results not-found">
                        <div class="post">
                            <p>该分类不存在</p>
                            <br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br>
                        </div>
                    </section>
                </c:otherwise>
            </c:choose>

        </main>
        <%@ include file="../Public/part/paging.jsp" %>

    </div>
    <%--  博客主体-左侧正文 end--%>
</rapid:override>

<%@ include file="../Public/framework.jsp" %>

4.2 CategoryController

这个就是根据分类ID查找文章列表。

package com.test.ssm.blog.controller.home;

import com.github.pagehelper.PageInfo;
import com.test.ssm.blog.entity.Article;
import com.test.ssm.blog.entity.Category;
import com.test.ssm.blog.entity.Tag;
import com.test.ssm.blog.enums.ArticleStatus;
import com.test.ssm.blog.service.ArticleService;
import com.test.ssm.blog.service.CategoryService;
import com.test.ssm.blog.service.TagService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;

import java.util.HashMap;
import java.util.List;

@Controller
public class CategoryController {

    @Autowired
    private CategoryService categoryService;
    @Autowired
    private ArticleService articleService;
    @Autowired
    private TagService tagService;

    //根据分类查询文章
    @RequestMapping("/category/{cateId}")
    public String getArticleListByCategory(@PathVariable("cateId")Integer cateId,
                                           @RequestParam(required = false,defaultValue = "1")Integer pageIndex,
                                           @RequestParam(required = false,defaultValue = "10")Integer pageSize,
                                           Model model){
        //获得分类信息
        Category category=categoryService.getCategoryById(cateId);
        if(category==null){
            return "redirect:/400";
        }
        model.addAttribute("category",category);

        //文章列表
        HashMap<String,Object> criteria=new HashMap<>(2);
        criteria.put("categoryId",cateId);
        criteria.put("status", ArticleStatus.PUBLISH.getValue());
        PageInfo<Article> articlePageInfo=articleService.pageArticle(pageIndex,pageSize,criteria);
        model.addAttribute("pageInfo",articlePageInfo);

        //侧边栏
        //标签列表显示
        List<Tag> allTagList=tagService.listTag();
        model.addAttribute("allTagList",allTagList);

        //获得随机文章
        List<Article> randomArticleList=articleService.listRandomArticle(8);
        model.addAttribute("randomArticleList",randomArticleList);

        //获得热评文章
        List<Article> mostCommentArticleList=articleService.listArticleByCommentCount(8);
        model.addAttribute("mostCommentArticleList",mostCommentArticleList);
        model.addAttribute("pageUrlPrefix","/category/"+pageIndex+"?pageIndex");
        return "Home/Page/articleListByCategory";


    }
}

4.3 页面显示

五.根据标签查询文章

在之前的后台管理页面,管理员后台:

一般用户后台:

前台的侧边栏:

点击这个列表中的标签都会跳转到显示这个标签下文章列表的页面。

5.1 标签下的文章列表JSP页面

<%@ page language="java" contentType="text/html; charset=UTF-8"
         pageEncoding="UTF-8" %>
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>
<%@ taglib uri="http://java.sun.com/jsp/jstl/fmt" prefix="fmt" %>
<%@ taglib uri="http://java.sun.com/jsp/jstl/functions" prefix="fn" %>
<%@ taglib prefix="rapid" uri="http://www.rapid-framework.org.cn/rapid" %>

<rapid:override name="description">
    <meta name="description" content="${category.categoryName}"/>
</rapid:override>
<rapid:override name="keywords">
    <meta name="keywords" content="${category.categoryName}"/>
</rapid:override>
<rapid:override name="title">
    <title>${category.categoryName}</title>
</rapid:override>

<%--面包屑导航 start--%>
<rapid:override name="breadcrumb">
    <nav class="breadcrumb">
        <a class="crumbs" href="/">
            <i class="fa fa-home"></i>首页</a>
        <i class="fa fa-angle-right"></i>
        <c:choose>
            <c:when test="${tag != null}">
                <a href="/tag/${tag.tagId}">${tag.tagName}</a>
                <i class="fa fa-angle-right"></i> 文章
            </c:when>
            <c:otherwise>
                该标签不存在
            </c:otherwise>

        </c:choose>

    </nav>
</rapid:override>
<%--面包屑导航 end--%>


<rapid:override name="left">
    <%--博客主体-左侧正文 start--%>
    <div id="primary" class="content-area">
        <main id="main" class="site-main">
            <c:choose>
                <c:when test="${pageInfo.list.size() != 0}">
                    <%--文章列表-start--%>
                    <c:forEach items="${pageInfo.list}" var="a">

                        <article class="post">

                            <figure class="thumbnail">
                                <a href="/article/${a.articleId}">
                                    <img width="280" height="210"
                                         src="/img/thumbnail/random/img_${a.articleId%15}.jpg"
                                         class="attachment-content size-content wp-post-image"
                                         alt="${a.articleTitle}">
                                </a>
                                <span class="cat">
                                              <a href="/category/${a.categoryList[0].categoryId}">${a.categoryList[0].categoryName}</a>
                                        </span>
                            </figure>

                            <header class="entry-header">
                                <h2 class="entry-title">
                                    <a href="/article/${a.articleId}" rel="bookmark">
                                            ${a.articleTitle}
                                    </a>
                                </h2>
                            </header><!-- .entry-header -->

                            <div class="entry-content">
                                <div class="archive-content">
                                   ${a.articleSummary}...
                                </div>
                                <span class="title-l"></span>
                                <span class="new-icon">
                                                    <c:choose>
                                                        <c:when test="${a.articleStatus == 2}">
                                                            <i class="fa fa-bookmark-o"></i>
                                                        </c:when>
                                                        <c:otherwise>
                                                            <jsp:useBean id="nowDate"
                                                                         class="java.util.Date"/> <%--当前时间--%>
                                                            <c:set var="interval"
                                                                   value="${nowDate.time - a.articleCreateTime.time}"/><%--时间差毫秒数--%>
                                                            <fmt:formatNumber value="${interval/1000/60/60/24}"
                                                                              pattern="#0"
                                                                              var="days"/><%--取天数整数--%>
                                                            <c:if test="${days <= 7}">NEW</c:if>
                                                        </c:otherwise>
                                                    </c:choose>
                                                </span>
                                <span class="entry-meta">
                                                    <span class="date">
                                                         <fmt:formatDate value="${a.articleCreateTime}"
                                                                         pattern="yyyy年MM月dd日"/>
                                                        &nbsp;&nbsp;
                                                    </span>
                                                    <span class="views">
                                                        <i class="fa fa-eye"></i>
                                                            ${a.articleViewCount} views
                                                    </span>
                                                    <span class="comment">&nbsp;&nbsp;
                                                        <a href="/article/${a.articleId}#comments"
                                                           rel="external nofollow">
                                                          <i class="fa fa-comment-o"></i>
                                                            <c:choose>
                                                                <c:when test="${a.articleCommentCount==0}">
                                                                    发表评论
                                                                </c:when>
                                                                <c:otherwise>
                                                                    ${a.articleCommentCount}
                                                                </c:otherwise>
                                                            </c:choose>
                                                        </a>
                                                    </span>
                                                </span>
                                <div class="clear"></div>
                            </div><!-- .entry-content -->
                            <span class="entry-more">
                                            <a href="/article/${a.articleId}"
                                               rel="bookmark">阅读全文
                                            </a>
                                        </span>
                        </article>
                    </c:forEach>
                    <%--文章列表-end--%>
                </c:when>
            </c:choose>
        </main>
        <%@ include file="../Public/part/paging.jsp" %>

    </div>
    <%--  博客主体-左侧正文 end--%>
</rapid:override>

<%@ include file="../Public/framework.jsp" %>

5.2 TagController

package com.test.ssm.blog.controller.home;

import com.github.pagehelper.PageInfo;
import com.test.ssm.blog.entity.Article;
import com.test.ssm.blog.entity.Tag;
import com.test.ssm.blog.enums.ArticleStatus;
import com.test.ssm.blog.service.ArticleService;
import com.test.ssm.blog.service.TagService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;

import java.util.HashMap;
import java.util.List;

@Controller
public class TagController {

    @Autowired
    private TagService tagService;
    @Autowired
    private ArticleService articleService;

    //根据标签查询文章
    @RequestMapping("/tag/{tagId}")
    public String getArticleListBytTag(@PathVariable("tagId")Integer tagId,
                                       @RequestParam(required = false,defaultValue = "1")Integer pageIndex,
                                       @RequestParam(required = false,defaultValue = "10")Integer pageSize, Model model){
        //该标签信息
        Tag tag = tagService.getTagById(tagId);
        if (tag == null) {
            return "redirect:/404";
        }
        model.addAttribute("tag", tag);

        //文章列表
        HashMap<String, Object> criteria = new HashMap<>(2);
        criteria.put("tagId", tagId);
        criteria.put("status", ArticleStatus.PUBLISH.getValue());
        PageInfo<Article> articlePageInfo = articleService.pageArticle(pageIndex, pageSize, criteria);
        System.out.println(articlePageInfo.getSize());
        model.addAttribute("pageInfo", articlePageInfo);

        //侧边栏
        //标签列表显示
        List<Tag> allTagList = tagService.listTag();
        model.addAttribute("allTagList", allTagList);
        //获得随机文章
        List<Article> randomArticleList = articleService.listRandomArticle(8);
        model.addAttribute("randomArticleList", randomArticleList);
        //获得热评文章
        List<Article> mostCommentArticleList = articleService.listArticleByCommentCount(8);
        model.addAttribute("mostCommentArticleList", mostCommentArticleList);
        model.addAttribute("pageUrlPrefix", "/tag?pageIndex");
        return "Home/Page/articleListByTag";

    }
}

5.3 页面显示

在点击上面页面的Spring的标签链接之后,跳转的页面显示为:

六.评论操作

6.1 评论显示JSP

我们在之前的第二节文章详细信息JSP页面的时候,就发现了底下的部分就是评论部分。也就是说评论并没有单独的JSP。我们把这个评论框的JSP拿出来

  <%--评论区域 start--%>
            <div class="scroll-comments"></div>
            <div id="comments" class="comments-area">
                <div id="respond" class="comment-respond">
                    <h3 id="reply-title" class="comment-reply-title"><span id="reply-title-word">发表评论</span>
                        <a rel="nofollow" id="cancel-comment-reply-link"
                           href="/article/${article.articleId}#respond"
                           style="">取消回复</a>
                    </h3>
                    <form id="comment_form" method="post">
                        <c:if test="${sessionScope.user!=null}">
                            <div class="user_avatar">
                                <img alt="努力"
                                     src="${sessionScope.user.userAvatar}"
                                     class="avatar avatar-64 photo" height="64" width="64">
                                登录者:${sessionScope.user.userNickname}
                                <br> <a href="javascript:void(0)" onclick="logout()">登出</a>
                                <input type="hidden" name="commentRole" value="1">
                                <input type="hidden" name="commentAuthorName"
                                       value="${sessionScope.user.getUserNickname()}">
                                <input type="hidden" name="commentAuthorEmail"
                                       value="${sessionScope.user.getUserEmail()}">
                                <input type="hidden" name="commentAuthorUrl" value="${sessionScope.user.getUserUrl()}">
                            </div>
                        </c:if>
                        <p class="comment-form-comment">
                            <textarea id="comment" name="commentContent" rows="4" tabindex="1" required></textarea>
                        </p>
                        <div id="comment-author-info">
                            <input type="hidden" name="commentPid" value="0">
                            <input type="hidden" name="commentPname" value="">
                            <c:if test="${sessionScope.user == null}">
                                <input type="hidden" name="commentRole" value="0">
                                <p class="comment-form-author">
                                    <label for="author_name">
                                        昵称<span class="required">*</span>
                                    </label>
                                    <input type="text" name="commentAuthorName" id="author_name" class="" value=""
                                           tabindex="2" required>
                                </p>
                                <p class="comment-form-email">
                                    <label for="author_email">
                                        邮箱<span class="required">*</span>
                                    </label>
                                    <input type="email" name="commentAuthorEmail" id="author_email" class="" value=""
                                           tabindex="3" required>
                                </p>
                                <p class="comment-form-url">
                                    <label for="author_url">网址</label>
                                    <input type="url" name="commentAuthorUrl" id="author_url" class="" value=""
                                           tabindex="4">
                                </p>
                            </c:if>
                        </div>
                        <div class="clear"></div>
                        <p class="form-submit">
                            <input id="submit" name="submit" type="submit" tabindex="5" value="提交评论">
                            <input type="hidden" name="commentArticleId"
                                   value="${article.articleId}" id="article_id">
                            <input type="hidden" name="commentPid" id="comment_pid" value="0">
                        </p>
                    </form>
                </div>

                <ol class="comment-list">
                    <c:set var="floor" value="0"/>
                    <c:forEach items="${commentList}" var="c">
                        <c:if test="${c.commentPid == 0}">
                            <c:set var="floor" value="${floor + 1}"/>
                            <li class="comments-anchor">
                                <ul id="anchor-comment-${c.commentId}"></ul>
                            </li>
                            <li class="comment">
                                <div id="div-comment-${c.commentId}" class="comment-body">
                                    <div class="comment-author vcard">
                                        <img class="avatar" src="${c.commentAuthorAvatar}" alt="avatar"
                                             style="display: block;">
                                        <strong>${c.commentAuthorName} </strong>
                                        <c:if test="${c.commentRole == 1}">
                                            <i class="fa fa-black-tie" style="color: #c40000;"></i>
                                            <span class=""
                                                  style="margin-top: 2px!important;color: #c40000;font-size: 13px;;"><b>博主</b></span>
                                        </c:if>
                                        <span class="comment-meta commentmetadata">
                                            <span class="ua-info" style="display: inline;">
                                                <br>
                                                <span class="comment-aux">
                                                    <span class="reply">
                                                        <a rel="nofollow" class="comment-reply-link" href="#respond"
                                                           onclick="replyComment()">回复
                                                        </a>
                                                    </span>
                                                    <fmt:formatDate value="${c.commentCreateTime}"
                                                                    pattern="yyyy年MM月dd日 HH:mm:ss"/>&nbsp;
                                                    <c:if test="${sessionScope.user != null}">
                                                        <a href="javascript:void(0)"
                                                           onclick="deleteComment(${c.commentId})">删除</a>
                                                        <a class="comment-edit-link"
                                                           href="/admin/comment/edit/${c.commentId}"
                                                           target="_blank">编辑</a>
                                                    </c:if>
                                                    <span class="floor"> &nbsp;${floor}楼 </span>
                                                </span>
                                            </span>
                                        </span>
                                        <p>
                                            <c:if test="${c.commentPid!=0}">
                                                <span class="at">@ ${c.commentPname}</span>
                                            </c:if>
                                                ${c.commentContent}
                                        </p>
                                    </div>
                                </div>
                                <ul class="children">
                                    <c:set var="floor2" value="0"/>
                                    <c:forEach items="${commentList}" var="c2">
                                        <c:if test="${c.commentId == c2.commentPid}">
                                            <c:set var="floor2" value="${floor2+1}"/>
                                            <li class="comments-anchor">
                                                <ul id="anchor-comment-${c2.commentId}"></ul>
                                            </li>
                                            <li class="comment">
                                                <div id="div-comment-${c.commentId}" class="comment-body">
                                                    <div class="comment-author vcard">
                                                        <img class="avatar" src="${c2.commentAuthorAvatar}" alt="avatar"
                                                             style="display: block;">
                                                        <strong>${c2.commentAuthorName} </strong>
                                                        <c:if test="${c2.commentRole==1}">
                                                            <i class="fa fa-black-tie" style="color: #c40000;"></i>
                                                            <span class=""
                                                                  style="margin-top: 2px!important;color: #c40000;font-size: 13px;;"><b>博主</b></span>
                                                        </c:if>
                                                        <span class="comment-meta">
                                                    <span class="ua-info" style="display: inline;">
                                                    <br>
                                                    <span class="comment-aux">
                                                        <span class="reply">
                                                            <a rel="nofollow" class="comment-reply-link" href="#respond"
                                                               onclick="replyComment()">回复
                                                            </a>
                                                        </span>
                                                        <fmt:formatDate value="${c2.commentCreateTime}"
                                                                        pattern="yyyy年MM月dd日 HH:mm:ss"/>&nbsp;
                                                        <c:if test="${sessionScope.user != null}">
                                                            <a href="javascript:void(0)"
                                                               onclick="deleteComment(${c2.commentId})">删除</a>
                                                            <a class="comment-edit-link"
                                                               href="/admin/comment/edit/${c2.commentId}"
                                                               target="_blank">编辑</a>
                                                        </c:if>
                                                        <span class="floor"> &nbsp;${floor2}层 </span>
                                                    </span>
                                                </span>
                                                    </span>
                                                        <p>
                                                            <c:if test="${c2.commentPid!=0}">
                                                                <c:if test="${c2.commentPid!=0}">
                                                                    <span class="at">@ ${c2.commentPname}</span>
                                                                </c:if>
                                                                ${c2.commentContent}
                                                            </c:if>
                                                        </p>
                                                    </div>
                                                </div>
                                            </li>
                                        </c:if>
                                    </c:forEach>
                                </ul>
                            </li>
                        </c:if>
                    </c:forEach>
                </ol>
            </div>

这个最终显示有两种不同的显示:

一种是在博主登录的情况下,会显示隐藏的信息,例如博主的图像和昵称等。在这个下面会显示评论的列表:

一种是在没有登录的情况下,需要你自己填入基本信息进行评论,如下:

6.1 CommentController

我们在上面的JSP中并没有发现表单的action和请求链接,这是因为在JS中获取了表单信息,使用ajax的形式提交评论。在评论成功后,会将刚才的输入的信息放入到缓存中,设置一个过期时间。

//ajax提交评论信息
$("#comment_form").submit(function () {
    $.ajax({
        async: false,
        type: "POST",
        url: '/comment',
        contentType: "application/x-www-form-urlencoded; charset=utf-8",
        data: $("#comment_form").serialize(),
        success: function (data) {
            if (data.code == 0) {
                layer.msg("评论成功!");
                localStorage.setItem('author', $("#author_name").val());
                localStorage.setItem('email', $("#author_email").val());
                localStorage.setItem('url', $("#author_url").val());
                window.setTimeout("window.location.reload()", 2000);
                return false;
            } else {
                layer.msg(data.msg);
            }

        },
        error: function () {
        }
    })
    return false;
})

CommentController层:要注意评论时候的身份

@Controller
@RestController
public class CommentController {

    @Autowired
    private CommentService commentService;

    @Autowired
    private ArticleService articleService;

    //添加评论
    @RequestMapping(value = "/comment",method = RequestMethod.POST)
    public JsonResult insertComment(HttpServletRequest servletRequest, Comment comment){
        //添加评论
        comment.setCommentCreateTime(new Date());
        comment.setCommentIp(MyUtils.getIpAddr(servletRequest));
        if(servletRequest.getSession().getAttribute("user")!=null){
            //如果是在登录的情况下,创建的comment是以博主身份创建的
            comment.setCommentRole(Role.ADMIN.getValue());
        }else{
            comment.setCommentRole(Role.VISITOR.getValue());
        }
        //根据Email创建头像
        comment.setCommentAuthorAvatar(MyUtils.getGravatar(comment.getCommentAuthorEmail()));

        //过滤字符:HtmlUtil
        comment.setCommentContent(HtmlUtil.escape(comment.getCommentContent()));
        comment.setCommentAuthorName(HtmlUtil.escape(comment.getCommentAuthorName()));
        comment.setCommentAuthorEmail(HtmlUtil.escape(comment.getCommentAuthorEmail()));
        comment.setCommentAuthorUrl(HtmlUtil.escape(comment.getCommentAuthorUrl()));

        try{
            commentService.insertComment(comment);
            Article article=articleService.getArticleByStatusAndId(ArticleStatus.PUBLISH.getValue(),comment.getCommentArticleId());
            articleService.updateCommentCount(article.getArticleId());
        }catch (Exception e){
            e.printStackTrace();
            return new JsonResult().fail();
        }
        return new JsonResult().ok();

    }
}

然后我们注意到这个删除和回复只在博主登录后才会有,也就是博主才有资格对评论进行删除和编辑的操作。这个发送的请求就是管理员后台评论的请求。

七.搜索操作

这是主页点击搜索后出现的搜索框:

    <%--搜索框--%>
    <aside class="widget widget_search">
        <div class="searchbar">
            <form method="get" id="searchform1" action="/search">
                    <span> <input type="text" value="" name="keywords" id="s1" placeholder="输入搜索内容" required="">
                        <button type="submit" id="searchsubmit1">搜索</button>
                    </span>
            </form>
        </div>
        <div class="clear"></div>
    </aside>

这是文章详情页的搜索框:

    <%--搜索框--%>
    <aside class="widget widget_search">
        <div class="searchbar">
            <form method="get" id="searchform1" action="/search">
                    <span> <input type="text" value="" name="keywords" id="s1" placeholder="输入搜索内容" required="">
                        <button type="submit" id="searchsubmit1">搜索</button>
                    </span>
            </form>
        </div>
        <div class="clear"></div>
    </aside>

7.1 搜索后显示文章列表JSP页面

输入搜索内容,点击搜索后跳转的页面。会显示文章列表。

<%@ page language="java" contentType="text/html; charset=UTF-8"
         pageEncoding="UTF-8" %>
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>
<%@ taglib uri="http://java.sun.com/jsp/jstl/fmt" prefix="fmt" %>
<%@ taglib uri="http://java.sun.com/jsp/jstl/functions" prefix="fn" %>
<%@ taglib prefix="rapid" uri="http://www.rapid-framework.org.cn/rapid" %>


<rapid:override name="title">
    <title>搜索结果</title>
</rapid:override>

<rapid:override name="breadcrumb">
    <%--面包屑导航 start--%>
    <nav class="breadcrumb">
        <a class="crumbs" href="/">
            <i class="fa fa-home"></i>首页</a>
            <i class="fa fa-angle-right"></i>
        搜索 ${param.keywords} 找到 ${pageInfo.total} 个与之相关的文章
    </nav>
    <%--面包屑导航 end--%>
</rapid:override>

<rapid:override name="left">
    <%--博客主体 start--%>
    <section id="content" class="site-content shadow">
        <%--博客主体-左侧正文 start--%>
        <section id="primary" class="content-area">
            <main id="main" class="site-main">
                <c:choose>
                    <c:when test="${pageInfo.list.size() != 0}">
                        <%--文章列表-start--%>
                        <c:forEach items="${pageInfo.list}" var="a">

                            <article class="post">

                                <figure class="thumbnail">
                                    <a href="/article/${a.articleId}">
                                        <img width="280" height="210"
                                             src="/img/thumbnail/random/img_${a.articleId%15}.jpg"
                                             class="attachment-content size-content wp-post-image"
                                             alt="${a.articleTitle}">
                                    </a>
                                    <span class="cat">
                                              <a href="/category/${a.categoryList[0].categoryId}">${a.categoryList[0].categoryName}</a>
                                        </span>
                                </figure>

                                <header class="entry-header">
                                    <h2 class="entry-title">
                                        <a href="/article/${a.articleId}" rel="bookmark">
                                                ${a.articleTitle}
                                        </a>
                                    </h2>
                                </header><!-- .entry-header -->

                                <div class="entry-content">
                                    <div class="archive-content">
                                            ${a.articleSummary}...
                                    </div>
                                    <span class="title-l"></span>
                                    <span class="new-icon">
                                                    <c:choose>
                                                        <c:when test="${a.articleStatus == 2}">
                                                            <i class="fa fa-bookmark-o"></i>
                                                        </c:when>
                                                        <c:otherwise>
                                                            <jsp:useBean id="nowDate"
                                                                         class="java.util.Date"/> <%--当前时间--%>
                                                            <c:set var="interval"
                                                                   value="${nowDate.time - a.articleCreateTime.time}"/><%--时间差毫秒数--%>
                                                            <fmt:formatNumber value="${interval/1000/60/60/24}"
                                                                              pattern="#0"
                                                                              var="days"/><%--取天数整数--%>
                                                            <c:if test="${days <= 7}">NEW</c:if>
                                                        </c:otherwise>
                                                    </c:choose>
                                                </span>
                                    <span class="entry-meta">
                                                    <span class="date">
                                                         <fmt:formatDate value="${a.articleCreateTime}"
                                                                         pattern="yyyy年MM月dd日"/>
                                                        &nbsp;&nbsp;
                                                    </span>
                                                    <span class="views">
                                                        <i class="fa fa-eye"></i>
                                                            ${a.articleViewCount} views
                                                    </span>
                                                    <span class="comment">&nbsp;&nbsp;
                                                        <a href="/article/${a.articleId}#comments"
                                                           rel="external nofollow">
                                                          <i class="fa fa-comment-o"></i>
                                                            <c:choose>
                                                                <c:when test="${a.articleCommentCount==0}">
                                                                    发表评论
                                                                </c:when>
                                                                <c:otherwise>
                                                                    ${a.articleCommentCount}
                                                                </c:otherwise>
                                                            </c:choose>
                                                        </a>
                                                    </span>
                                                </span>
                                    <div class="clear"></div>
                                </div><!-- .entry-content -->
                                <span class="entry-more">
                                            <a href="/article/${a.articleId}"
                                               rel="bookmark">阅读全文
                                            </a>
                                        </span>
                            </article>
                        </c:forEach>
                        <%--文章列表-end--%>
                    </c:when>
                </c:choose>
            </main>
            <%@ include file="../Public/part/paging.jsp" %>

        </section>
    </section>
</rapid:override>



<%@ include file="../Public/framework.jsp" %>

7.2 Controller

根据传入过来的关键字进行搜索。

   //搜索
    @RequestMapping("/search")
    public String search(@RequestParam("keywords")String keywords,
                         @RequestParam(required = false,defaultValue = "1")Integer pageIndex,
                         @RequestParam(required = false,defaultValue = "10")Integer pageSize,
                         Model model){

        //文章列表
        HashMap<String,Object> criteria=new HashMap<>(2);
        criteria.put("status",ArticleStatus.PUBLISH.getValue());
        criteria.put("keywords",keywords);
        //根据文章状态和输入的关键字进行搜索
        PageInfo<Article> articlePageInfo=articleService.pageArticle(pageIndex,pageSize,criteria);
        model.addAttribute("pageInfo",articlePageInfo);

        //侧边栏显示
        //标签列表显示
        List<Tag> allTagList=tagService.listTag();
        model.addAttribute("allTagList",allTagList);

        //获得随机文章
        List<Article> randomArticleList=articleService.listRandomArticle(8);
        model.addAttribute("randomArticleList",randomArticleList);

        //获得热评文章
        List<Article> mostCommentArticleList=articleService.listArticleByCommentCount(8);
        model.addAttribute("mostCommentArticleList",mostCommentArticleList);

        //最新评论
        List<Comment> recentCommentList=commentService.listRecentComment(10);
        model.addAttribute("recentCommentList",recentCommentList);

        model.addAttribute("pageUrlPrefix","/search?pageIndex");

        return "Home/Page/search";
    }

7.3 页面显示

查找到相关的文章:

没有与关键字相关的文章:

八.公告显示

博客主页会显示滚动的公告,点击这个公告就会到公告详细页面。

8.1 公告详情JSP页面

<%@ page language="java" contentType="text/html; charset=UTF-8"
         pageEncoding="UTF-8" %>
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>
<%@ taglib uri="http://java.sun.com/jsp/jstl/fmt" prefix="fmt" %>
<%@ taglib uri="http://java.sun.com/jsp/jstl/functions" prefix="fn" %>
<%@ taglib prefix="rapid" uri="http://www.rapid-framework.org.cn/rapid" %>

<rapid:override name="header-style">
    <style>
        .entry-title {
            background: #f8f8f8;
        }
    </style>
</rapid:override>


<rapid:override name="breadcrumb">
    <%--面包屑导航 start--%>
    <nav class="breadcrumb">
        <a class="crumbs" href="/">
            <i class="fa fa-home"></i>首页
        </a>
        <i class="fa fa-angle-right"></i>
        博客公告
        <i class="fa fa-angle-right"></i>
        正文
    </nav>
    <%--面包屑导航 end--%>
</rapid:override>


<rapid:override name="left">
    <%--博客主体-左侧文章正文 start--%>
    <div id="primary" class="content-area">
        <main id="main" class="site-main" role="main">
            <article class="post" style="min-height: 500px;">
                <header class="entry-header">
                    <h1 class="entry-title">
                           ${notice.noticeTitle}
                    </h1>
                </header><!-- .entry-header -->
                <div class="entry-content">
                    <div class="single-content">
                            ${notice.noticeContent}
                    </div>

                    <br><br>

                    <footer class="single-footer">
                        <ul class="single-meta">
                            <li class="r-hide">
                                <a href="javascript:pr()" title="侧边栏">
                                    <i class="fa fa-caret-left"></i>
                                    <i class="fa fa-caret-right"></i>
                                </a>
                            </li>
                        </ul>
                        <ul id="fontsize">
                            <li>A+</li>
                        </ul>
                        <div class="single-cat-tag">
                            <div class="single-cat">日期:<fmt:formatDate value="${notice.noticeCreateTime}" pattern="yyyy年MM月dd日"/>
                            </div>
                        </div>
                    </footer><!-- .entry-footer -->


                    <div class="clear"></div>
                </div><!-- .entry-content -->
            </article><!-- #post -->



        </main>
        <!-- .site-main -->
    </div>
    <%--博客主体-左侧文章正文end--%>
</rapid:override>


<%--侧边栏 start--%>
<rapid:override name="right">
    <%@include file="../Public/part/sidebar-3.jsp" %>
</rapid:override>
<%--侧边栏 end--%>

<%@ include file="../Public/framework.jsp" %>

8.2 HomeNoticeController

package com.test.ssm.blog.controller.home;

import com.test.ssm.blog.entity.Article;
import com.test.ssm.blog.entity.Notice;
import com.test.ssm.blog.service.ArticleService;
import com.test.ssm.blog.service.NoticeService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;

import java.util.List;

@Controller
public class HomeNoticeController {
    @Autowired
    private NoticeService noticeService;

    @Autowired
    private ArticleService articleService;


    //公告详情页
    @RequestMapping(value = "/notice/{noticeId}")
    public String NoticeDetailView(@PathVariable("noticeId")Integer noticeId, Model model){
        //公告内容和信息显示
        Notice notice=noticeService.getNoticeById(noticeId);
        model.addAttribute("notice",notice);

        //侧边栏
        //热评文章
        List<Article> mostCommentArticleList=articleService.listArticleByCommentCount(8);
        model.addAttribute("mostCommentArticleList",mostCommentArticleList);
        return "Home/Page/noticeDetail";


    }
}

8.3 页面显示

九.申请友链

我们可以看到首页文章列表下有一个博客链接,这个就是友情链接。

我们可以在博客前台进行友情链接的申请。

9.1 申请JSP页面

<%@ page language="java" contentType="text/html; charset=UTF-8"
         pageEncoding="UTF-8" %>
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>
<%@ taglib uri="http://java.sun.com/jsp/jstl/fmt" prefix="fmt" %>
<%@ taglib uri="http://java.sun.com/jsp/jstl/functions" prefix="fn" %>
<%@ taglib prefix="rapid" uri="http://www.rapid-framework.org.cn/rapid" %>

<rapid:override name="header-style">
    <style>
        .entry-title {
            background: #f8f8f8;
        }
    </style>
    <link rel="stylesheet" href="/plugin/layui/css/layui.css">
</rapid:override>


<rapid:override name="breadcrumb">
    <%--面包屑导航 start--%>
    <nav class="breadcrumb">
        <a class="crumbs" href="/">
            <i class="fa fa-home"></i>首页
        </a>
        <i class="fa fa-angle-right"></i>
        申请友链
        <i class="fa fa-angle-right"></i>
        正文
    </nav>
    <%--面包屑导航 end--%>
</rapid:override>


<rapid:override name="left">
    <%--博客主体-左侧文章正文 start--%>
    <div id="primary" class="content-area">
        <main id="main" class="site-main" role="main">
            <article class="post" style="min-height: 500px;">
                <header class="entry-header">
                    <h1 class="entry-title">
                           申请友链
                    </h1>
                </header><!-- .entry-header -->
                <div class="entry-content">
                    <div class="single-content">
                        <form class="layui-form layui-form-pane" id="applyLinkForm"  method="post">
                            <div class="layui-form-item">
                                <label class="layui-form-label">网站名称</label>
                                <div class="layui-input-block">
                                    <input type="text" name="linkName"  placeholder="如:${options.optionSiteTitle}" class="layui-input" required>
                                </div>
                            </div>
                            <div class="layui-form-item">
                                <label class="layui-form-label">网站地址</label>
                                <div class="layui-input-block">
                                    <input type="url" name="linkUrl"  placeholder="如:" class="layui-input" required>
                                </div>
                            </div>
                            <div class="layui-form-item">
                                <label class="layui-form-label">网站描述</label>
                                <div class="layui-input-block">
                                    <input type="text" name="linkDescription" placeholder="如:${options.optionSiteDescrption}" class="layui-input" required>
                                </div>
                            </div>

                            <div class="layui-form-item layui-form-text">
                                <label class="layui-form-label">备注</label>
                                <div class="layui-input-block">
                                    <textarea placeholder="申请原因和联系方式" class="layui-textarea" name="linkOwnerContact" maxlength="100"></textarea>
                                </div>
                            </div>
                            <div class="layui-form-item">
                                <button class="layui-btn" lay-submit="">提交申请</button>
                            </div>
                        </form>


                    </div>

                    <br><br>

                    <footer class="single-footer">
                        <ul class="single-meta">
                            <li class="r-hide">
                                <a href="javascript:pr()" title="侧边栏">
                                    <i class="fa fa-caret-left"></i>
                                    <i class="fa fa-caret-right"></i>
                                </a>
                            </li>
                        </ul>
                        <ul id="fontsize">
                            <li>A+</li>
                        </ul>
                    </footer><!-- .entry-footer -->


                    <div class="clear"></div>
                </div><!-- .entry-content -->
            </article><!-- #post -->



        </main>
        <!-- .site-main -->
    </div>
    <%--博客主体-左侧文章正文end--%>
</rapid:override>

<%--侧边栏 start--%>
<rapid:override name="right">
    <%@include file="../Public/part/sidebar-3.jsp" %>
</rapid:override>
<%--侧边栏 end--%>

<rapid:override name="footer-script">
    <script>

    </script>
</rapid:override>

<%@ include file="../Public/framework.jsp" %>

9.2 HomeLinkController

package com.test.ssm.blog.controller.home;

import com.test.ssm.blog.entity.Article;
import com.test.ssm.blog.entity.Link;
import com.test.ssm.blog.enums.LinkStatus;
import com.test.ssm.blog.service.ArticleService;
import com.test.ssm.blog.service.LinkService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.ResponseBody;

import java.util.Date;
import java.util.List;

@Controller
public class HomeLinkController {
    @Autowired
    private LinkService linkService;
    @Autowired
    private ArticleService articleService;

    @RequestMapping("/applyLink")
    public String applyLinkView(Model model)
    {
        //侧边栏显示
        //显示热评文章
        List<Article> mostCommentArticleList=articleService.listArticleByCommentCount(8);
        model.addAttribute("mostCommentArticleList",mostCommentArticleList);
        return "Home/Page/applyLink";
    }

    @RequestMapping(value = "/applyLinkSubmit",method = RequestMethod.POST)
    @ResponseBody
    public void applyLinkSubmit(Link link){
        link.setLinkStatus(LinkStatus.HIDDEN.getValue());
        link.setLinkCreateTime(new Date());
        link.setLinkUpdateTime(new Date());
        linkService.insertLink(link);
    }
}

9.3 页面显示

十.页面操作

10.1 文章归档

点击,就是显示所有文章列表。

 //文章归档页面显示
    @RequestMapping(value = "/articleFile")
    public String articleFile(Model model){
        List<Article> articleList=articleService.listAllNotWithContent();
        model.addAttribute("articleList",articleList);

        //热评文章
        List<Article> mostCommentArticleList=articleService.listArticleByCommentCount(8);
        model.addAttribute("mostCommentArticleList",mostCommentArticleList);
        return "Home/Page/articleFile";
    }

10.2 关于本站

这个显示是在Heade.jsp,显示的是菜单信息

 <div class="menu-topmenu-container">
                <ul id="menu-topmenu" class="top-menu">
                    <c:forEach items="${menuList}" var="m">
                        <li class="menu-item">
                            <c:if test="${m.menuLevel==1}">
                                <a href="${m.menuUrl}" >
                                    <i class="${m.menuIcon}"></i>
                                    <span class="font-text">${m.menuName}&nbsp;</span>&nbsp;
                                </a>
                            </c:if>
                        </li>
                    </c:forEach>
                </ul>
            </div>

我们可以看到的是这个菜单的链接请求是发送菜单的Url。申请友链和文章归档都是早早添加到Controller中的, 不是自定义的。关于本站相当于自定义页面,所以为了方便其他自定义页面的请求,所以获取的是URL,然后根据这个进行页面查询。

点击关于本站,显示关于本站的基本信息。

页面详情页的Controller:

  //页面详情页
    @RequestMapping(value = "/{key}")
    public String pageDetail(@PathVariable("key")String key, Model model){
        Page page=pageService.getPageByKey(1,key);
        if(page==null){
            return "redirect:/404";
        }
        model.addAttribute("page",page);
        //侧边栏
        //热评文章
        List<Article> mostCommentArticleList=articleService.listArticleByCommentCount(8);
        model.addAttribute("mostCommentArticleList",mostCommentArticleList);
        return "Home/Page/page";
    }

点击了关于本站,页面显示:

10.3 站点地图

站点地图是一个放网站所有链接的页面。

Controller:

 //站点地图显示
    @RequestMapping(value = "/map")
    public String siteMap(Model model)
    {
        //文章
        List<Article> articleList=articleService.listAllNotWithContent();
        model.addAttribute("articleList",articleList);
        //分类
        List<Category> categoryList=categoryService.listCategory();
        model.addAttribute("categoryList",categoryList);
        //标签
        List<Tag> tagList=tagService.listTag();
        model.addAttribute("tagList",tagList);

        //侧边栏
        //热评
        List<Article> mostCommentArticleList=articleService.listArticleByCommentCount(8);
        model.addAttribute("mostCommentArticleList",mostCommentArticleList);
        return "Home/Page/siteMap";
    }

页面显示为:

 

 

 

  个人博客系统(HituxBlog)是专业为个人建站而开发的一款网站程序。该系统采用最流行的ASP+ACCESS进行搭建,页面使用DIV+CSS进行编写,全面兼容时下IE、FireFox、Chrome等主流浏览器。系统内置多达30款主题及精美相册,后台一键切换。前台所有内容均可以在后台进行修改删除等操作。   通过该系统建立您的博客或者是个人网站将变得轻而易举。不需要具备多么专业的网页设计知识,不需要对程序有多熟悉,仅仅下载海纳个人博客的源码上传到您申请的空间里,即生成了您的网站。接下来您要做的只是对网站的更新,写一篇文章,或是上传一张图片。将更多的精力用在宣传您的网站上,而不是建立网站。21世纪人人上网,人人有网站的时代,您不再无助,HituxBlog愿助您一臂之力,携手共进! 系统无与伦比的五大特色: 1、页面设计够简单,拒绝花俏; 2、便捷后台,管理前台所有内容; 3、页面全静态化,易优化且高效; 4、内置多达30款主题,自由切换; 5、相册展示模式,美伦美奂。 -------------------------安 全 建 议------------------------------ 后台管理地址:http://你的网站域名/AdminCool/login.asp 用户名:admin 密码:admin 后台文件夹名:AdminCool 数据库存放位置:DatabaseX 提醒:为确保网站安全,我们建议: 1、更改默认的后台用户名和密码;
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值