当前位置: 首页 > news >正文

SpringBoot学习日记 Day10:企业级博客系统开发实战(一)

一、项目启航:从零搭建企业级博客系统

今天开始真正意义上的企业级项目实战!我将把前9天学到的所有知识融会贯通,构建一个可部署的博客系统。这就像用乐高积木搭建城堡,每个模块都要严丝合缝。

二、项目初始化:打好坚实基础

1. 一键创建项目骨架

# 使用Spring Initializr快速创建项目
spring init --dependencies=web,data-jpa,mysql,security,validation,actuator,redis \--groupId=com.example --artifactId=blog-system \--name=BlogSystem --package-name=com.example.blog \--java-version=11

2. 项目结构设计

src/
├── main/
│   ├── java/com/example/blog/
│   │   ├── config/           # 配置类
│   │   ├── controller/       # 控制层
│   │   ├── entity/          # 实体类
│   │   ├── repository/      # 数据访问
│   │   ├── service/         # 服务层
│   │   ├── dto/            # 数据传输对象
│   │   ├── security/        # 安全相关
│   │   └── BlogApplication.java
│   └── resources/
│       ├── application.yml
│       ├── application-dev.yml
│       ├── application-prod.yml
│       └── static/
└── test/                    # 测试代码

3. 多环境配置

application.yml(公共配置):
spring:profiles:active: devjackson:date-format: yyyy-MM-dd HH:mm:sstime-zone: GMT+8server:servlet:context-path: /apilogging:pattern:console: "%d{yyyy-MM-dd HH:mm:ss} [%thread] %-5level %logger{36} - %msg%n"application-dev.yml(开发环境):
spring:datasource:url: jdbc:mysql://localhost:3306/blog_dev?useUnicode=true&characterEncoding=utf8&serverTimezone=Asia/Shanghaiusername: rootpassword: 123456driver-class-name: com.mysql.cj.jdbc.Driverjpa:hibernate:ddl-auto: updateshow-sql: trueh2:console:enabled: falsedebug: true

三、核心技术集成:一站式配置

1. Swagger3文档配置

@Configuration
@OpenAPIDefinition(info = @Info(title = "博客系统API文档",version = "1.0",description = "企业级博客系统接口文档",contact = @Contact(name = "开发者", email = "dev@example.com"))
)
public class SwaggerConfig {@Beanpublic OpenAPI customOpenAPI() {return new OpenAPI().components(new Components().addSecuritySchemes("JWT", new SecurityScheme().type(SecurityScheme.Type.HTTP).scheme("bearer").bearerFormat("JWT"))).addSecurityItem(new SecurityRequirement().addList("JWT"));}
}

2. 统一响应体设计

@Data
@AllArgsConstructor
@NoArgsConstructor
public class Result<T> {private Integer code;private String message;private T data;private Long timestamp;public static <T> Result<T> success(T data) {return new Result<>(200, "成功", data, System.currentTimeMillis());}public static <T> Result<T> error(Integer code, String message) {return new Result<>(code, message, null, System.currentTimeMillis());}
}

3. 全局异常处理增强

@RestControllerAdvice
@Slf4j
public class GlobalExceptionHandler {@ExceptionHandler(BusinessException.class)public Result<Void> handleBusinessException(BusinessException e) {log.warn("业务异常: {}", e.getMessage());return Result.error(e.getCode(), e.getMessage());}@ExceptionHandler(AccessDeniedException.class)public Result<Void> handleAccessDeniedException(AccessDeniedException e) {log.warn("权限拒绝: {}", e.getMessage());return Result.error(403, "没有访问权限");}@ExceptionHandler(Exception.class)public Result<Void> handleException(Exception e) {log.error("系统异常: ", e);return Result.error(500, "系统繁忙,请稍后再试");}
}

四、用户模块:安全与认证体系

1. 用户实体设计

@Data
@Entity
@Table(name = "users")
@Where(clause = "is_deleted = 0")
public class User {@Id@GeneratedValue(strategy = GenerationType.IDENTITY)private Long id;@Column(unique = true, nullable = false)private String username;@Column(nullable = false)private String password;@Column(unique = true)private String email;private String avatar;@Enumerated(EnumType.STRING)private UserRole role = UserRole.USER;@CreationTimestampprivate LocalDateTime createTime;@UpdateTimestampprivate LocalDateTime updateTime;private Boolean isDeleted = false;public enum UserRole {USER, ADMIN}
}

2. JWT认证体系

@Component
@RequiredArgsConstructor
public class JwtAuthenticationFilter extends OncePerRequestFilter {private final JwtUtils jwtUtils;private final UserDetailsService userDetailsService;@Overrideprotected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) throws ServletException, IOException {try {String jwt = parseJwt(request);if (jwt != null && jwtUtils.validateJwtToken(jwt)) {String username = jwtUtils.getUserNameFromJwtToken(jwt);UserDetails userDetails = userDetailsService.loadUserByUsername(username);UsernamePasswordAuthenticationToken authentication = new UsernamePasswordAuthenticationToken(userDetails, null, userDetails.getAuthorities());authentication.setDetails(new WebAuthenticationDetailsSource().buildDetails(request));SecurityContextHolder.getContext().setAuthentication(authentication);}} catch (Exception e) {logger.error("Cannot set user authentication: {}", e);}filterChain.doFilter(request, response);}private String parseJwt(HttpServletRequest request) {String headerAuth = request.getHeader("Authorization");if (StringUtils.hasText(headerAuth) && headerAuth.startsWith("Bearer ")) {return headerAuth.substring(7);}return null;}
}

3. 用户服务实现

@Service
@RequiredArgsConstructor
public class UserService {private final UserRepository userRepository;private final PasswordEncoder passwordEncoder;private final JwtUtils jwtUtils;@Transactionalpublic User register(RegisterDTO dto) {if (userRepository.existsByUsername(dto.getUsername())) {throw new BusinessException("用户名已存在");}if (userRepository.existsByEmail(dto.getEmail())) {throw new BusinessException("邮箱已存在");}User user = new User();user.setUsername(dto.getUsername());user.setPassword(passwordEncoder.encode(dto.getPassword()));user.setEmail(dto.getEmail());return userRepository.save(user);}public String login(LoginDTO dto) {User user = userRepository.findByUsername(dto.getUsername()).orElseThrow(() -> new BusinessException("用户不存在"));if (!passwordEncoder.matches(dto.getPassword(), user.getPassword())) {throw new BusinessException("密码错误");}return jwtUtils.generateToken(user.getUsername());}
}

五、文章模块:核心业务实现

1. 文章实体设计

@Data
@Entity
@Table(name = "articles")
public class Article {@Id@GeneratedValue(strategy = GenerationType.IDENTITY)private Long id;@Column(nullable = false)private String title;@Column(columnDefinition = "TEXT")private String content;private String summary;@ManyToOne@JoinColumn(name = "user_id")private User author;private Integer viewCount = 0;@Enumerated(EnumType.STRING)private ArticleStatus status = ArticleStatus.DRAFT;@CreationTimestampprivate LocalDateTime createTime;@UpdateTimestampprivate LocalDateTime updateTime;public enum ArticleStatus {DRAFT, PUBLISHED, DELETED}
}

2. 文章服务层

@Service
@RequiredArgsConstructor
@Transactional(readOnly = true)
public class ArticleService {private final ArticleRepository articleRepository;public Page<Article> getPublishedArticles(Pageable pageable) {return articleRepository.findByStatus(ArticleStatus.PUBLISHED, pageable);}public Article getArticleById(Long id) {return articleRepository.findById(id).orElseThrow(() -> new BusinessException("文章不存在"));}@Transactionalpublic Article createArticle(Article article, User author) {article.setAuthor(author);article.setStatus(ArticleStatus.DRAFT);return articleRepository.save(article);}@Transactionalpublic Article updateArticle(Long id, Article updatedArticle, User currentUser) {Article article = getArticleById(id);if (!article.getAuthor().getId().equals(currentUser.getId())) {throw new BusinessException("没有修改权限");}article.setTitle(updatedArticle.getTitle());article.setContent(updatedArticle.getContent());article.setSummary(updatedArticle.getSummary());return articleRepository.save(article);}
}

六、Docker化部署:生产环境准备

1. Dockerfile配置

# 构建阶段
FROM maven:3.8.4-openjdk-11 AS builder
WORKDIR /app
COPY pom.xml .
COPY src ./src
RUN mvn package -DskipTests# 运行阶段
FROM openjdk:11-jre-slim
WORKDIR /app# 安装时区配置
RUN apt-get update && apt-get install -y tzdata
ENV TZ=Asia/Shanghai# 复制应用
COPY --from=builder /app/target/blog-system-0.0.1.jar app.jar# 创建非root用户
RUN groupadd -r spring && useradd -r -g spring spring
USER springEXPOSE 8080
ENTRYPOINT ["java", "-jar", "/app.jar"]

2. Docker Compose编排

version: '3.8'services:app:build: .ports:- "8080:8080"environment:- SPRING_PROFILES_ACTIVE=prod- DB_PASSWORD=mysql123depends_on:- mysql- redisrestart: unless-stoppedmysql:image: mysql:8.0environment:MYSQL_ROOT_PASSWORD: rootpassMYSQL_DATABASE: blog_prodMYSQL_USER: blog_userMYSQL_PASSWORD: mysql123volumes:- mysql_data:/var/lib/mysqlrestart: unless-stoppedredis:image: redis:6.2-alpineports:- "6379:6379"volumes:- redis_data:/datarestart: unless-stoppedvolumes:mysql_data:redis_data:

七、今日成果验收

✅ 已完成功能:
- 项目骨架搭建和多环境配置
- Swagger3 API文档集成
- 统一响应体和异常处理
- JWT认证安全体系
- 用户注册登录功能
- 文章基础CRUD操作
- Docker化部署配置

🚀 启动验证:
# 开发环境启动
mvn spring-boot:run -Dspring-boot.run.profiles=dev

# Docker编译运行
docker-compose up --build

# 访问验证
curl http://localhost:8080/api/v1/articles

八、明日开发计划

1. 评论系统实现:嵌套评论、回复功能
2. 权限控制增强:角色权限、操作拦截
3. 数据统计功能:浏览量统计、用户活跃度
4. 缓存优化:Redis缓存热点数据
5. 前端界面集成:Vue/React前端项目

今日感悟:企业级项目开发就像建造大楼,地基(项目结构)要牢固,管线(配置集成)要规范,每个模块(功能实现)都要精心设计。明天继续完善这座"大楼"!

如果遇到任何问题,欢迎在评论区交流讨论。完整代码已上传GitHub,需要的朋友可以私信获取!


文章转载自:

http://RL6DLHkQ.cwjsz.cn
http://ZRD22d8I.cwjsz.cn
http://Ucz4azoX.cwjsz.cn
http://nB8UfSG2.cwjsz.cn
http://Sf6sdACB.cwjsz.cn
http://TmDcOqTA.cwjsz.cn
http://L9iXQOBW.cwjsz.cn
http://bybePH3F.cwjsz.cn
http://T1odIwyC.cwjsz.cn
http://dWucitvp.cwjsz.cn
http://npdLTuYt.cwjsz.cn
http://TD1YMlOg.cwjsz.cn
http://EJA2r5bC.cwjsz.cn
http://dM8K4Tk2.cwjsz.cn
http://GvOxPOJ9.cwjsz.cn
http://G9GQ09wO.cwjsz.cn
http://bg6SuXQR.cwjsz.cn
http://eYzSeaCP.cwjsz.cn
http://eXTUySKA.cwjsz.cn
http://dUkobfbM.cwjsz.cn
http://n5ZS3qFO.cwjsz.cn
http://MQ0D6Smx.cwjsz.cn
http://XNb2wEnp.cwjsz.cn
http://9oaEGqa6.cwjsz.cn
http://QUTfEOCH.cwjsz.cn
http://1lVWXw5q.cwjsz.cn
http://bNg8E9Mv.cwjsz.cn
http://lVzeWlvd.cwjsz.cn
http://m8EsUeu1.cwjsz.cn
http://FvRizROG.cwjsz.cn
http://www.dtcms.com/a/373642.html

相关文章:

  • 嵌入式学习---(硬件)
  • 写算法第二题(英语介词)dom对象
  • cn2an:中文数字与阿拉伯数字的智能转换工具
  • Hive和Flink数据倾斜问题
  • 嵌入式ARM架构学习2——汇编
  • 渗透测试全景解析:从基础概念到实战演练
  • 鸿蒙Next应用UI稳定性故障调试:从崩溃到流畅的实战指南
  • 企智汇施工工程项目管理系统:全生命周期信息化管理解决方案!施工企业管理系统!施工企业项目管理软件!工程项目管理系统!工程项目管理软件!
  • 遥感数据同化方法:集合卡尔曼滤波和变分同化算法
  • mac安装Java开发环境
  • Java网络初识(2):IP地址和端口号,协议,五元组
  • 什么是算法:高效解决问题的逻辑框架
  • EFCore与EF6:ORM技术深度解析
  • 【开题答辩全过程】以 线上“三味书屋”学习平台设计与实现为例,包含答辩的问题和答案
  • iframe引入界面有el-date-picker日期框,点击出现闪退问题处理
  • BP-Adaboost模型
  • 使用redis的发布/订阅(Pub/Sub), 实现消息队列
  • 鸿蒙:更改状态栏、导航栏颜色
  • [数据结构——lesson4.双向链表]
  • 集成学习:从理论到实践的全面解析
  • 机器学习-集成学习
  • 集成学习简介
  • JDK 17、OpenJDK 17、Oracle JDK 17 的说明
  • VM中CentOS 7密码重置
  • 科技信息差(9.8)
  • MATLAB的数值计算(三)曲线拟合与插值
  • 城市脉搏中的“绿色卫士”:当智能科技邂逅城市清洁
  • linux播放视频出现需要MPEG-4 AAC解码器,H.265(Main Profile)解码器,但是没有安装
  • ARM工作模式、汇编学习
  • 【入门级-算法-6、排序算法:选择排序】