个人博客平台随笔
1.前端使用到的工具
Semantic UI:Recipes | Semantic UI
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/semantic-ui@2.5.0/dist/semantic.min.css">
<script src="https://cdn.jsdelivr.net/npm/semantic-ui@2.5.0/dist/semantic.min.js"></script>
semantic ui依赖 jQuery:jsDelivr - A free, fast, and reliable CDN for JS and open source
https://cdn.jsdelivr.net/npm/jquery@3.6/dist/jquery.min.js
markdown编译器采用: Editor.md - 开源在线 Markdown 编辑器
随机图片:Lorem Picsum
---博客详情页面优化部分---
排版:typo.css
添加动画效果:animate.css
代码高亮显示:Prism官网下载prism.css和prism.js
生成目录:Tocbot官网下载tocbot.css和tocbot.min.js
生成二维码:qrcode.min.js
2.前端遇到的问题
在引用别人的typo.css时候和自己的css发生冲突,导致页面显示效果不佳
解决:将别人的typo.css封闭起来,在css中全部加上一个.typo前缀,只有包含typo元素下面的才会起作用。
3.idea构建框架
在idea中新建项目,选择Spring Initializer,选择java语言,maven类型,选择jdk系欸java版本后,添加相关依赖
在项目的src/main/resources中将application改成.yml文件,复制几个分别为开发环境application-dev.yml和生产环境application-pro.yml
在application.yml指定当前活跃的配置
application-pro.yml中
spring: datasource: driver-class-name: com.mysql.cj.jdbc.Driver url: jdbc:mysql://localhost:3306/blog?serverTimezone=UTC username: root password: 123456 jpa: hibernate: ddl-auto: none show-sql: true logging: level: root: warn com.example: info file: path: log/blog-pro.log server: port: 8081
application-dev.yml中
spring: datasource: driver-class-name: com.mysql.cj.jdbc.Driver url: jdbc:mysql://localhost:3306/blog?serverTimezone=UTC username: root password: 123456 jpa: hibernate: ddl-auto: update show-sql: true logging: level: root: info com.example: debug file: path: log/blog-dev.log
测试:
启动后访问8080,可以正常访问到404即成功
然后在application.yml中active: dev改成active: pro,重新启动访问8081出现404即配置成功
测试完后将application.yml的active改回dev
4.异常拦截处理
ControllerExceptionHandler.java
package com.example.handler; import jakarta.servlet.http.HttpServletRequest; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.core.annotation.AnnotationUtils; import org.springframework.web.bind.annotation.ControllerAdvice; import org.springframework.web.bind.annotation.ExceptionHandler; import org.springframework.web.bind.annotation.ResponseStatus; import org.springframework.web.servlet.ModelAndView; @ControllerAdvice public class ControllerExceptionHandler { private final Logger logger = LoggerFactory.getLogger(this.getClass()); //统一拦截所有exception @ExceptionHandler(Exception.class) public ModelAndView exceptionHandler(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 mv = new ModelAndView(); mv.addObject("url", request.getRequestURL()); mv.addObject("exception", e); mv.setViewName("error/error"); //设置返回的页面 return mv; } }
IndexController.java
package com.example.web; import com.example.NotFoundException; import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.GetMapping; @Controller public class IndexController { @GetMapping("/") public String index(){ // int i = 9/0; //测试500 String blog = null; if (blog == null) { throw new NotFoundException("博客不存在"); } return "index"; } }
NotFoundException.java
package com.example; import org.springframework.http.HttpStatus; import org.springframework.web.bind.annotation.ResponseStatus; @ResponseStatus(HttpStatus.NOT_FOUND) public class NotFoundException extends RuntimeException { public NotFoundException() { } public NotFoundException(String message) { super(message); } public NotFoundException(String message, Throwable cause) { super(message, cause); } }
5.日志处理
aspect/LogAsppect.java
package com.example.aspect; import jakarta.servlet.http.HttpServletRequest; import org.aspectj.lang.JoinPoint; import org.aspectj.lang.annotation.*; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.stereotype.Component; import org.springframework.web.context.request.RequestContextHolder; import org.springframework.web.context.request.ServletRequestAttributes; import java.util.Arrays; @Aspect @Component public class LogAspect { private final Logger logger = LoggerFactory.getLogger(this.getClass()); @Pointcut("execution(* com.example.web.*.*(..))") public void log() { } @Before("log()") public void doBefore(JoinPoint joinPoint) { ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes(); HttpServletRequest request = attributes.getRequest(); String url = String.valueOf(request.getRequestURL()); 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 doAfterReture(Object result) { logger.info("Result : {}" , 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) + '}'; } } }
访问http://localhost:8080/2/hi结果
6.将静态页面导入到idea
重新启动,可能会出现有些样式没有引用成功,原因是这些静态页面没有使用 thymeleaf 模板,对于相对路径全部都需要添加一下th:href="@{/css/xx.css}"
为了不一个个页面修改,对于公共的部分可以统一处理
统一处理的方法:新建一个_fragments.html页面,在所有页面中,找一个head中的link最多的复制进来,统一修改
在其他页面中这样运用
对于底部的js部分也可以作统一处理
对于公共菜单,底部也进行处理
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· Manus的开源复刻OpenManus初探
· AI 智能体引爆开源社区「GitHub 热点速览」
· 三行代码完成国际化适配,妙~啊~
· .NET Core 中如何实现缓存的预热?