Servlet 网页重定向

sendRedirect 与 forward 的本质差别、301 与 302 的选择。

Beginner
Key Points重定向是客户端行为,浏览器发第二次请求,地址栏会变;转发是服务端行为,一次请求,地址栏不变。

两种跳转

forward
Where客户端服务端
Requests2 次1 次
URL bar变成新地址不变
Request scope丢失保留
Target可以是外部站点只能本应用内
Speed多一次往返快

代码

Java
// 重定向:登录成功后跳到首页
resp.sendRedirect(req.getContextPath() + "/home");

// 转发:Servlet 查完数据交给 JSP 渲染
req.setAttribute("user", user);
req.getRequestDispatcher("/WEB-INF/views/user.jsp").forward(req, resp);

Redirect URLs must include getContextPath(), or a /myapp deployment jumps to the server root. Forwards use app-relative paths without the context path.

301 与 302

Java
// 302 临时重定向(sendRedirect 的默认行为)
resp.setStatus(HttpServletResponse.SC_FOUND);
resp.setHeader("Location", "/new-page");

// 301 永久重定向:告诉搜索引擎和浏览器缓存这个跳转
resp.setStatus(HttpServletResponse.SC_MOVED_PERMANENTLY);
resp.setHeader("Location", "/new-page");

// 307 临时重定向,且保持原请求方法(POST 仍是 POST)
resp.setStatus(HttpServletResponse.SC_TEMPORARY_REDIRECT);
resp.setHeader("Location", "/new-page");
  • 301 —— 网站改版、域名迁移。浏览器会长期缓存,改错了很难撤回
  • 302 —— 登录后跳转、临时维护。默认选择
  • 307 —— 需要保留 POST 体和方法的场景

POST 后重定向

After a successful form submit, redirect to the result page instead of forwarding to it. Otherwise refreshing resubmits the form — that is the PRG (Post/Redirect/Get) pattern.

Java
// 错误:刷新会重复下单
req.getRequestDispatcher("/order/success.jsp").forward(req, resp);

// 正确:重定向,刷新只是重新 GET 结果页
resp.sendRedirect(req.getContextPath() + "/order/success?id=" + orderId);
Always return after sendRedirect. It does not stop method execution; later code still runs and may write a partial response, causing IllegalStateException.

Friends & Partners