这个基于Spring Boot的个人博客系统是我在2023年完成的一个全栈项目,前后耗时约3个月。系统采用前后端分离架构,后端基于Spring Boot 2.7 + MyBatis Plus构建,前端使用Vue 3 + Element Plus实现。项目从零开始搭建,完整实现了用户认证、文章管理、评论互动等核心功能模块,并最终通过了严格的黑盒测试。
Spring Boot的自动配置特性大幅减少了XML配置的工作量。我在项目中主要利用了以下特性:
实际开发中发现,Spring Boot的版本选择很关键。最初使用2.4版本时遇到与MyBatis Plus的兼容性问题,升级到2.7.0后解决。
Vue 3的组合式API相比选项式API更适合复杂的前端交互场景。在博客系统中,我特别利用了:
javascript复制// 请求拦截器示例
service.interceptors.request.use(
config => {
const token = localStorage.getItem('token')
if (token) {
config.headers['Token'] = token
}
return config
},
error => {
return Promise.reject(error)
}
)
系统采用典型的三层架构:
核心表结构设计考虑了以下原则:
sql复制CREATE TABLE `article` (
`id` bigint NOT NULL AUTO_INCREMENT,
`title` varchar(100) NOT NULL,
`content` longtext NOT NULL,
`category_id` bigint DEFAULT NULL,
`user_id` bigint NOT NULL,
`view_count` int DEFAULT '0',
`status` tinyint DEFAULT '0' COMMENT '0-草稿 1-已发布',
`create_time` datetime DEFAULT CURRENT_TIMESTAMP,
PRIMARY KEY (`id`),
KEY `idx_category` (`category_id`),
KEY `idx_user` (`user_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
系统安全方面实现了:
认证流程采用JWT方案,关键实现点包括:
java复制@Component
public class JwtInterceptor implements HandlerInterceptor {
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) {
String token = request.getHeader("Token");
if (StringUtils.isBlank(token)) {
throw new UnauthorizedException("请先登录");
}
Claims claims = JwtUtil.parseToken(token);
if (claims == null || JwtUtil.isTokenExpired(claims.getExpiration())) {
throw new UnauthorizedException("Token已失效");
}
// 将用户信息存入ThreadLocal
UserContext.setUserId(claims.get("userId", Long.class));
return true;
}
}
支持的功能包括:
上传图片时需要注意:
实现特点:
采用分层测试方案:
推荐部署方案:
Nginx配置片段:
nginx复制server {
listen 80;
server_name blog.example.com;
location /api {
proxy_pass http://127.0.0.1:8080;
proxy_set_header Host $host;
}
location / {
root /var/www/blog-frontend;
try_files $uri $uri/ /index.html;
}
}
Spring Boot多环境配置:
yaml复制# application-prod.yml
spring:
datasource:
url: jdbc:mysql://mysql-master:3306/blog?useSSL=false
username: prod_user
password: ${DB_PASSWORD}
redis:
host: redis-cluster
password: ${REDIS_PASSWORD}
在开发过程中有几个特别值得注意的点:
接口版本控制:从项目开始就应该在API路径中加入/v1/这样的版本标识,为后续升级留有余地。我最初没有考虑这点,导致后期不得不通过Nginx重写规则来解决兼容问题。
异常处理体系:建议统一异常处理架构,我最终采用的方案是:
java复制@Bean
public Docket api() {
return new Docket(DocumentationType.SWAGGER_2)
.select()
.apis(RequestHandlerSelectors.basePackage("com.blog.controller"))
.paths(PathSelectors.any())
.build();
}