聊聊重定向与转发

# 重定向:Redirect

重定向是指当浏览器向一个URL发送请求时,服务器返回一个重定向指令,告诉浏览器地址已经变了,麻烦使用新的URL再重新发送新请求

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

@WebServlet(urlPatterns = "/first")
public class RedirectServlet extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) 
                                                throws ServletException, IOException {
        String name = req.getParameter("name");
        String redirectToUri = "index"+(name == null ? "" : "?name="+name);
        resp.sendRedirect(redirectToUri);
    }
}
1
2
3
4
5
6
7
8
9
10

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

HTTP/1.1 302 Found
Location: /hello
1
2

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

启动浏览器控制台,可以看到两次HTTP请求,/first由用户发起,/hellofirst发起,也就是浏览器本身:

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

重定向有两种:一种是302响应,称为临时重定向,一种是301响应,称为永久重定向。两者的区别是,如果服务器发送301永久重定向响应,浏览器会缓存/hi/hello这个重定向的关联,下次请求/hi的时候,浏览器就直接发送/hello请求了。

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

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

resp.setStatus(HttpServletResponse.SC_MOVED_PERMANENTLY); // 301
resp.setHeader("Location", "/hello");
1
2

# 转发: Forward

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

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

@WebServlet(urlPatterns = "/second")
public class ForwardServlet extends HttpServlet {
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) 
        										throws ServletException, IOException {
        req.getRequestDispatcher("/hello").forward(req, resp);
    }
}
1
2
3
4
5
6
7

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

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

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

转发和重定向的区别在于,转发是在Web服务器内部完成的,对浏览器来说,它只发出了一个HTTP请求,并且浏览器的地址栏路径仍然是/second, 浏览器并不知道该请求在Web服务器内部实际上做了一次转发。

上次更新: 2020/09/09, 8:09:00
最近更新
01
RabbitMQ简介
10-27
02
聊聊Java多态
10-21
03
JVM垃圾回收器
10-16
更多文章>