Java初学者项目实战:构建一个简单的论坛系统

初学者应以Spring Boot+Thymeleaf+JDBC实现发帖、列表、详情三核心功能:建users/posts表,用JdbcTemplate手写SQL,Controller返回模板名,Thymeleaf仅用th:each/th:href/th:text基础语法,严格匹配命名。

直接上手写一个“完整论坛系统”对 Java 初学者不现实,真正可行的路径是:用最简技术栈实现核心交互闭环——用户发帖、查看帖子列表、点击进入详情页。其余功能(登录、权限、回复、搜索)先搁置,否则三天内必然卡死在 Spring Security 配置或 MyBatis 多表关联上。

用 Spring Boot + Thymeleaf 快速跑通 MVC 流程

别碰前后端分离。初学者强行接 axiosVue,90% 的时间花在跨域、CORS404 路由和浏览器控制台红字上,跟业务逻辑无关。Thymeleaf 模板渲染能让你一眼看到“请求 → Controller → Model → HTML”的完整链条。

  • spring-boot-starter-web + spring-boot-starter-thymeleaf + spring-boot-starter-jdbc(先不用 JPA,避免被 @EntityHibernate 的代理对象绕晕)
  • application.properties 里只配数据库 URL、用户名、密码,其他全删掉,不加 spring.jpa.hibernate.ddl-auto 自动建表——手写 CREATE TABLE 更清醒
  • Controller 方法返回字符串(如 "post/list"),对应 src/main/resources/templates/post/list.html,不返回 ResponseEntity 或 JSON

数据库只建两张表:users 和 posts

别设计 categoriestagsreplies 表。一张 posts 表含 idtitlecontentuser_idcreated_at 就够。外键先不设约束,用注释说明“此处应为 users.

id”,避免 SQLIntegrityConstraintViolationException 让人懵圈。

CREATE TABLE users (
  id BIGINT PRIMARY KEY AUTO_INCREMENT,
  username VARCHAR(50) NOT NULL
);

CREATE TABLE posts (
  id BIGINT PRIMARY KEY AUTO_INCREMENT,
  title VARCHAR(100) NOT NULL,
  content TEXT,
  user_id BIGINT NOT NULL,
  created_at DATETIME DEFAULT CURRENT_TIMESTAMP
);
  • 插入测试数据用 INSERT INTO users (username) VALUES ('alice'), ('bob');,手动填 user_id 值,不依赖序列或触发器
  • DAO 层用 JdbcTemplate 直接写 SQL 查询,比如 query("SELECT p.*, u.username FROM posts p JOIN users u ON p.user_id = u.id", ...),不抽象 PostMapper 接口
  • 查列表时用 queryForList(),查单条用 queryForObject(),别碰 RowMapper 泛型——类型擦除会让初学者怀疑 Java 是不是坏了

Thymeleaf 模板里只用最基础语法

别写 th:fragmentth:replaceth:with。一个页面一个文件,重复代码先复制粘贴,等跑通再抽离。重点盯住三处:

  • th:each="post : ${posts}" —— 确保后端 Model.addAttribute("posts", list) 的 key 名和模板里一致
  • th:href="@{/post/{id}(id=${post.id})}" —— 注意括号位置,写成 @{/post/${post.id}} 会生成错误 URL
  • th:text="${post.title}" —— 不要漏掉 ${},写成 th:text="post.title" 页面就显示字面量 “post.title”
  
  

启动报错优先查这三处

90% 的初学者卡在启动失败,不是框架问题,是配置或路径笔误:

  • Whitelabel Error Page:检查 Controller 方法是否真返回了模板名字符串,且对应 HTML 文件在 templates/ 下存在;确认类上有 @Controller(不是 @RestController
  • Failed to configure a DataSource:检查 application.properties 是否拼错 spring.datasource.url,MySQL 8+ 必须加 ?serverTimezone=UTC
  • 页面显示空白但无报错:打开浏览器开发者工具 → Network 标签页,看 GET /post/list 返回的是 200 还是 404;若 404,确认 Controller 的 @GetMapping("/post/list") 路径和浏览器地址栏完全一致(注意斜杠)

复杂点在于:所有环节都依赖“命名严格匹配”——Java 类名、方法名、模板文件路径、HTML 中的变量名、数据库字段名,差一个字母就断链。这不是设计缺陷,是初学阶段必须亲手踩过的验证过程。