个人博客项目总结

项目概述

项目地址: https://gitee.com/sicauliuyang/blog

  1. 项目功能流程图
    个人博客项目总结_第1张图片
  2. 技术组合

后台: Spring Boot + JPA + thymeleaf框架
数据库: MySQL
前端UI: Semantic UI框架

  1. 插件集成

编辑器 Markdown

内容排版 typo.css

动画 animate.css

代码高亮 prism

目录生成 Tocbot

滚动侦测 waypoints

平滑滚动 jquery.scrollTo

二维码生成 qrcode.js

框架搭建

引入spring boot模块

  • web
  • Thymeleaf
  • JPA
  • MySQL
  • Aspects
  • DevTools

application.yml配置

application.yml:

spring:
  thymeleaf:
    mode: HTML
  profiles:
    active: dev # 启动开发配置文件

applicatioin-dev.yml:

spring:
  datasource:
    driver-class-name: com.mysql.cj.jdbc.Driver
    url: jdbc:mysql://localhost:3306/blog?useUnicode=true&characterEncoding=utf-8&serverTimezone=GMT%2B8
    username: root
    password: 123456
  jpa:
    hibernate:
      # 每次运行程序,没有表格会新建表格,表内有数据不会清空,只会更新
      ddl-auto: update
    # 在控制台显示sql语句
    show-sql: true
logging:
  level:
    root: info
    cn.edu.bupt.blog: debug
  file:
    name: log/blog-dev.log
server:
  port: 8082

application-pro.yml:

spring:
  datasource:
    driver-class-name: com.mysql.cj.jdbc.Driver
    url: jdbc:mysql://localhost:3306/blog?useUnicode=true&characterEncoding=utf-8&serverTimezone=GMT%2B8
    username: root
    password: 123456
  jpa:
    hibernate:
      # 每次运行程序,没有表格会新建表格,表内有数据不会清空,只会更新
      ddl-auto: none
    # 在控制台显示sql语句
    show-sql: true
logging:
  level:
    root: info
    cn.edu.bupt.blog: debug
  file:
    name: log/blog-dev.log
server:
  port: 8081

在资源文件夹下创建日志配置文件

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>
        

异常处理

  1. 定义错误页面

在template/error文件夹下定义常见的错误页面,如下。springboot项目出现错误时可以调用对应错误页面。

  • 404.html

  • 500.html

  1. 全局处理异常

统一处理异常

/**
 * 拦截所有controller抛出的异常
 */
@ControllerAdvice
public class ControllerExceptionHandle {
    // 获取日志日志对象
    private final Logger logger = LoggerFactory.getLogger(ControllerExceptionHandle.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.getClass());

        // 当代码错误引发的异常类与注解标记的类一直,则抛出异常
        if(AnnotationUtils.findAnnotation(this.getClass(), ResponseStatus.class) != null) {
            throw e;
        }
        ModelAndView mav = new ModelAndView();
        mav.addObject("url",request.getRequestURL());
        mav.addObject("excepation",e);
        // 跳转到对应页面
        mav.setViewName("error/error");
        return mav;
    }
}

上面统一处理异常代码中 相应状态码如下

定义异常类

/**
 * 资源找不到
 */
@ResponseStatus(HttpStatus.NOT_FOUND)
public class NotFoundException extends RuntimeException{
    public NotFoundException() {
        super();
    }

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

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

当抛出NotFoundException ,统一异常处理类会抛出该异常,这时由springboot框架自己处理。再到template/error文件夹下寻找404.html页面,如果有调用该页面。

  1. 错误页面信息处理

th:utext: 对于显示的字符串不转义,th:remove=“tag” 移除html标签

在错误页面添加这点代码,方便在代码中检查

日志处理

创建aop切面类

/**
 * 记录日志类
 * 通过aspect
 */
@Aspect // 标记这是一个切面类
/**
 *  泛指各种组件,就是说当我们的类不属于各种归类的时候(不属于@Controller、@Services等的时候),
 *  我们就可以使用@Component来标注这个类
 */
@Component
public class LogAspect {
    // 用于控制台日志输出
    private final Logger logger = LoggerFactory.getLogger(this.getClass());

    // 定义切点,用于扫描:cn.edu.bupt.blog.web 的所有类的所有方法
    @Pointcut("execution(* cn.edu.bupt.blog.web.*.*(..))")
    public void log() {
    }

    // 界面点之前执行
    @Before("log()")
    public void doBefore(JoinPoint joinPoint) {
        // 获取HttpServletRequest
        ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
        HttpServletRequest request = attributes.getRequest();
        String url = request.getRequestURL().toString();
        String ip = request.getRemoteAddr();
        String classMethod = joinPoint.getSignature().getDeclaringTypeName() + "." + joinPoint.getSignature().getName();;
        // 参数列表
        Object[] args = joinPoint.getArgs();
        RequestLog requestLog = new RequestLog(url,ip,classMethod,args);
        logger.info("request ---- {}",requestLog);
    }

    // 界面点之后执行
    @After("log()")
    public void doAfter() {
        logger.info("----------doAfter----------");
    }

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

    // 请求日志对象
    private class RequestLog{
        private String url;
        private String ip;
        private String classMethod;
        // 参数列表
        private Object[] args;

        public RequestLog(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 "RequestLog{" +
                    "url='" + url + '\'' +
                    ", ip='" + ip + '\'' +
                    ", classMethod='" + classMethod + '\'' +
                    ", args=" + Arrays.toString(args) +
                    '}';
        }
    }
}

doAfterReturning:最后执行

thymeleaf 模板

  1. th:value 和 th:text 的区别
    th:value 和input相关
    th:text 和div相关

  2. 在js中,使用[[${内容}]] 来显示后台返回的内容

项目经验

命名约定

Service/DAO层命名约定:

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

注解

  • @Service用于标注业务层组件

  • @Controller用于标注控制层组件(如struts中的action)

  • @Repository用于标注数据访问组件,即DAO组件.

  • @Component泛指组件,当组件不好归类的时候,我们可以使用这个注解进行标注。

需要积累

  • jpql 用法

  • jpa 用法

你可能感兴趣的:(项目)