首页 理论教育JavaWeb应用开发|内部跳转与外部跳转的差异

JavaWeb应用开发|内部跳转与外部跳转的差异

【摘要】:下面是请求转发与重定向两种形式的比较。可见,小明一共发出了两个请求和收到了两次回复,小明也知道他的问题是小王解答的。而请求转发是在服务器端内部将请求转发给另外一个资源,浏览器只知道发出了请求并得到了响应结果,并不知道在服务器程序内部发生了转发行为。Servlet2 对客户端的请求做出响应。图3.4forward()方法的工作原理图图3.4所示的交互过程如下:浏览器访问Servlet1。Servlet2 对请求做出响应。

尽管HttpServletResponse 对象的sendRedirect()方法和RequestDispatcher 对象的forward()方法都可以让浏览器获得另外一个URL 所指向的资源,但两者的内部运行机制有着很大的区别。下面是请求转发与重定向两种形式的比较(即内部跳转和外部跳转的区别)。

1.请求转发与重定向的资源范围的区别

请求转发只能将请求转发给同一个WEB 应用中的组件;而请求重定向不仅可以重定向到当前应用程序中的其他资源,还可以重定向到同一个站点上的其他应用程序中的资源,甚至是使用绝对URL 重定向到其他站点的资源。如果传递给HttpServletResponse对象的sendRedirect()方法的相对URL 以“/”开头,它是相对于整个WEB 站点的根目录;如果创建RequestDispatcher 对象时指定的相对URL 以“/”开头,它是相对于当前WEB 应用程序的根目录。

2.浏览器地址栏显示的URL 的区别

使用请求重定向形式的访问过程结束后,浏览器地址栏中显示的URL 会发生改变(如图3.2 所示),由初始的URL 地址变成重定向的目标URL;而使用请求转发形式的访问过程结束后,浏览器地址栏保持初始的URL 地址不变。

3.资源之间的request 对象和response 对象的区别

请求转发过程中资源之间共享相同的request 对象和response 对象,它们属于同一个访问请求和响应过程;而请求重定向过程中资源之间使用各自的request 对象和response 对象,它们属于两个独立的访问请求和响应过程,比如在例3.2 中不能在另一个Servlet 中获取到前一个Servlet 中设置的message 属性的属性值。

4.工作原理的区别

请求重定向对浏览器的请求直接作出响应,响应的结果就是告诉浏览器去重新发出对另外一个URL 的访问请求。这个过程好比你的同学小明向你请教一个问题,而你现在比较忙或解决不了,但是你知道小王可以帮他解决这个问题,所以你告诉他小王可以帮他解决,小明收到你的回复之后立即去请教小王,然后小王为小明解答问题。可见,小明一共发出了两个请求和收到了两次回复,小明也知道他的问题是小王解答的。

而请求转发是在服务器端内部将请求转发给另外一个资源,浏览器只知道发出了请求并得到了响应结果,并不知道在服务器程序内部发生了转发行为。这个过程好比小明向你请教一个问题,而你解决不了,但是你知道小王可以解决,所以你去请教小王,然后将小王的回复再回复给小明。可见,小明只发出了一个请求和收到了一次回复,他只知道你帮他解决了问题,并不知道你请教了小王。

下面分别给出了sendRedirect()方法和forward()方法的工作原理图。

图3.3 sendRedirect()方法(外部跳转)的工作原理图

图3.3 所示的交互过程如下:(www.chuimin.cn)

(1)浏览器访问Servlet1(发送请求)。

(2)Servlet1 想让Servlet2 为客户端服务,调用sendRedirect()方法,将客户端请求重定向到Servlet2。

(3)浏览器访问Servlet2。

(4)Servlet2 对客户端的请求做出响应。

从图3.3 中的交互过程可以看出,调用sendRedirect()方法实际上是告诉浏览器Servlet2 所在的位置,让浏览器重新访问Servlet2。调用sendRedirect()方法,会在响应中设置Location 响应报头。要注意的是,这个过程对于用户来说是透明的,浏览器会自动完成新的访问。

图3.4 forward()方法(内部跳转)的工作原理图

图3.4 所示的交互过程如下:

(1)浏览器访问Servlet1(发送请求)。

(2)Servlet1 想让Servlet2 对客户端的请求进行响应,于是调用forward()方法,将请求转发给Servlet2 进行处理。

(3)Servlet2 对请求做出响应。

从图3.4 中的交互过程可以看出,调用forward()方法,对浏览器来说是透明的,它并不知道为其服务的Servlet 已经换成了Servlet2,它只知道发出了一个请求,获得了一个响应。