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

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>

排查与解决建议

  1. 检查模板文件路径
    确认post_new.html是否放在Spring Boot默认的模板目录src/main/resources/templates下,路径错误会导致Thymeleaf无法找到模板,间接引发404。

  2. 排查账号查询逻辑
    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";
        // }
    }
    
  3. 确认控制器扫描范围
    检查Spring Boot主启动类所在包是否包含com.hellion.writeup.controller,若主启动类在其他包下,需添加@ComponentScan指定扫描路径。

  4. 简化Thymeleaf表单路径写法
    表单的th:action可简化为th:action="@{/posts/new}",无需额外单引号包裹,避免路径解析异常。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.13 02:05:16