重定向与转发

    例如,我们已经编写了一个能处理的HelloServlet,如果收到的路径为/hi,希望能重定向到/hello,可以再编写一个RedirectServlet

    如果浏览器发送GET /hi请求,RedirectServlet将处理此请求。由于RedirectServlet在内部又发送了重定向响应,因此,浏览器会收到如下响应:

    1. Location: /hello

    当浏览器收到302响应后,它会立刻根据的指示发送一个新的GET /hello请求,这个过程就是重定向:

    观察Chrome浏览器的网络请求,可以看到两次HTTP请求:

    并且浏览器的地址栏路径自动更新为/hello

    重定向有什么作用?重定向的目的是当Web应用升级后,如果请求路径发生了变化,可以将原来的路径重定向到新路径,从而避免浏览器请求原路径找不到资源。

    HttpServletResponse提供了快捷的redirect()方法实现302重定向。如果要实现301永久重定向,可以这么写:

    1. resp.setStatus(HttpServletResponse.SC_MOVED_PERMANENTLY); // 301

    Forward是指内部转发。当一个Servlet处理请求的时候,它可以决定自己不继续处理,而是转发给另一个Servlet处理。

    例如,我们已经编写了一个能处理/helloHelloServlet,继续编写一个能处理/morningForwardServlet

    ForwardServlet在收到请求后,它并不自己发送响应,而是把请求和响应都转发给路径为/hello的Servlet,即下面的代码:

    1. req.getRequestDispatcher("/hello").forward(req, resp);

    后续请求的处理实际上是由HelloServlet完成的。这种处理方式称为转发(Forward),我们用流程图画出来如下:

    forward

    注意到使用转发的时候,浏览器的地址栏路径仍然是/morning,浏览器并不知道该请求在Web服务器内部实际上做了一次转发。

    从下载练习:使用重定向和转发 (推荐使用快速下载)

    使用重定向时,浏览器知道重定向规则,并且会自动发起新的HTTP请求;

    使用转发时,浏览器并不知道服务器内部的转发逻辑。

    重定向与转发 - 图2