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
相关产品推荐
相关产品推荐

