导读:本期聚焦于小伙伴创作的《Java怎么实现一个简易博客系统的文章发布与评论模块结构?》,敬请观看详情。一个博客系统最核心的能力莫过于写文章和互动评论。不少初学者在动手时用Servlet硬写,结果请求分发混乱、数据层耦合严重。本文基于Spring Boot梳理文章发布与评论模块的分层结构:Controller接收参数做校验,Service封装业务逻辑,Repository持久化到MySQL。文章表与评论表通过外键关联,发布接口用@RequestBody接收JSON,评论接口限制必须携带合法文章ID。这样拆开后,后续接入Redis缓存热点文章或做敏感词过滤都更容易,也比把所有逻辑堆在JSP里好维护得多。

用Java搭建一个简易博客系统,重点在于把文章发布与评论这两块业务逻辑拆清楚。很多刚接触Web开发的人容易把接收请求、处理数据和存库都写在一个类里,导致代码越改越乱。下面我们从分层结构讲起,逐步给出一个可运行的实现思路。

Java怎么实现一个简易博客系统的文章发布与评论模块结构?

一、整体模块分层设计

简易博客系统通常采用经典的三层架构:控制层、业务层、持久层。控制层用Spring MVC的Controller接收前端请求,只负责参数校验和返回结果;业务层Service写真正的发布文章、添加评论规则;持久层用JPA或者MyBatis把对象存进MySQL。

这样的好处是文章模块和评论模块各自独立。比如文章表article存标题和内容,评论表comment存内容和关联的文章ID。两者通过外键约束保证评论一定挂在存在的文章下,避免脏数据。

1.1 数据表结构示例

先定义两张表,字段尽量简单但能表达关系。article表用自增主键,comment表用article_id做外键。

CREATE TABLE article (
  id BIGINT AUTO_INCREMENT PRIMARY KEY,
  title VARCHAR(200) NOT NULL,
  content TEXT NOT NULL,
  create_time DATETIME DEFAULT CURRENT_TIMESTAMP
);

CREATE TABLE comment (
  id BIGINT AUTO_INCREMENT PRIMARY KEY,
  article_id BIGINT NOT NULL,
  content VARCHAR(500) NOT NULL,
  create_time DATETIME DEFAULT CURRENT_TIMESTAMP,
  FOREIGN KEY (article_id) REFERENCES article(id)
);

1.2 实体类映射

在Java里用实体类对应表结构。下面以JPA注解方式写两个类,关系字段用@ManyToOne标注,方便后续查询某篇文章的全部评论。

@Entity
@Table(name = "article")
public class Article {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;
    private String title;
    private String content;
    private LocalDateTime createTime;
    // getter和setter省略
}

@Entity
@Table(name = "comment")
public class Comment {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;
    @ManyToOne
    @JoinColumn(name = "article_id")
    private Article article;
    private String content;
    private LocalDateTime createTime;
    // getter和setter省略
}

二、文章发布模块实现

文章发布接口要做的事不多:拿到标题和内容,判空,然后存库。Controller层用@PostMapping接收JSON,Service层调用Repository的save方法。这里注意标题不能超长,内容不能为空,否则直接返回错误码。

如果直接在Controller里写保存逻辑,以后要加“发布时自动提取摘要”就得分散改代码。放到Service里,只改一个方法即可,符合单一职责原则。

2.1 Controller接收发布请求

以下代码展示如何用Spring Boot接收文章发布请求。使用@RequestBody把前端JSON转成对象,用BindingResult做基础校验。

@RestController
@RequestMapping("/api/article")
public class ArticleController {

    @Autowired
    private ArticleService articleService;

    @PostMapping("/publish")
    public Map<String, Object> publish(@RequestBody Article article, BindingResult result) {
        Map<String, Object> resp = new HashMap<>();
        if (result.hasErrors() || article.getTitle() == null || article.getContent() == null) {
            resp.put("code", 400);
            resp.put("msg", "标题或内容不能为空");
            return resp;
        }
        articleService.publish(article);
        resp.put("code", 200);
        resp.put("msg", "发布成功");
        return resp;
    }
}

2.2 Service与Repository

Service注入JpaRepository,发布方法仅仅是保存并打日志。实际项目可在这里接入搜索引擎或清理缓存。

@Service
public class ArticleService {

    @Autowired
    private ArticleRepository articleRepository;

    public void publish(Article article) {
        article.setCreateTime(LocalDateTime.now());
        articleRepository.save(article);
    }
}

public interface ArticleRepository extends JpaRepository<Article, Long> {
}

三、评论模块结构

评论模块必须绑定文章。常见错误是前端传了不存在的articleId,后端没校验就插入,导致评论找不到归属。正确做法是在Service里先查文章存不存在,再存评论。

另外评论内容要做长度限制和简单敏感词拦截,虽然简易系统不一定接第三方,但至少防一下空评论和超长文本,减轻数据库压力。

3.1 添加评论接口

Controller接收articleId和content,转给Service处理。下面代码演示参数用表单格式提交,也可以改成JSON。

@RestController
@RequestMapping("/api/comment")
public class CommentController {

    @Autowired
    private CommentService commentService;

    @PostMapping("/add")
    public Map<String, Object> addComment(@RequestParam Long articleId, @RequestParam String content) {
        Map<String, Object> resp = new HashMap<>();
        boolean ok = commentService.addComment(articleId, content);
        if (ok) {
            resp.put("code", 200);
            resp.put("msg", "评论成功");
        } else {
            resp.put("code", 404);
            resp.put("msg", "文章不存在或内容非法");
        }
        return resp;
    }
}

3.2 评论业务校验

Service先查文章,再构建Comment对象。这里用Optional避免空指针,是Java 8之后的推荐写法。

@Service
public class CommentService {

    @Autowired
    private ArticleRepository articleRepository;
    @Autowired
    private CommentRepository commentRepository;

    public boolean addComment(Long articleId, String content) {
        if (content == null || content.trim().length() == 0 || content.length() > 500) {
            return false;
        }
        Optional<Article> opt = articleRepository.findById(articleId);
        if (!opt.isPresent()) {
            return false;
        }
        Comment c = new Comment();
        c.setArticle(opt.get());
        c.setContent(content);
        c.setCreateTime(LocalDateTime.now());
        commentRepository.save(c);
        return true;
    }
}

四、模块联调与扩展思考

文章和评论分开写完后,可以用Postman先发一篇文章,拿到返回的文章ID,再带着这个ID发评论。只要外键和校验生效,数据层就不会乱。

如果以后想显示某篇文章和全部评论,可以在ArticleRepository里写@Query查评论列表,或者前端分两次请求。这种结构下,接Redis缓存热门文章、接消息队列异步审核评论都不会动到原有发布逻辑,维护成本明显更低。

4.1 查询文章评论示例

给CommentRepository加一个按文章ID查的方法,Spring会自动生成SQL。

public interface CommentRepository extends JpaRepository<Comment, Long> {
    List<Comment> findByArticleId(Long articleId);
}

通过上述结构,一个简易博客系统的文章发布与评论模块就具备了清晰边界。即便后续加入用户系统和权限控制,也只需在Controller入口加拦截器,不影响已经写好的核心逻辑。

Java博客系统Spring_Boot修改时间:2026-08-10 07:48:33

免责声明:​ 已尽一切努力确保本网站所含信息的准确性。网站内容多为原创整理与精心编撰,观点力求客观中立。本站旨在免费分享,内容仅供个人学习、研究或参考使用。若引用了第三方作品,版权归原作者所有。如内容涉及您的权益,请联系我们处理。
内容垂直聚焦
专注技术核心技术栏目,确保每篇文章深度聚焦于实用技能。从代码技巧到架构设计,为用户提供无干扰的纯技术知识沉淀,精准满足专业提升需求。
知识结构清晰
覆盖从开发到部署的全链路。AI、前端、编程、数据库、服务器、建站、系统层层递进,构建清晰学习路径,帮助用户系统化掌握开发与运维所需的核心技术。
深度技术解析
拒绝泛泛而谈,深入技术细节与实践难点。无论是数据库优化还是服务器配置,均结合真实场景与代码示例进行剖析,致力于提供可直接应用于工作的解决方案。
专业领域覆盖
精准对应开发生命周期。从前端界面到后端编程,从数据库操作到服务器运维,形成完整闭环,一站式满足全栈工程师和运维人员的技术需求。
即学即用高效
内容强调实操性,步骤清晰、代码完整。用户可根据教程直接复现和应用于自身项目,显著缩短从学习到实践的距离,快速解决开发中的具体问题。
持续更新保障
专注既定技术方向进行长期、稳定的内容输出。确保各栏目技术文章持续更新迭代,紧跟主流技术发展趋势,为用户提供经久不衰的学习价值。