`
pterodactyl
  • 浏览: 749016 次
  • 性别: Icon_minigender_1
  • 来自: 杭州
社区版块
存档分类
最新评论

jsp/servlet中 forward, include, reDirect 之间的区别

    博客分类:
  • java
阅读更多

 

jsp/servlet forward, include, reDirect 之间的区别

讨论它们的区别之前,先让我们看下它们是怎样被调用的?

 

Response.sendRedirect ( redirect)

redirect ="AccessGoalCharts.jsp?rcatID=3&rhaID=All_&doSearch=true”

实际上,container 会将这个 redirect url 字符串重新送到

Browser interface, 相当于用户重新在address 栏中输入了一个地址,赫赫,

这样解释简单吧?

 

request.getRequestDispatcher ( "welcome.jsp ").forward(request, response);

我们查一下web.xml , 如果我们没有找到相应的servlet  mapping , 那么这套

Request response( 也就是原来的browse interface) 就被转到 welcome.jsp

去处理了,welcome.jsp 产生的html page 也就被返回到了 response( 也就是原来的browser interface). 如果在web.xml 当中我们找到了相应的 servlet mapping, 如下所示,

 <servlet -mapping >

    <servlet -name>DemoServlet </servlet -name>

    <url -pattern>/welcome.jsp </url -pattern>

 </servlet -mapping>

那么这套requestresponse 就被forward 到了DemoServlet doGet 或者 doPost 去处理了,问题是,getRequestDispatcher 为什么 改名字叫做 getURLDispatcher , 这不是更加符合 由 web.xml 控制的实际情况吗?

 

Request.getRequestDispatcher (“welcome.jsp ”).include(request,response ) forward(request,response ) 的情况一模一样,区别在于,这个response, 也就是 Browse Interface 在接收了welcome.jsp 产生的html page 以后( 假设在 web,xml 当中没有相对应于 welcome.jsp servlet -mapping) ,还可以在这个response( browser interface) 当中接收其他的html page, 我测试过的代码如下所示:

            request.getRequestDispatcher ( "welcome.jsp " ).include(request, response);

           

            PrintWriter out = response.getWriter ( );

            out.println ( "<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.01 Transitional//EN\">" );

            out.println ( "<HTML>" );

            out.println ( " <HEAD><TITLE>A Servlet </TITLE></HEAD>" );

            out.println ( " <BODY>" );

            out.print ( "    This is " + request.getParameter ( "name" ));

            out.print ( this .getClass ());

            out.println ( ", using the POST method" );

            out.println ( " </BODY>" );

            out.println ( "</HTML>" );

            out.flush ( );

            out.close ( );

 

好了,还有一些考试大全中经常描述的 forward 对于 用户来讲是透明的,而 reDirect 对于用户来讲是 在browser 的地址栏中可见的讲法,都是正确的讲法.

==============================================================

forward,include,redirect jsp web 页面(jsp servelt ) 的三种不同的路由关系,三个貌似相同,其实还是有许多差别的,而了解这些细微的差别,在web 开发中是很重要的。
说明:
一、forwardincludejavax.servlet.RequestDispatcher 来封装, 由包容器container 提供RequestDispatcher 接口的实现,其中声明如下:
void forward(ServletRequest req,ServletResponse res)
void include(ServeltRequest req,ServletResponse res)
可以通过两种方式得到RequestDispatcher :
1
ServletContext.getRequestDispatcher (String path);
其中这里path 必须开始为"/" ,即这里的path 必须相对于contextroot.
2
ServeltRequest.getRequestDispatcher (String path)
这里的path 可以为相对路径, 如果path 开始为"/", 则也认为是从contextroot 开始的。
二、RedirectHttpServletResponse.sendRedirect (String location) 来支持
差别:
三个都可以对用户的request 进行转发,但是还是有许多的不同,差别最主要集中在如下几个方面:
1
forwardinclude 共亨 Request 范围内的对象,redirect 则不行,即:如果一个javabean 被声明为request 范围的话,则被forward 到的资源也可以访问这个javabean ,redriect 则不行。
2
forwardinclude 基本上都是转发到context 内部的资源,而redirect 可以重定向到外部的资源, 如: req.sendRedriect ("
http://www.mocuai.com ");

以上来源 http://www.cn-java.com/target/news.php?news_id=3176


struts-config.xml
<forward name="succ "  path ="/pages/dynabean2.jsp" redirect="true" />
设置redirect="true" 后 转向目标页面时效果和redirect 一致。

==================================================================

forward,include,redirect jsp web 页面(jsp servelt ) 的三种不同的路由关系,三个貌似相同,其实还是有许多差别的,而了解这些细微的差别,在web 开发中是很重要的。
说明:
一、forwardincludejavax.servlet.RequestDispatcher 来封装, 由包容器container 提供RequestDispatcher 接口的实现,其中声明如下:

通常,在一个设计良好的Web 应用中,都会综合使用Servlet JSP 技术。Servlet 控制业务流转,JSP 则负责业务处理结果的显示 。此时,将大量用到重定向技术。

重定向技术可以分为两类,一类是客户端重定向,一类是服务器端重定向 。客户端重定向可以通过设置特定的HTTP 头,或者写JavaScript 脚本实现。本文主要探讨服务器端重定向技术的实现


服务器端的重定向相关类


服务器端的重定向技术涉及到

javax.servlet.ServletContext

javax.servlet.RequestDispatcher

javax.servlet.http.ServletRequest

javax.servlet.http.ServletResponse 等几个接口。图1 是这几个接口之间的关系图。


1 重定向相关类关系图

 <!-- [if gte vml 1]><v:shapetype id="_x0000_t75" coordsize="21600,21600" o:spt="75" o:preferrelative="t" path="m@4@5l@4@11@9@11@9@5xe" filled="f" stroked="f"> <v:stroke joinstyle="miter"/> <v:formulas> <v:f eqn="if lineDrawn pixelLineWidth 0"/> <v:f eqn="sum @0 1 0"/> <v:f eqn="sum 0 0 @1"/> <v:f eqn="prod @2 1 2"/> <v:f eqn="prod @3 21600 pixelWidth"/> <v:f eqn="prod @3 21600 pixelHeight"/> <v:f eqn="sum @0 0 1"/> <v:f eqn="prod @6 1 2"/> <v:f eqn="prod @7 21600 pixelWidth"/> <v:f eqn="sum @8 21600 0"/> <v:f eqn="prod @7 21600 pixelHeight"/> <v:f eqn="sum @10 21600 0"/> </v:formulas> <v:path o:extrusionok="f" gradientshapeok="t" o:connecttype="rect"/> <o:lock v:ext="edit" aspectratio="t"/> </v:shapetype><v:shape id="_x0000_i1025" type="#_x0000_t75" style='width:420.75pt; height:296.25pt'> <v:imagedata src="jspservlet中%20forward,%20include-%20reDirect%20之间的区别.files/image001.gif" o:title="83364"/> </v:shape><![endif]--><!-- [if !vml]--> <!-- [endif]-->

服务器端的重定向方式


服务器端的重定向可以有两种方式,一是使用HttpServletResponse.sendRedirect () 方法 ,一是使用RequestDispatcher.forward () 方法 。下面对这两种方式进行介绍。

HttpServletResponse.sendRedirect () 方法

HttpServletResponse 接口定义了可用于转向的sendRedirect () 方法。代码如下:

public void sendRedirect (java.lang.String location)throws java.io.IOException

这个方法将响应定向到参数location 指定的、新的URLlocation 可以是一个绝对的URL ,如response.sendRedirect ("http://java.sun.com ") 也可以使用相对的URL 如果location“/” 开头,则容器认为相对于当前Web 应用的根,否则,容器将解析为相对于当前请求的URL 这种重定 向的方法,将导致客户端浏览器的请求URL 跳转。从浏览器中的地址栏中可以看到新的URL 地址,作用类似于上面设置HTTP 响应头信息的实现。

RequestDispatcher.forward () 方法

RequestDispatcher 是一个Web 资源的包装器,可以用来把当前request 传递到该资源,或者把新的资源包括到当前响应中。RequestDispatcher 接口中定义了两个方法,参见如下代码:

public interface RequestDispatcher {
void forward(ServletRequest request, ServletResponse response);
void include(ServletRequest request, ServletResponse response);
}

 

forward() 方法将当前的requestresponse 重定向到该RequestDispacher 指定的资源。这在实际项目中大量使 用,因为完成一个业务操作往往需要跨越多个步骤,每一步骤完成相应的处理后,转向到下一个步骤。比如,通常业务处理在Servlet 中处理,处理的结果转 向到一个JSP 页面进行显示。这样看起来类似于Servlet 链的功能,但是还有一些区别。一个RequestDispatcher 对象可以把请求发送到 任意一个服务器资源,而不仅仅是另外一个Servlet include() 方法将把Request Dispatcher 资源的输出包含到当前输出中。

注意,只有在尚未向客户端输出响应时才可以调用forward() 方法,如果页面缓存不为空,在重定向前将自动清除缓存。否则将抛出一个IllegalStateException 异常。


如何得到RequestDispatcher


有三种方法可以得到Request Dispatcher 对象。

1.javax.servlet . ServletRequest getRequestDispatcher (String path) 方法,其中path 可以是相对路径,但不能越出当前Servlet 上下文。如果path“/” 开头,则解析为相对于当前上下文的根。

2.javax.servlet . ServletContext getRequestDispatcher (String path) 方法,其中path 必须以“/” 开头,路径相对于当前的Servlet 上下文。可以调用ServletContext getContext (String uripath ) 得到另一个Servlet 上下文,并可以转向到外部上下文的一个服务器资源链接。

3. 使用javax.servlet . ServletContext getNamedDispatcher (String name) 得到名为name 的一个Web 资源,包括Servlet JSP 页面。这个资源的名字在Web 应用部署描述文件web.xml 中指定。

这三种方法的使用有细微的差别。比如,下面是一个应用的配置文件web.xml

<?xml version="1.0" ?>
<!DOCTYPE web-app PUBLIC "-//Sun Microsystems, Inc.//DTD Web Application 2.2//EN"
"http://java.sun.com/j2ee/dtds/web-app_2_2.dtd ">
<web-app>
<servlet >
<servlet -name>FirstServlet </servlet -name>
<servlet -class>org. javaresearch.redirecttest.ServletOne </servlet -class>
</servlet >
<servlet >
<servlet -name>SecondServlet </servlet -name>
<servlet -class>org.javaresearch . redirecttest.ServletTwo </servlet -class>
</servlet >
<servlet -mapping>
<servlet -name>FirstServlet </servlet -name>
<url -pattern>/servlet/firstservlet /</url -pattern>
</servlet -mapping>
<servlet -mapping>
<servlet -name>SecondServlet </servlet -name>
<url -pattern>/servlet/secondservlet /</url -pattern>
</servlet -mapping>
</web-app>

 

其中定义了两个Servlet ,名字分别为FirstServlet SecondServlet ,对应的类分别为 org.javaresearch . redirecttest.ServletOne org. javaresearch.redirecttest.ServletTwo 。可以在浏览器中通过类似于下面的链接访问:

http://localhost:8080/servlet/firstservlet/

使用1 中方法,例如在firstservlet 可以写入下面的代码:

RequestDispatcher rd = request.getRequestDispatcher ( "secondservlet ");
rd.forward (request, response);

 

此时控制权将转向到第二个Servlet 了。

使用2 中的方法,可以从Servlet Context 中得到RequestDispatcher 代码如下:

RequestDispatcher rd = getServletContext ( ).getRequest
Dispatcher("/servlet/secondservlet ");
rd.forward (request, response);

 

使用3 中的方法,从上面的web. xml 配置文件可以看到定义了两个Servlet ,名字分别为FirstServlet SecondServlet ,所以可以得到命名的Dispatcher

RequestDispatcher rd = getServletContext ( ).getNamedDispatcher ("SecondServlet ");
rd.forward (request, response);

 

这样也可以重定向到SecondServlet 了。


JSP
页面中的重定向


JSP
在解析后编译为一个Servlet 运行,所以在JSP 中也可以使用上面的重定向代码,并且,JSP 还提供了更便利的操作,如下:

<jsp:forward page= "nextpage.jsp "/>

 

JSP 页面执行到这儿,将终止当前的处理,将控制权交由nextpage.jsp


如何选择


RequestDispatcher.forward ()
方法和HttpServletResponse.sendRedirect () 方 法的区别是:前者仅是容器中控制权的转向,在客户端浏览器地址栏中不会显示出转向后的地址;后者则是完全的跳转,浏览器将会得到跳转的地址,并重新发送请 求链接。这样,从浏览器的地址栏中可以看到跳转后的链接地址。所以,前者更加高效,在前者可以满足需要时,尽量使用Request Dispatcher.forward () 方法,并且,这样也有助于隐藏实际的链接。在有些情况下,比如,需要跳转到一个其它服务器上的资源,则必须使用 HttpServletResponse.sendRequest () 方法。

 

===================================================

forward 是服务器请求资源, 服务器直接访问目标地址的URL, 把那个URL 的响应内容读取过来, 然后把这些内容

再发给浏览器. 浏览器根本不知道服务器发送的内容从哪里来的, 所以它的地址栏还是原来的地址.

redirect
是服务端根据 逻辑, 发送一个状态码, 告诉浏览器重新去请求那个地址. 所以地址栏显示的是新的URL.

redirect 等于客户端向服务器端发出 两次request ,同时也接受两次response

2.
从数据共享来说

forward:
转发页面和转发到的页面可以共享request 里面的数据.

假如从a 页面 到 b 页面 在到c 页面 如果用

a 页面中:

request.setAttribute ( "a","aa ");

<jsp:forward page="b.jsp "></jsp:forward >

b 页面中:

<jsp:forward page="c.jsp "></jsp:forward >

跳转 在c 页面用

request.getAttribute ( "a")

就可以得到a 页面的值,或者用

request.getParameter ( "name")

也可以得到。

但是要用response.sendRedirect ( "b.jsp ");

跳转的话就得不到a 页面的值和内容。


redirect:
不能共享数据.

redirect
不仅可以重定向到当前应用程序的其他资源, 还可以重定向到同一个站点上的其他应用程序中的资源,

甚至是使用绝对URL 重定向到其他站点的资源.

forward,
方法只能在同一个Web 应用程序内的资源之间转发请求.

forward
是服务器内部的一种操作.
redirect
是服务器通知客户端, 让客户端重新发起请求.


所以, 你可以说 redirect 是一种间接的请求, 但是你不能说" 一个请求是属于forward 还是redirect "


3.
从运用地方来说

forward:
一般用于用户登陆的时候, 根据角色转发到相应的模块.

redirect:
一般用于用户注销登陆时返回主页面和跳转到其它的网站等.

4.
从效率来说
forward:
.
redirect:
.


5.jsp
语法

<jsp:forward page={"relativeurl " | "<%= expression %>"} />

或者这样写:

<jsp:forward page={"relativeurl " | "<%= expression %>"} >


<jsp:param name="parametername " value="{parametervalue | <%= expression %>}" />+


</jsp:forward >

6.
例子

<jsp:forward page="/servlet /login" />

<jsp:forward page="/servlet /login">

<jsp:param name="username" value="jsmith " />

</jsp:forward >

描述

<jsp:forward >
标签从一个jsp 文件向另一个文件传递一个包含用户请求的request 对象.<jsp:forward > 标签以下的代码,将不能执行.


你能够向目标文件传送参数和值,在这个例子中我们传递的参数名为username, 值为scott , 如果你使用了<jsp:param > 标签的话,目标文件必须是一个动态的文件,能够处理参数.


如果你使用了非缓冲输出的话,那么使用<jsp:forward > 时就要小心。
如果在你使用<jsp:forward > 之前,jsp 文件已经有了数据,那么文件执行就会出错.

属性

page="{relativeurl | <%= expression %>}"
这里是一个表达式或是一个字符串用于说明你将要定向的文件或url . 这个文件可以是jsp , 程序段,或者其它能够处理request 对象的文件(asp,cgi,php ).

<jsp:param name="parametername " value="{parametervalue | <%= expression %>}" />+
向一个动态文件发送一个或多个参数,这个文件一定是动态文件.

如果你想传递多个参数,你可以在一个jsp 文件中使用多个<jsp:param >name 指定参数名,value 指定参数值.



<jsp:forward >
例子

<%@ page contentType ="text/html;charset =gb2312" %>

<html>

       <head>

              <title>test</title>

       </head>

       <body>

              <jsp:forward page="forwardTo.jsp ">

                     <jsp:param name="userName " value="riso "/>

              </jsp:forward >

       </body>

</html>

forwardTo.jsp

<%@ page contentType ="text/html;charset =gb2312" %>

<!--forwardTo.jsp -->

<%

       String useName =request.getParameter ("userName ");

       String outStr = "
谢谢光临!";

       outStr +=useName ;

       out.println (outStr );

%>

redirect
的例子:

譬 如:client 通过XXX\index.jsp?name =gauss&pwd =123 访问index.jsp ,index.jsp 中有< jsp:forward page="login.jsp "/>, 则在login.jsp 中可以通过<span c

分享到:
评论

相关推荐

    JavaWeb 面试

    1、jsp有哪些内置对象?作用分别是什么? 2、jsp有哪些动作?作用分别是什么?...7、JAVA SERVLET API中forward() 与redirect()的区别? 8、Servlet的基本架构 。。。。。。。。。。。。。。。。。。。。。。

    servlet2.4doc

    forward(ServletRequest, ServletResponse) - Method in interface javax.servlet.RequestDispatcher Forwards a request from a servlet to another resource (servlet, JSP file, or HTML file) on the server. ...

    JavaWeb重点叙述

    JavaWeb重点叙述里包括 jsp部分 servlet的生命周期 简述forward和redirect的区别 理解jsp的运行原理 jsp include指令和include动作的区别 创建servlet的步骤 了解Tomcat jsp的九个内置对象和四大作用域等

    JSP实例编程100例

    34、javax.servlet.jsp.JspWriter - out 对象 35、page 隐含对象 36、application 对象 37、PageContext 对象 38、Page范围 - pageContext 39、测试要显示的中文 40、IF控制符的操作 41、HttpServletRequest 接口所...

    千方百计笔试题大全

    187、JAVA SERVLET API中forward() 与redirect()的区别? 44 189、Can a Java Thread be started from Servlet class, and what will be the implications? 45 190、What is ...

    java面试宝典

    187、JAVA SERVLET API中forward() 与redirect()的区别? 44 189、Can a Java Thread be started from Servlet class, and what will be the implications? 45 190、What is ...

    Java面试宝典2020修订版V1.0.1.doc

    18、JSP中动态INCLUDE与静态INCLUDE的区别? 37 19、JSP和Servlet有哪些相同点和不同点,他们之间的联系是什么? 38 20、页面传递对象的方法? 38 21、Cookied和session区别? 38 22、Filter的生命周期与执行过程 38...

    java面试题

    jsp中动态include和静态include的区别? 答:动态include用jsp:include实现,适用于动态页面,可以携带参数 静态include用include伪码实现,适用于静态页面 math.round(11.5)等于多少?math.round(-11.5)等于多少? ...

    java 面试题 总结

    22、JSP中动态INCLUDE与静态INCLUDE的区别? 动态INCLUDE用jsp:include动作实现 &lt;jsp:include page="included.jsp" flush="true" /&gt;它总是会检查所含文件中的变化,适合用于包含动态页面,并且可以带参数。 静态...

    JAP编程学习100例

    34、javax.servlet.jsp.JspWriter - out 对象 35、page 隐含对象 36、application 对象 37、PageContext 对象 38、Page范围 - pageContext 39、测试要显示的中文 40、IF控制符的操作 41、HttpServletRequest 接口所...

    超级有影响力霸气的Java面试题大全文档

    25、JSP中动态INCLUDE与静态INCLUDE的区别?  动态INCLUDE用jsp:include动作实现 &lt;jsp:include page="included.jsp" flush="true" /&gt;它总是会检查所含文件中的变化,适合用于包含动态页面,并且可以带参数。 静态...

    Java面试宝典2010版

    6、SERVLET API中forward() 与redirect()的区别? 86 7、什么情况下调用doGet()和doPost()? 8、Request对象的主要方法: 87 9、forward 和redirect的区别 10、request.getAttribute() 和 request.getParameter() ...

    java基础题 很全面

    5. JSP中动态INCLUDE与静态INCLUDE的区别? 17 6. JSP和Servlet有哪些相同点和不同点,他们之间的联系是什么? 17 7. forward 和redirect的区别 17 8. 说出在JSP页面里是怎么分页的? 17 9. 什么情况下调用doGet()和...

    最新Java面试宝典pdf版

    6、SERVLET API中forward() 与redirect()的区别? 86 7、什么情况下调用doGet()和doPost()? 86 8、Request对象的主要方法: 87 9、forward 和redirect的区别 87 10、request.getAttribute() 和 request....

    Java面试笔试资料大全

    6、SERVLET API中forward() 与redirect()的区别? 86 7、什么情况下调用doGet()和doPost()? 86 8、Request对象的主要方法: 87 9、forward 和redirect的区别 87 10、request.getAttribute() 和 request....

    JAVA面试宝典2010

    6、SERVLET API中forward() 与redirect()的区别? 86 7、什么情况下调用doGet()和doPost()? 86 8、Request对象的主要方法: 87 9、forward 和redirect的区别 87 10、request.getAttribute() 和 request....

    Java面试宝典-经典

    6、SERVLET API中forward() 与redirect()的区别? 86 7、什么情况下调用doGet()和doPost()? 86 8、Request对象的主要方法: 87 9、forward 和redirect的区别 87 10、request.getAttribute() 和 request....

Global site tag (gtag.js) - Google Analytics