项目名称:个人博客系统
需求分析
我们要明确这个博客系统需要实现哪些核心功能。

-
用户模块:
- 注册: 用户可以注册一个新账号。
- 登录: 已注册用户可以使用用户名和密码登录。
- 登出: 用户可以退出登录。
- 个人中心: 登录后可以查看和修改个人信息(如用户名、邮箱、密码)。
- 权限控制: 只有登录用户才能发表、编辑、删除自己的文章。
-
文章模块:
- 文章列表: 在首页展示所有已发布的文章,按发布时间倒序排列。
- 文章详情: 点击文章标题或摘要,可以跳转到文章详情页面。
- 发表文章: 登录用户可以发表新文章,包括标题、内容摘要和正文。
- 编辑文章: 文章作者可以编辑自己已发布的文章。
- 删除文章: 文章作者可以删除自己已发布的文章。
-
评论模块:
- 发表评论: 所有访客(登录后)都可以在文章下方发表评论。
- 评论列表: 在文章详情页展示该文章的所有评论。
技术选型
选择合适的技术栈是项目成功的关键,对于这个项目,我们选择目前主流且成熟的技术组合。

-
后端:
- 框架: Spring Boot 3.x - 简化 Spring 应用的初始搭建和开发过程,无需大量 XML 配置。
- 持久层: MyBatis-Plus - MyBatis 的增强工具,极大简化了 CRUD 操作,代码更简洁。
- 数据库: MySQL 8.0 - 最流行的开源关系型数据库,适合存储结构化数据。
- 模板引擎: Thymeleaf - 用于在服务器端渲染 HTML,可以很好地与 Spring Boot 集成,实现前后端不分离的开发模式。
- 安全框架: Spring Security - 用于处理用户认证(登录)和授权(权限控制)。
- 构建工具: Maven - 项目管理和构建自动化。
- 服务器: Tomcat (内嵌) - Spring Boot 默认内嵌 Tomcat 服务器。
-
前端:
- 核心: HTML5, CSS3, JavaScript (ES6)
- UI 框架: Bootstrap 5 - 提供了一套美观且响应式的 UI 组件,可以快速构建出专业的界面。
- JavaScript 库: jQuery - 简化 DOM 操作和 AJAX 请求。
项目结构
一个标准的 Maven Web 项目结构如下:
blog-system/
├── src/
│ ├── main/
│ │ ├── java/
│ │ │ └── com/
│ │ │ └── example/
│ │ │ └── blog/
│ │ │ ├── config/ // Spring Security 配置
│ │ │ ├── controller/ // 控制器,处理 HTTP 请求
│ │ │ ├── entity/ // 实体类,与数据库表对应
│ │ │ ├── mapper/ // MyBatis-Plus 的 Mapper 接口
│ │ │ ├── service/ // 业务逻辑层接口
│ │ │ │ └── impl/ // 业务逻辑层实现
│ │ │ └── BlogApplication.java // 应用程序入口
│ │ ├── resources/
│ │ │ ├── static/ // 存放静态资源 (CSS, JS, 图片)
│ │ │ ├── templates/ // 存放 Thymeleaf 模板文件
│ │ │ │ ├── index.html
│ │ │ │ ├── login.html
│ │ │ │ ├── register.html
│ │ │ │ ├── post/ // 文章相关页面
│ │ │ │ └── user/ // 用户相关页面
│ │ │ ├── application.yml // Spring Boot 配置文件
│ │ │ └── mapper/ // MyBatis-Plus 的 XML 映射文件 (可选,推荐注解)
│ │ └── webapp/
│ └── test/
├── pom.xml
数据库设计
根据需求,我们设计以下几张表:
t_user (用户表)
| 字段名 | 类型 | 约束 | 描述 |
| :--- | :--- | :--- | :--- |
| id | bigint | PK, AI | 用户 ID |
| username | varchar(50) | UNIQUE, NOT NULL | 用户名 |
| password | varchar(100) | NOT NULL | 密码 (加密存储) |
| email | varchar(100) | UNIQUE | 邮箱 |
| nickname | varchar(50) | | 昵称 |
| avatar | varchar(255) | | 头像 URL |
| create_time | datetime | | 创建时间 |
t_post (文章表)
| 字段名 | 类型 | 约束 | 描述 |
| :--- | :--- | :--- | :--- |
| id | bigint | PK, AI | 文章 ID | | varchar(100) | NOT NULL | 文章标题 |
| summary | varchar(255) | | |
| content | longtext | NOT NULL | 文章内容 |
| user_id | bigint | FK (t_user.id) | 作者 ID |
| create_time | datetime | | 创建时间 |
| update_time | datetime | | 更新时间 |
t_comment (评论表)
| 字段名 | 类型 | 约束 | 描述 |
| :--- | :--- | :--- | :--- |
| id | bigint | PK, AI | 评论 ID |
| content | text | NOT NULL | 评论内容 |
| post_id | bigint | FK (t_post.id) | 所属文章 ID |
| user_id | bigint | FK (t_user.id) | 评论者 ID |
| create_time | datetime | | 创建时间 |
开发步骤详解
步骤 1:项目初始化
- 使用 Spring Initializr (start.spring.io) 快速创建项目。
- Project: Maven
- Language: Java
- Spring Boot: 选择一个稳定版本 (如 3.2.x)
- Project Metadata:
- Group:
com.example - Artifact:
blog - Name:
blog - Packaging: Jar
- Java: 17 或更高版本
- Group:
- Dependencies:
- Spring Web: 用于构建 Web 应用。
- Thymeleaf: 用于模板引擎。
- MySQL Driver: 连接 MySQL 数据库。
- MyBatis-Plus: ORM 框架。
- Spring Security: 安全框架。
- 下载项目并导入你的 IDE (如 IntelliJ IDEA)。
步骤 2:配置项目
pom.xml 已经包含了所需依赖,接下来配置 application.yml:
# src/main/resources/application.yml
server:
port: 8080
spring:
datasource:
driver-class-name: com.mysql.cj.jdbc.Driver
url: jdbc:mysql://localhost:3306/blog_db?useSSL=false&serverTimezone=UTC&characterEncoding=UTF-8
username: root
password: your_password
thymeleaf:
cache: false # 开发时关闭缓存,方便实时查看修改
mybatis-plus:
configuration:
log-impl: org.apache.ibatis.logging.stdout.StdOutImpl # 打印 SQL 日志,方便调试
global-config:
db-config:
logic-delete-field: deleted # 逻辑删除字段名
logic-delete-value: 1 # 逻辑删除值
logic-not-delete-value: 0 # 逻辑未删除值
步骤 3:创建实体类
在 entity 包下创建与数据库表对应的 Java 类。
User.java
// Lombok 注解简化 getter/setter
@Data
public class User {
private Long id;
private String username;
private String password;
private String email;
private String nickname;
private String avatar;
private Date createTime;
}
Post.java
@Data
public class Post {
private Long id;
private String title;
private String summary;
private String content;
private Long userId;
private Date createTime;
private Date updateTime;
}
Comment.java
@Data
public class Comment {
private Long id;
private String content;
private Long postId;
private Long userId;
private Date createTime;
}
步骤 4:创建 Mapper 接口
使用 MyBatis-Plus 的 BaseMapper 可以直接获得 CRUD 能力。
UserMapper.java
@Mapper
public interface UserMapper extends BaseMapper<User> {
}
PostMapper 和 CommentMapper 同理。
步骤 5:创建 Service 层
UserService.java (接口)
public interface UserService extends IService<User> {
User findByUsername(String username);
}
UserServiceImpl.java (实现)
@Service
@RequiredArgsConstructor // Lombok 注解,自动生成 final 字段的构造器注入
public class UserServiceImpl extends ServiceImpl<UserMapper, User> implements UserService {
@Override
public User findByUsername(String username) {
return lambdaQuery().eq(User::getUsername, username).one();
}
}
PostService 和 CommentService 也类似,可以添加自定义的业务方法,如 addPost, getPostsByUserId 等。
步骤 6:创建 Controller 层
这是项目的核心,负责接收请求、调用 Service、返回视图或数据。
HomeController.java (处理首页、文章列表)
@Controller
public class HomeController {
@Autowired
private PostService postService;
@GetMapping("/")
public String index(Model model) {
// 获取最新的文章列表
List<Post> posts = postService.list();
model.addAttribute("posts", posts);
return "index"; // 返回 templates/index.html
}
}
PostController.java (处理文章详情、发表等)
@Controller
@RequestMapping("/post")
public class PostController {
@Autowired
private PostService postService;
// 文章详情页
@GetMapping("/{id}")
public String detail(@PathVariable("id") Long id, Model model) {
Post post = postService.getById(id);
model.addAttribute("post", post);
// TODO: 获取该文章的评论列表并放入 model
return "post/detail";
}
// 跳转到发表文章页
@GetMapping("/add")
public String add() {
return "post/add";
}
// 处理发表文章的表单提交
@PostMapping("/add")
public String addPost(Post post) {
// TODO: 获取当前登录用户 ID 并设置到 post 中
postService.save(post);
return "redirect:/"; // 发表成功后重定向到首页
}
}
步骤 7:前端页面开发
使用 Thymeleaf 和 Bootstrap 来构建页面,Thymeleaf 通过 th: 属性来动态绑定数据。
templates/index.html (首页)
<!DOCTYPE html>
<html lang="zh" xmlns:th="http://www.thymeleaf.org">
<head>
<meta charset="UTF-8">我的博客 - 首页</title>
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0/dist/css/bootstrap.min.css" rel="stylesheet">
</head>
<body>
<nav class="navbar navbar-expand-lg navbar-dark bg-dark">
<div class="container">
<a class="navbar-brand" href="/">我的博客</a>
<!-- ... 导航栏其他部分 ... -->
</div>
</nav>
<div class="container mt-4">
<div class="row">
<div class="col-md-8">
<h2>最新文章</h2>
<div class="list-group">
<a th:each="post : ${posts}" th:href="@{'/post/' + post.id}" class="list-group-item list-group-item-action">
<h5 class="mb-1" th:text="${post.title}">文章标题</h5>
<p class="mb-1" th:text="${post.summary}">..</p>
<small class="text-muted" th:text="'发布于 ' + #dates.format(post.createTime, 'yyyy-MM-dd HH:mm')"></small>
</a>
</div>
</div>
<div class="col-md-4">
<!-- 侧边栏,可以放登录框等 -->
</div>
</div>
</div>
</body>
</html>
其他页面如 login.html, register.html, post/detail.html 等也按照类似方式开发,使用 Thymeleaf 动态填充内容。
步骤 8:集成 Spring Security
这是实现登录、注册和权限控制的关键。
-
创建
UserDetails实现:@Data @AllArgsConstructor public class UserDetailsImpl implements UserDetails { private User user; // 我们的实体类 @Override public Collection<? extends GrantedAuthority> getAuthorities() { return AuthorityUtils.createAuthorityList("ROLE_USER"); // 给用户一个 USER 角色 } @Override public String getPassword() { return user.getPassword(); } @Override public String getUsername() { return user.getUsername(); } // ... 其他方法如 isAccountNonExpired() 等直接返回 true ... } -
创建
UserDetailsService实现:@Service @RequiredArgsConstructor public class UserDetailsServiceImpl implements UserDetailsService { private final UserService userService; @Override public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException { User user = userService.findByUsername(username); if (user == null) { throw new UsernameNotFoundException("用户不存在"); } return new UserDetailsImpl(user); } } -
创建安全配置类:
@Configuration @RequiredArgsConstructor public class SecurityConfig { private final UserDetailsService userDetailsService; @Bean public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception { http .authorizeHttpRequests(auth -> auth .requestMatchers("/login", "/register", "/css/**", "/js/**").permitAll() // 允许匿名访问的路径 .anyRequest().authenticated() // 其他所有请求都需要认证 ) .formLogin(form -> form .loginPage("/login") // 自定义登录页 .defaultSuccessUrl("/") // 登录成功后跳转的页面 .permitAll() ) .logout(logout -> logout .logoutSuccessUrl("/login") // 登出后跳转的页面 .permitAll() ) .csrf(AbstractHttpConfigurer::disable); // 在非 RESTful 应用中可以暂时禁用 CSRF return http.build(); } @Bean public PasswordEncoder passwordEncoder() { return new BCryptPasswordEncoder(); // 使用 BCrypt 加密密码 } } -
修改
UserService的注册方法: 在UserServiceImpl中添加一个注册方法,使用PasswordEncoder对密码进行加密后再保存。
步骤 9:测试与部署
- 单元测试: 使用 JUnit 为 Service 层的方法编写测试用例。
- 集成测试: 启动整个应用,手动或使用 Postman 等工具测试各个接口和页面功能。
- 打包部署:
- 在
pom.xml中添加 Spring Boot Maven 插件(通常已包含)。 - 执行
mvn clean package命令,会生成一个.jar文件。 - 将此
.jar文件复制到服务器上。 - 确保服务器上安装了 Java 运行环境。
- 执行命令
java -jar blog.jar启动应用。 - 访问
http://your_server_ip:8080即可看到你的博客。
- 在
总结与展望
这个案例为你构建了一个功能完整的 Java Web 项目,它涵盖了:
- MVC 架构模式 的清晰应用。
- Spring Boot 的自动配置和快速开发。
- MyBatis-Plus 的便捷数据访问。
- Thymeleaf 的服务器端页面渲染。
- Spring Security 的核心认证授权流程。
未来可以扩展的方向:
- 前后端分离: 将后端改造为纯 RESTful API,前端使用 Vue.js 或 React 等框架开发。
- 功能增强: 添加文章分类、标签、全文搜索 (Elasticsearch)、文件上传等功能。
- 性能优化: 引入缓存 (Redis)、数据库分库分表等。
- 容器化部署: 使用 Docker 将应用打包成镜像,使用 Kubernetes 进行编排管理。
通过这个案例,你可以将零散的 Java Web 知识点融会贯通,真正理解一个项目是如何从零开始被构建出来的,祝你开发顺利!
