Servlet重定向与转发

2023/05/19

1. 概述

有时候,Java Servlet中的初始HTTP请求处理程序需要将请求委托给另一个资源。 在这些情况下,我们可以进一步转发请求,也可以将其重定向到其他资源。

在本文中我们介绍这两种机制,并讨论它们的差异和最佳实践。

2. Maven依赖


<dependency>
    <groupId>javax.servlet</groupId>
    <artifactId>javax.servlet-api</artifactId>
    <version>4.0.1</version>
</dependency>

3. Forward

让我们看看如何做一个简单的Forward:

/*@formatter:off*/
protected void doGet(HttpServletRequest req, HttpServletResponse resp) {
    RequestDispatcher dispatcher = getServletContext().getRequestDispatcher("/forwarded");
    dispatcher.forward(req, resp);
}
/*@formatter:on*/

我们从父Servlet获取RequestDispatcher引用,并将其指向另一个服务器资源

简单地说,这会转发请求,当客户端向“http://localhost:8080/hello?name=Dennis”发送请求,此逻辑将运行,请求将转发到“/forwarded”。

4. Redirect

下面是使用重定向的代码片段:

/*@formatter:off*/
protected void doGet(HttpServletRequest req, HttpServletResponse resp){
    resp.sendRedirect(req.getContextPath() + "/redirected");
}
/*@formatter:on*/

我们使用原始Response对象将此请求重定向到另一个URL:“/redirected”

当客户向“http://localhost:8080/welcome?name=Dennis”发送请求时,请求将被重定向到“http://localhost:8080/redirected”。

5. 差异

在这两种情况下,我们都传递了带有值的参数“name”。 简单地说,转发的请求仍然具有这个值,但重定向的请求没有。

这是因为使用通过重定向时,Request对象与原始对象不同,如果我们仍然想使用这个参数,则需要将其保存在HttpSession对象中。

下面列出了Servlet转发和重定向之间的主要区别:

Forward:

  • 请求将在服务器端进一步处理
  • 客户端不受转发的影响,浏览器中的URL保持不变
  • Request和Response对象在转发后将保持相同的对象,请求范围内对象仍然可用

Redirect:

  • 请求被重定向到其他资源
  • 客户端将在重定向后看到URL的改变
  • 创建一个新请求
  • 重定向通常在Post/Redirect/Get web开发模式中使用

6. 总结

转发和重定向都是关于将用户请求发送到不同的资源,尽管它们具有完全不同的语义。

如何选择它们进行使用很简单:如果需要上一个Request作用域,或者不需要通知用户,但应用程序也希望执行内部操作,则使用转发。

要放弃Request作用域,或者如果新内容与原始请求没有关联(例如重定向到登录页面或完成表单提交),则使用重定向。

与往常一样,本教程的完整源代码可在GitHub上获得。

Show Disqus Comments

Post Directory

扫码关注公众号:Taketoday
发送 290992
即可立即永久解锁本站全部文章