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

Servlet/JSP表单重复提交问题:RequestDispatcher失效原因及解决

问题分析与解决方案

为什么RequestDispatcher会引发表单重复提交提示?

当你通过POST提交登录表单到owner-controller Servlet后,使用RequestDispatcher.forward()转发到viewStaff.jsp时,浏览器地址栏始终保留原POST请求的URL(owner-controller?action=login)。这是因为转发是服务器内部的资源跳转,浏览器完全感知不到这个过程,它只会记录最后一次响应对应的请求地址。

当你刷新viewStaff.jsp页面时,浏览器会重新发送之前记录的POST请求,也就是再次提交登录表单,因此会弹出确认重复提交的提示。

如何在使用RequestDispatcher时避免表单重复提交?

核心思路是采用Post/Redirect/Get(PRG)模式:登录验证成功后,先通过response.sendRedirect()重定向到一个GET请求的地址,再在该GET请求中使用RequestDispatcher转发到viewStaff.jsp。这样浏览器地址栏会更新为GET请求的URL,刷新时只会发送GET请求,不会触发重复提交。

代码修改示例

  1. 修改登录验证成功后的逻辑,改为重定向到GET请求:
public void login(HttpServletRequest request,HttpServletResponse response) throws ServletException, IOException {
    String username = "";
    String password = "";
    
    String username_err = "";
    String password_err = "";
    
    username = request.getParameter("username");
    password = request.getParameter("password");
    
    if(username.isEmpty()) {
        username_err = "please enter username";
    }
    
    if(password.isEmpty()) {
        password_err = "please enter password";
    }
    
    if(!username.isEmpty()&&!password.isEmpty()) {
        // 将需要传递的数据存入Session(重定向后request域数据会丢失)
        request.getSession().setAttribute("loginUser", username);
        // 重定向到GET请求的viewStaff动作
        response.sendRedirect("owner-controller?action=viewStaff");
    } else {
        request.setAttribute("username_err", username_err);
        request.setAttribute("password_err", password_err);
        RequestDispatcher rd = request.getRequestDispatcher("/owners/login.jsp");
        rd.forward(request, response);
    }
}
  1. 在Servlet中添加doGet方法处理GET请求的viewStaff动作:
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
    String action = request.getParameter("action");
    if("viewStaff".equals(action)) {
        viewStaff(request, response);
    }
}
  1. 原viewStaff方法可保持不变,若需使用存入Session的数据,直接从Session获取后转存到request域即可:
public void viewStaff(HttpServletRequest request,HttpServletResponse response) throws ServletException, IOException {
    // 示例:从Session获取登录用户信息,转存到request域供JSP使用
    String loginUser = (String) request.getSession().getAttribute("loginUser");
    request.setAttribute("loginUser", loginUser);
    
    RequestDispatcher rd = request.getRequestDispatcher("/owners/viewStaff.jsp");
    rd.forward(request, response);
}

补充说明

  • 重定向后request域的数据会丢失,所以需要传递的必要数据必须存入Session,在转发到JSP前可将数据从Session转移到request域,避免Session中残留无效数据。
  • 这种方式既保留了RequestDispatcher转发的优势(可通过request域传递数据到JSP),又解决了表单重复提交的问题,是Web开发中处理POST提交后页面跳转的标准方案。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.08 15:40:28