Spring中@GetMapping与@PostMapping对应URL无法找到的问题排查
问题:访问新建文章页面出现404错误
我正在开发一个博客应用,想要实现新建文章功能。已经在控制器中创建了映射路径为/posts/new的@GetMapping和@PostMapping注解方法,Thymeleaf表单里也使用了th:action = "@{'/posts/new'}",但启动应用后访问localhost:8080/posts/new时出现404错误,提示URL未找到。检查过拼写和代码后仍未找到问题,相关代码如下:
post_new.html
<!DOCTYPE html> <html lang="en" xmlns:th="http://www.thymeleaf.org"> <head> <meta charset="utf-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta name="viewport" content="width=device-width, initial-scale=1"> <title>Blog :: New Post</title> </head> <body> <div class="container"> <a th:href="@{/}">Home</a> <form action="#" th:action="@{'/posts/new'}" th:object="${post}"> <input type="hidden" th:field="*{account}" /> <input type="hidden" th:field="*{createdAt}" /> <h2>Write new post</h2> <div> <label for="new-post-title">Title</label> <input id="new-post-title" type="text" th:field="*{title}" placeholder="Title"/> </div> <div> <label for="new-post-body">Body</label> <textarea id="new-post-body" th:field="*{body}"></textarea> </div> <button type="submit">Publish post</button> </form> </div> </body> </html>
PostController.java
package com.hellion.writeup.controller; import com.hellion.writeup.models.Account; import com.hellion.writeup.models.Post; import com.hellion.writeup.service.AccountService; import com.hellion.writeup.service.PostService; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Controller; import org.springframework.ui.Model; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.ModelAttribute; import org.springframework.web.bind.annotation.PathVariable; import org.springframework.web.bind.annotation.PostMapping; import java.util.Optional; @Controller public class PostController { @Autowired private PostService postService; @Autowired private AccountService accountService; @GetMapping("/posts/{id}") public String getPost(@PathVariable Long id, Model model) { Post post = postService.getPost(id, model); if (post != null) { model.addAttribute("post", post); return "post"; } else { return "404"; } } @GetMapping("/posts/new") public String createNewPost(Model model){ return postService.createNewPost(model); } @PostMapping("/posts/new") public String saveNewPost(@ModelAttribute Post post){ postService.save(post); return "redirect:/posts/" + post.getId(); } }
PostService.java
package com.hellion.writeup.service; import com.hellion.writeup.models.Account; import com.hellion.writeup.models.Post; import com.hellion.writeup.repository.PostRepository; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import org.springframework.ui.Model; import java.time.LocalDateTime; import java.util.List; import java.util.Optional; @Service public class PostService { @Autowired private PostRepository postRepository; @Autowired private AccountService accountService;; public Optional<Post> getById(Long id) { return postRepository.findById(id); } public List<Post> getAll() { return postRepository.findAll(); } public Post save(Post post) { if (post.getId() == null) { post.setCreatedAt(LocalDateTime.now()); } return postRepository.save(post); } public Post getPost(Long id, Model model) { Optional<Post> optionalPost = getById(id); if (optionalPost.isPresent()) { Post post = optionalPost.get(); return post; } return null; } public String createNewPost(Model model){ Optional<Account> optionalAccount = accountService.findByEmail("user.user@domain.com"); if(optionalAccount.isPresent()){ Post post = new Post(); post.setAccount(optionalAccount.get()); model.addAttribute("post", post); return "post_new"; }else{ return "404"; } } }
post.html
<!DOCTYPE HTML> <html land= "en" xmlns:th="http://www.thymeleaf.org"> <head> <meta charset="utf-8"> <meta http-equiv="X-UA-Compatible" content="IE-edge"> <meta name="viewport" content="width=device-width, initial-scale=1"> <link th:href="@{/styles/style.css}" rel="stylesheet" /> <title>Writeup :: Post</title> </head> <body> <div class ="container"> <a th:href="@{'/'}">Home</a> <div class="post"> <h2 th:text="${post.title}">Title</h2> <h5 th:text="'Written by: ' + ${post.account.getFirstName()}">Account First Name</h5> <h5 th:text="'Created on: ' + ${post.createdAt}">Created At</h5> <p th:text="${post.body}">Body text</p> </div> </div> </body> </html>
排查与解决建议
检查模板文件路径
确认post_new.html是否放在Spring Boot默认的模板目录src/main/resources/templates下,路径错误会导致Thymeleaf无法找到模板,间接引发404。排查账号查询逻辑
PostService.createNewPost方法中,若accountService.findByEmail("user.user@domain.com")查询不到账号,会直接返回"404",此时控制器虽命中但返回404页面。可以临时注释账号判断逻辑,直接返回post_new模板,测试页面是否能正常访问:public String createNewPost(Model model){ // 临时注释账号查询逻辑 // Optional<Account> optionalAccount = accountService.findByEmail("user.user@domain.com"); // if(optionalAccount.isPresent()){ Post post = new Post(); // post.setAccount(optionalAccount.get()); model.addAttribute("post", post); return "post_new"; // }else{ // return "404"; // } }确认控制器扫描范围
检查Spring Boot主启动类所在包是否包含com.hellion.writeup.controller,若主启动类在其他包下,需添加@ComponentScan指定扫描路径。简化Thymeleaf表单路径写法
表单的th:action可简化为th:action="@{/posts/new}",无需额外单引号包裹,避免路径解析异常。
内容的提问来源于stack exchange,提问作者user13372981
相关产品推荐
相关产品推荐

