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

HttpServletResponse调用sendRedirect无法执行,报错响应已提交问题求助

错误根本原因

你遇到的response is already committed报错的核心原因是:HTTP协议是请求-响应模式的短连接协议,当你的addSolution方法返回ResponseEntity对象时,该PUT请求的完整响应已经被发送给客户端,对应的HttpServletResponse生命周期已经结束,TCP连接也已关闭,后续定时任务再持有这个过期的Response对象操作重定向,必然会抛出异常。

原有设计的其他问题

  • Spring控制器默认是单例模式,你在类中定义的start、time、myResponse都是全局成员变量,多用户同时发起请求时变量会互相覆盖,完全无法正常使用。
  • 服务端的@Scheduled定时任务和客户端的请求生命周期完全解耦,服务端单方面发起的重定向指令根本无法送达已经结束的HTTP请求对应的客户端。

正确实现方案

根据你的使用场景选择对应方案即可:

方案1:使用HTTP Refresh响应头(适配浏览器场景,最简便)

直接在PUT请求的响应头中添加Refresh字段,告诉浏览器1分钟后自动跳转到目标地址,不需要服务端任何定时任务,修改addSolution方法即可:

@PutMapping("/maths/answer")
public ResponseEntity<Object> addSolution(@RequestBody MathsAnswer from, HttpServletResponse res){
    // 原有业务逻辑不变
    Object result = service.addSolution(from);
    // 添加响应头,60秒后跳转到/timeUp
    HttpHeaders headers = new HttpHeaders();
    headers.add("Refresh", "60; url=/timeUp");
    return new ResponseEntity<>(result, headers, HttpStatus.OK);
}

方案2:前端主动计时跳转(适配前后端分离场景,兼容性最好)

前端调用完PUT接口拿到200响应后,自行通过setTimeout计时1分钟,主动跳转到/timeUp地址,不需要服务端做任何额外逻辑。

方案3:WebSocket长连接方案(适配需要服务端主动推送的场景)

如果必须由服务端控制跳转时机,你需要先让客户端和服务端建立WebSocket长连接,PUT请求处理完成后记录客户端标识和开始时间,1分钟后服务端通过WebSocket向对应客户端推送跳转指令,客户端收到指令后再执行跳转操作。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.28 09:36:05