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

Spring Boot 3 请求转发问题:GET转POST触发405方法不允许错误

问题描述

我有一个Job列表页面,其中编辑链接的代码如下:

<a href="/editprep?id=81" class="btn btn-secondary">Edit</a>

需求是先执行编辑准备操作,再转发至编辑表单页面,最后保存数据。但目前出现如下错误:

Whitelabel Error Page

This application has no explicit mapping for /error, so you are seeing this as a fallback.
Mon Aug 14 13:41:33 BST 2023
There was an unexpected error (type=Method Not Allowed, status=405).

控制台报错信息:

2023-08-14T13:41:33.877+01:00  WARN 7881 --- [qtp603184112-33] .w.s.m.s.DefaultHandlerExceptionResolver : Resolved [org.springframework.web.HttpRequestMethodNotSupportedException: Request method 'GET' is not supported]

对应的编辑准备控制器方法:

//@ModelAttribute
@RequestMapping(value="/editprep", method=RequestMethod.GET)
public ModelAndView editPrep(@RequestParam String id, ModelMap model) {
    System.out.printf("Would edit job with ID %s%n", id);
    Job editingJob = repository.findById(Long.valueOf(id)).orElseThrow();
    model.addAttribute("editingJob", editingJob);
    /*
    System.out.println(model);
    System.out.println("Found job " + editingJob);
    */
    //return "redirect:/editjob";
    return new ModelAndView("forward:/editjob", model);
    //return "controlpanel";
}

(因多次调试,代码略显杂乱)

该方法会转发至编辑表单页面,后续保存操作的控制器方法:

@RequestMapping(value="/editjob", method=RequestMethod.POST)
public String editJob(@RequestParam String date, @RequestParam String place, @RequestParam String amount, @RequestParam boolean billed, @RequestParam boolean paid, @RequestParam String notes) {
    return "/";
}

此保存逻辑与创建/保存逻辑基本一致,后续需做代码复用。请问如何解决这个编码错误?是否存在逻辑/流程错误?

解决方案

1. 错误直接原因

405错误的核心是请求方法不匹配:

  • 点击<a>标签发起的是GET请求,editprep处理完后用forward转发到/editjob,转发会保留原请求的GET方法。
  • 但/editjob的控制器方法只支持POST请求,Spring因此抛出HttpRequestMethodNotSupportedException。

2. 修复步骤

方法一:给/editjob添加GET请求支持

编辑表单页面本身需要通过GET请求访问,用来展示表单并回显数据,所以新增一个处理GET请求的/editjob方法:

@RequestMapping(value="/editjob", method=RequestMethod.GET)
public String showEditForm(@ModelAttribute("editingJob") Job editingJob) {
    // 返回编辑表单视图,model中的editingJob会自动回显到表单字段
    return "editJobForm"; // 替换成你的实际表单视图名称
}

原editprep的转发逻辑可以保留,转发后会匹配到这个新的GET方法,正常展示表单。

方法二:合并逻辑,移除editprep步骤

直接把编辑准备逻辑放到/editjob的GET方法中,简化流程:

@RequestMapping(value="/editjob", method=RequestMethod.GET)
public String showEditForm(@RequestParam String id, Model model) {
    Job editingJob = repository.findById(Long.valueOf(id)).orElseThrow();
    model.addAttribute("editingJob", editingJob);
    return "editJobForm";
}

同时修改页面上的编辑链接:

<a href="/editjob?id=81" class="btn btn-secondary">Edit</a>

这种方式更简洁,减少不必要的中间转发步骤。

3. 流程优化建议

  • 表单提交规范:确保编辑表单的<form>标签使用POST方法,action指向/editjob,这样提交时会匹配到现有的POST处理方法。
  • 代码复用:将创建/保存、编辑/保存的核心逻辑提取到公共服务类(比如JobService)的saveJob(Job job)方法中,两个控制器方法直接调用该服务,避免重复代码。
  • 异常处理:findById(...).orElseThrow()可以自定义JobNotFoundException异常,通过@ControllerAdvice统一处理,避免用户看到默认的错误页面。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.13 13:55:59