You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Spring Boot中如何将URL中的postId替换为文章别名

实现Spring Boot中通过文章别名替代PostId访问文章的方案

整体思路

把URL里的postId替换成文章别名(slug),需要从数据库存储、实体类映射、查询逻辑、页面链接这几个环节逐一调整。

具体步骤

1. 数据库新增文章别名字段

给存储文章的post表加一个slug字段,用来存唯一的文章别名,必须保证唯一性:

ALTER TABLE post 
ADD COLUMN slug VARCHAR(255) UNIQUE NOT NULL COMMENT '文章别名,唯一标识';

注意:如果已有存量文章,先给这些文章批量生成符合规则的唯一slug(比如标题转小写+空格替换成-),再添加非空约束。

2. 修改Post实体类

在Post类中新增slug属性,加上JPA注解和对应的getter/setter:

import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;

@Entity
public class Post {
    // 原有属性
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private int postId;
    
    private String title;
    private String contents;
    // 其他原有属性...

    // 新增slug属性
    @Column(unique = true, nullable = false)
    private String slug;

    // getter和setter
    public String getSlug() {
        return slug;
    }

    public void setSlug(String slug) {
        this.slug = slug;
    }

    // 原有属性的getter/setter...
}

3. 更新Service层查询逻辑

在PostServices里新增通过分类名和slug查询文章的方法:

@Service
public class PostServices {
    // 原有方法...

    public Optional<Post> getPostByCategoryNameAndSlug(String catName, String slug) {
        // 先通过分类名找到对应分类
        Category category = categoryServices.getCategoryByName(catName);
        if (category == null) {
            return Optional.empty();
        }
        // 根据分类和slug查询文章
        return postRepository.findByCategoryAndSlug(category, slug);
    }
}

对应的PostRepository要新增查询方法:

public interface PostRepository extends JpaRepository<Post, Integer> {
    Optional<Post> findByCategoryAndSlug(Category category, String slug);
}

4. 修改Controller映射

替换原来的{catName}/{postId}映射,新增{catName}/{slug}的请求处理:

@GetMapping("{catName}/{slug}")
public String showPostByCategoryAndSlug(@PathVariable("catName") String catName, 
                                        @PathVariable("slug") String slug, 
                                        Model model) {
    Optional<Post> post = postServices.getPostByCategoryNameAndSlug(catName, slug);
    Category category = categoryServices.getCategoryByName(catName);

    if (post.isPresent()) {
        model.addAttribute("content", post.get().getContents());
        model.addAttribute("title", post.get().getTitle());
        model.addAttribute("updateDate", post.get().getUpdatedAt());
        model.addAttribute("category", category.getCatName());
        model.addAttribute("postByCategoryAndPostId", category.getPostId());
    } else {
        model.addAttribute("postNotFoundByCategory", "该分类下无对应文章");
    }

    return "content/home";
}

可以保留原来的{catName}/{postId}映射做兼容,也直接替换,根据需求选择。

5. 修改JSP页面链接

把原来链接里的postId替换成slug:

<c:forEach items="${ postByCategoryAndPostId}" var="menus">
    <a href="<%=request.getContextPath()%>/${category}/${menus.slug}" class="list-group-item list-group-item-action bg-light">${menus.title} </a>
</c:forEach>

额外注意事项

  • Slug生成规则:建议在文章创建时自动生成slug,比如标题转小写、空格替换为-、去除特殊字符,若出现重复则追加数字(如what-is-java重复时改为what-is-java-1)。
  • 唯一性校验:确保数据库的唯一约束生效,避免相同slug导致的异常。
  • 存量数据处理:如果是已上线项目,要给现有文章批量生成符合规则的唯一slug,保证旧链接能正常跳转。

内容的提问来源于stack exchange,提问作者harendrakumar rajpoot

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.02 00:50:27