# springboot+thymeleaf 个人博客 **Repository Path**: sicauliuyang/blog ## Basic Information - **Project Name**: springboot+thymeleaf 个人博客 - **Description**: No description available - **Primary Language**: Java - **License**: Apache-2.0 - **Default Branch**: master - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 6 - **Forks**: 1 - **Created**: 2020-02-07 - **Last Updated**: 2025-01-24 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README # 项目概述 项目地址: https://gitee.com/sicauliuyang/blog 1. 项目功能流程图 ![在这里插入图片描述](https://images.gitee.com/uploads/images/2020/0208/111302_36e07273_1697445.png) 2. 技术组合 后台: Spring Boot + JPA + thymeleaf框架 数据库: MySQL 前端UI: Semantic UI框架 3. 插件集成 [编辑器 Markdown](https://pandao.github.io/editor.md/) [内容排版 typo.css](https://github.com/sofish/typo.css) [动画 animate.css](https://daneden.github.io/animate.css/) [代码高亮 prism](https://github.com/PrismJS/prism) [目录生成 Tocbot](https://tscanlin.github.io/tocbot/) [滚动侦测 waypoints](http://imakewebthings.com/waypoints/) [平滑滚动 jquery.scrollTo](https://github.com/flesler/jquery.scrollTo) [二维码生成 qrcode.js](https://davidshimjs.github.io/qrcodejs/) # 框架搭建 ## 引入spring boot模块 - web - Thymeleaf - JPA - MySQL - Aspects - DevTools ### application.yml配置 **application.yml:** ```yaml spring: thymeleaf: mode: HTML profiles: active: dev # 启动开发配置文件 ``` **applicatioin-dev.yml:** ```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:** ```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** ```xml ${FILE_LOG_PATTERN} ${LOG_FILE} ${LOG_FILE}.%d{yyyy-MM-dd}.%i 30 10MB ``` ### 异常处理 1. 定义错误页面 在template/error文件夹下定义常见的错误页面,如下。springboot项目出现错误时可以调用对应错误页面。 - 404.html - 500.html 2. 全局处理异常 统一处理异常 ```java /** * 拦截所有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; } } ``` 上面统一处理异常代码中 相应状态码如下 定义异常类 ```java /** * 资源找不到 */ @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页面,如果有调用该页面。 3. 错误页面信息处理 th:utext: 对于显示的字符串不转义,th:remove="tag" 移除html标签 在错误页面添加这点代码,方便在代码中检查 ### 日志处理 创建aop切面类 ```java /** * 记录日志类 * 通过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 用法