Spring Boot - 博客后台管理系统 -【未完】

Spring Boot - 博客后台管理系统 -【未完】_第1张图片

Spring Boot - 博客后台管理系统 -【未完】_第2张图片

文章目录

      • 1.2 功能规划
    • 2、页面设计与开发
      • 2.1 设计
      • 2.2 页面开发
      • 2.3 插件集成
      • 2.4 工具
      • 2.5 页面原型
        • 前端页面
        • 后台页面
      • 3.1 构建与配置
      • 3.2 异常处理
      • 3.4 页面处理
      • 4.1 实体设计
      • 4.2 应用分层
      • 4.3 约定
      • 状态码
    • 5、后台管理功能实现
      • 5.1 登录
      • 5.2 分类管理
      • 5.3 标签管理
      • 5.4 博客管理
    • 6、前端展示功能实现
      • 6.1 首页展示
      • 6.2 分类页
      • 6.3 标签页
      • 6.4 归档页
      • 6.5 关于我
      • 2.4 ~~目录结构~~ (后面:命名约定为准)
      • 3.3 日志处理

技术栈:

  • 后端:Spring + Springmvc + mybatis(mybatis plus)
  • 后端脚手架:Spring Boot 2.2.2
  • 模板: thymeleaf模板
  • 数据库:MySQL5.5
  • 前端框架:vue 3
  • 前端脚手架:vue-cli 3
  • UI:Semantic UI框架 、element UI
  • 前端路由:vue-router
  • 权限管理:shiro
  • 缓存:redis

Spring Boot - 博客后台管理系统 -【未完】_第3张图片    Spring Boot - 博客后台管理系统 -【未完】_第4张图片    Spring Boot - 博客后台管理系统 -【未完】_第5张图片    在这里插入图片描述    Spring Boot - 博客后台管理系统 -【未完】_第6张图片    Spring Boot - 博客后台管理系统 -【未完】_第7张图片

Spring Boot - 博客后台管理系统 -【未完】_第8张图片   在这里插入图片描述

工具与环境:

  • IDEA eclipse
  • Maven 3
  • JDK 8
  • Axure RP 8
  • lombok - 简化代码

1.2 功能规划

Spring Boot - 博客后台管理系统 -【未完】_第9张图片

2、页面设计与开发

2.1 设计

页面规划:

前端展示:首页、详情页、分类、标签、归档、关于我

后台管理:模板页

2.2 页面开发

  • vue

  • iview
    Semantic UI官网 开始时候用semantic UI(各种问题),逐渐替换
    Semantic UI中文官网
    Semantic UI 中文 API

  • webpack

  • 背景图片资源
    使用:canvas-ribbon.js

  • 图床 sm ms
    图床 评测

  • 古诗api - https://www.jinrishici.com/#

  • 博客园 大佬 - https://www.cnblogs.com/gaoya666/category/1222505.html

2.3 插件集成

  • Pjax 异步加载 - githubvue-router 实现SPA
    《Laravel-Pjax 使用》 - https://zhuanlan.zhihu.com/p/89629239
    《jquery-pjax中文文档 - BSify》 - http://bsify.admui.com/jquery-pjax/
    《如何将Pjax整合进网站,实现全站无刷新加载?》 - https://cloud.tencent.com/developer/article/1147511
    《过渡页面 》 - https://www.jianshu.com/p/808a647dc324
    (或者使用:history.js - https://github.com/balupton/history.js)

  • 编辑器 Markdown
    HyperMD
    《Markdown编辑器 HyperMD for Typecho》

  • Font Awesome

  • openmoji - 免费开源表情符号

  • 内容排版 typo.css

  • 动画 animate.css
    用 semantic 自带的

  • 代码高亮 prism
    异步加载 加上 Prism.highlightAll();
    http://www.mamicode.com/info-detail-1041544.html

  • 目录生成 Tocbot
    editor.md 内置目录 - [toc]

  • 滚动侦测 waypoints

  • 平滑滚动 jquery.scrollTo

  • 二维码生成 qrcode.js

  • 《【插件】博客 - 看板娘》

  • 《给博客添加夜间模式》 - https://imjad.cn/archives/code/add-night-mode-to-blog/

  • [文字]图标生成
    http://www.network-science.de/ascii/
    http://patorjk.com/software/taag/#p=display&f=Graffiti&t=Type%20Something%20

  • 小图标 - www.easyicon.net

2.4 工具

  • api 测试 - postman - https://www.postman.com/
  • 开发:sts、vscode
  • 环境:java8、node.js

2.5 页面原型

前端页面

登录

Spring Boot - 博客后台管理系统 -【未完】_第10张图片

welcome页

Spring Boot - 博客后台管理系统 -【未完】_第11张图片

后台页面

图片上传 - 参考博客园:https://upload.cnblogs.com/avatar/crop

Spring Boot - 博客后台管理系统 -【未完】_第12张图片

3.1 构建与配置

1、引入Spring Boot模块:

  • web
  • Thymeleaf
  • JPA mybatis - plus
  • MySQL
  • Aspects
  • DevTools

2、application.yml配置

  • 使用 thymeleaf 3

pom.xml:

<thymeleaf.version>3.0.2.RELEASEthymeleaf.version>
<thymeleaf-layout-dialect.version>2.1.1thymeleaf-layout-dialect.version>
application.yml:
spring:
  thymeleaf:
    mode: HTML

# 暂时没用

# 默认 HTML5 、 这里改html3也能用

  • 数据库连接配置
spring:
  datasource:
    driver-class-name: com.mysql.jdbc.Driver
    url: jdbc:mysql://localhost:3306/blog?useUnicode=true&characterEncoding=utf-8
    username: root
    password: root

# 用 mybatis
  jpa:
    hibernate:
      ddl-auto: update
    show-sql: true




#server
server:
  port: 80
  servlet:
    context-path: /
  • 日志配置

    application.yml:

logging:
  level:
    root: info
    com.imcoding: debug
  file: log/imcoding.log

logback-spring.xml:


<configuration>
    
    <include resource="org/springframework/boot/logging/logback/defaults.xml" />
    <property name="LOG_FILE" value="${LOG_FILE:-${LOG_PATH:-${LOG_TEMP:-${java.io.tmpdir:-/tmp}}}/spring.log}"/>
    <include resource="org/springframework/boot/logging/logback/console-appender.xml" />

    
    <appender name="TIME_FILE"
              class="ch.qos.logback.core.rolling.RollingFileAppender">
        <encoder>
            <pattern>${FILE_LOG_PATTERN}pattern>
        encoder>
        <file>${LOG_FILE}file>
        <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
            <fileNamePattern>${LOG_FILE}.%d{yyyy-MM-dd}.%ifileNamePattern>
            
            <maxHistory>30maxHistory>
            
            <timeBasedFileNamingAndTriggeringPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP">
                <maxFileSize>10MBmaxFileSize>
            timeBasedFileNamingAndTriggeringPolicy>

        rollingPolicy>
    appender>

    <root level="INFO">
        <appender-ref ref="CONSOLE" />
        <appender-ref ref="TIME_FILE" />
    root>

configuration>

  • 生产环境与开发环境配置
    • application-dev.yml
    • application-pro.yml

3.2 异常处理

1、定义错误页面

  • 404
  • 500
  • error

2、全局处理异常

统一处理异常:

@ControllerAdvice
public class ControllerExceptionHandler {

    private final Logger logger = LoggerFactory.getLogger(ControllerExceptionHandler.class);
    /**
     * 异常处理
     * @param request
     * @param e
     * @return
     */
    @ExceptionHandler({Exception.class})
    public ModelAndView handleException(HttpServletRequest request, Exception e) throws Exception {

        logger.error("Request URL : {} , Exception : {}", request.getRequestURL(), e);

        if (AnnotationUtils.findAnnotation(e.getClass(), ResponseStatus.class) != null) {
            throw e;
        }
        ModelAndView mav = new ModelAndView();
        mav.addObject("url", request.getRequestURL());
        mav.addObject("exception", e);
        mav.setViewName("error/error");

        return mav;
    }
}

错误页面异常信息显示处理:

<div>
    <div th:utext="'<!--'" th:remove="tag">div>
    <div th:utext="'Failed Request URL : ' + ${url}" th:remove="tag">div>
    <div th:utext="'Exception message : ' + ${exception.message}" th:remove="tag">div>
    <ul th:remove="tag">
        <li th:each="st : ${exception.stackTrace}" th:remove="tag"><span th:utext="${st}" th:remove="tag">span>li>
    ul>
    <div th:utext="'-->'" th:remove="tag">div>
div>

3、资源找不到异常

@ResponseStatus(HttpStatus.NOT_FOUND)
public class NotFoundExcepiton extends RuntimeException {

    public NotFoundExcepiton() {
    }

    public NotFoundExcepiton(String message) {
        super(message);
    }

    public NotFoundExcepiton(String message, Throwable cause) {
        super(message, cause);
    }
}

3.4 页面处理

1、静态页面导入project

2、thymeleaf布局

  • 定义fragment
  • 使用fragment布局

3、错误页面美化

4、设计与规范

4.1 实体设计

实体类:

  • 博客 Blog
  • 博客分类 Type
  • 博客标签 Tag
  • 博客评论 Comment
  • 用户 User

实体关系:(暂时先这样吧)

Spring Boot - 博客后台管理系统 -【未完】_第13张图片

  • 文档:https://download.csdn.net/download/LawssssCat/12137698

一张表一个 po 对象

Blog类:

Tag类:

Type类:

Comment类:

User类:

Role类

4.2 应用分层

Spring Boot - 博客后台管理系统 -【未完】_第14张图片

4.3 约定

Service/DAO层命名约定:

  • 获取单个对象的方法用 find 做前缀。Object
  • 获取多个对象的方法用 find 做前缀。Objects
  • 获取单个vo对象 findxxxinfo
  • 获取统计值的方法用 count 做前缀。
  • 插入的方法用 save (推荐) 或 insert 做前缀。
  • 删除的方法用 remove(推荐) 或 delete 做前缀。
  • 修改的方法用 update 做前缀。

如:

功能 url 请求方式 物理路径 转发 重定向 controller service dao(根据 mp 看情况修改)
登录页面 /login /system/login ~ pageController.toLoginPage
user
用户登录 /user/login POST JsonResult 前端处理 userController.doLogin shiro subject.login
管理页面 展示 /user、/xxx /system/user、/system/xxx ~ pageController.toSystemPage Model add User
管理页面修改 /user/edit 、 /xxx/edit /system/user_edit 、 /system/xxx_edit ~ pageController.toSystemPageEdit Model add User
用户列表 /user/list?pageCurrent=xx&&username=xx GET JsonResult userController.findPageObject userService.dofindPageObject userDao.findPageObject
用户校验/查重 /user/valid?id=xx&&xx GET JsonResult userController.validObject userService.doValidObject userDao.validObject
用户添加 /user/{id}?xx POST JsonResult userController.saveObject userService.doSaveObject userDao.insertObject
用户详情 /user/{id} GET JsonResult userController.findObjectInfo userService.dofindObjectInfo userDao.findObjectInfo
用户修改 /user/{id}?xx PUT JsonResult userController.updateObject userService.doUpdateObject userDao.updateObject
用户删除 /user/{id} DELETE JsonResult userController.removeObject userService.doRemoveObject userDao.deleteObject
userState
用户状态(userState)列表 /us/list GET JsonResult userStateController.findObjects userStateService.doFindObjects userStateDao.findObjects
用户状态(userState)查询 by userState-Id /us/{id} GET JsonResult userStateController.findObjectById userStateService.doFindObjectById userStateDao.findObjectById
用户状态校验/查重
/us/valid?id=xx&&xxx…
(添加校验 不传 id)
GET JsonResult userStateController.validObject userStateService.doValidObject userStateDao.validObject
用户状态(userState) 添加 /us?xxx POST JsonResult userStateController.saveObject userStateService.doSaveObject userStateService.insertObject
用户状态(userState) 修改 /us?xxx PUT JsonResult userStateController.updateObject userStateService.doUpdateObject userStateService.updateObject
用户状态(userState) 删除 /us/{id} DELETE JsonResult userStateController.removeObject userStateService.doRemoveObject userStateService.deleteObject
avatar
图片查询 /avatar/{id} GET JsonResult avatarController.findObjectById avatarService.doFindObjectById avatarDao.findObjectById
图片列表 /avatar/list?pageCurrent=xx&&name=xx GET JsonResult avatarController.findPageObject avatorService.doFindPageObject avatarDao.findPageObject
图片校验/查重
1.id以外
2.名字不能重复
/avatar/valid?id=xx&&xx… GET JsonResult avatarController.validObject avatorService.doValidObject avatarDao.validObject
图片上传 /avatar/load POST JsonResult
首页展示 / 、/index /blog/article ~ pageController.toIndexPage

Spring Boot - 博客后台管理系统 -【未完】_第15张图片

Spring Boot - 博客后台管理系统 -【未完】_第16张图片

状态码

状态码 说明 类型
200 正常
400 异常

5、后台管理功能实现

5.1 登录

1、构建登录页面和后台管理首页

2、UserService和UserRepository

3、LoginController实现登录

4、MD5加密

5、登录拦截器

5.2 分类管理

1、分类管理页面

2、分类列表分页

{
  "content":[
    {"id":123,"title":"blog122","content":"this is blog content"},
    {"id":122,"title":"blog121","content":"this is blog content"},
    {"id":121,"title":"blog120","content":"this is blog content"},
    {"id":120,"title":"blog119","content":"this is blog content"},
    {"id":119,"title":"blog118","content":"this is blog content"},
    {"id":118,"title":"blog117","content":"this is blog content"},
    {"id":117,"title":"blog116","content":"this is blog content"},
    {"id":116,"title":"blog115","content":"this is blog content"},
    {"id":115,"title":"blog114","content":"this is blog content"},
    {"id":114,"title":"blog113","content":"this is blog content"},
    {"id":113,"title":"blog112","content":"this is blog content"},
    {"id":112,"title":"blog111","content":"this is blog content"},
    {"id":111,"title":"blog110","content":"this is blog content"},
    {"id":110,"title":"blog109","content":"this is blog content"},
    {"id":109,"title":"blog108","content":"this is blog content"}],
  "last":false,
  "totalPages":9,
  "totalElements":123,
  "size":15,
  "number":0,
  "first":true,
  "sort":[{
    "direction":"DESC",
    "property":"id",
    "ignoreCase":false,
    "nullHandling":"NATIVE",
    "ascending":false
  }],
  "numberOfElements":15
}

3、分类新增、修改、删除

5.3 标签管理

5.4 博客管理

1、博客分页查询

2、博客新增

3、博客修改

4、博客删除

6、前端展示功能实现

6.1 首页展示

1、博客列表

2、top分类

3、top标签

4、最新博客推荐

5、博客详情

1、Markdown 转换 HTML

  • commonmark-java https://github.com/atlassian/commonmark-java
  • pom.xml引用commonmark和扩展插件
<dependency>
   <groupId>com.atlassian.commonmarkgroupId>
   <artifactId>commonmarkartifactId>
   <version>0.10.0version>
dependency>
<dependency>
   <groupId>com.atlassian.commonmarkgroupId>
   <artifactId>commonmark-ext-heading-anchorartifactId>
   <version>0.10.0version>
dependency>
<dependency>
   <groupId>com.atlassian.commonmarkgroupId>
   <artifactId>commonmark-ext-gfm-tablesartifactId>
   <version>0.10.0version>
dependency>

2、评论功能

  • 评论信息提交与回复功能
  • 评论信息列表展示功能
  • 管理员回复评论功能

6.2 分类页

6.3 标签页

6.4 归档页

6.5 关于我

2.4 目录结构 (后面:命名约定为准)

/system/... 管理页面 /blog/... 游客页面 /article/... 文章页面

/user/list
/user/edit
/user/remove
/

请求、 对类的请求

templates

│ application-dev.yml // 配置文件

├─pages // 公共页面 - thymeleaf 模板路径
│ │ /login - 登录
│ │ / - 主页
│ │ /about - 关于我
│ │
│ ├─admin // 管理页面
│ │ md //编辑
│ │
│ ├─article // 文章页面
│ │ details/xxxx
│ │
│ └─fragments // _part of page
│ _topnav.html

/doLoginUI --> 登录

/doIndexUI --> /article --> / - 主页
/about - 关于我
/article/details/xxx - id=xxx文章路径

/doAdminUI --> 管理页面
/admin/md/?aritcleId=xxx - 修改id=xxx文章
/admin/

static

├─dist // 静态资源
│ ├─css
│ ├─js
│ ├─images // 图片
│ └─lib // 插件


3.3 日志处理

1、记录日志内容

  • 请求 url
  • 访问者 ip
  • 调用方法 classMethod
  • 参数 args
  • 返回内容

2、记录日志类: (后期改为 log 类 存数据库)

@Aspect
@Component
public class LogAspect {

    private final Logger logger = LoggerFactory.getLogger(this.getClass());

    /**
     * 定义切面
     */
    @Pointcut("execution(* com.imcoding.web.*.*(..))")
    public void log() {
    }

    @Before("log()")
    public void doBefore(JoinPoint joinPoint) {
        ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
        HttpServletRequest request = attributes.getRequest();
        String classMethod = joinPoint.getSignature().getDeclaringTypeName() + "." + joinPoint.getSignature().getName();
        ReqeustLog reqeustLog = new ReqeustLog(
                request.getRequestURL().toString(),
                request.getRemoteAddr(),
                classMethod,
                joinPoint.getArgs()
        );
        logger.info("Rquest  ----- {}",reqeustLog);
    }

    @After("log()")
    public void doAfter() {
        //logger.info("---------- doAfter 2 ----------");
    }

    @AfterReturning(returning = "result",pointcut = "log()")
    public void doAtfertRturning(Object result) {
        logger.info("Return ------ {}",result );
    }


    private class ReqeustLog {
        private String url;
        private String ip;
        private String classMethod;
        private Object[] args;

        public ReqeustLog(String url, String ip, String classMethod, Object[] args) {
            this.url = url;
            this.ip = ip;
            this.classMethod = classMethod;
            this.args = args;
        }

        @Override
        public String toString() {
            return "ReqeustLog{" +
                    "url='" + url + '\'' +
                    ", ip='" + ip + '\'' +
                    ", classMethod='" + classMethod + '\'' +
                    ", args=" + Arrays.toString(args) +
                    '}';
        }
    }

}

你可能感兴趣的:(#,SpringBoot,博客框架,-,hexo)