个人理解request.getRequestDispatcher()的两个方法forward()/include()。哪里错了,还麻烦各位提醒!

时间:2015-01-01 21:09:46   收藏:1   阅读:52393

首先,解释一下request.getRequestDispatcher(String arg0)是"转向"的意思,跟response.sendRedirect(String arg0)重定向是不一样的;

1..request.getRequestDispatcher(String arg0)---转向的特点:
1.1.地址栏的URl是不变,如:servlet --A转向到servlet--- B的时候,地址栏还是 A它本身,但是内容其实上已经是B的内容了.
2..response.sendRedirect(String arg0)---重定向的特点:
2.1.地址栏的URL是会改变的.如:servlet --A转向到servlet--- B的时候,地址栏就变成B了
2.2.重定向"  sendRedirect(String arg0)  "跟转向的"  forward()"方法有点类似之处:就是在放在它们后面的语句都不会被执行.还有response不能被传递.
---------------------------------------------------------------------------------------------------------------
解释forward()跟include()两个方法
共同点:
(1) forward() 跟include() 在执行的时候,URl也就是浏览器地址栏那的地址是不会改变.从哪里转向的,就是哪的地址
如下面的例子:(创建两个servlet A跟B)
差异点:
(1)调用forward() 的话,有关response对象的一切方法或者属性都会失去作用..只有request能被转向到下一个页面.
    调用include()的话,response跟request都能被传递到转向的下一个页面..
Servlet A:
public A extends HttpServlet{
....省略其它
doGet(HttpServletRequest req,HttpServletResponse resp){
PrintWriter pw=response.getWriter(); pw.write("A");//在页面上打出"A"
 
request.getRequestDispatcher("B").forward(req,resp);//请看结果1
//使用include()的话,结果会怎样呢?请看结果2
//request.getRequestDispatcher("B").include(req,resp);
}
....省略其它
}
Servlet B:
public B extends HttpServlet{
....省略其它
doGet(HttpServletRequest req,HttpServletResponse resp){
PrintWriter pw=response.getWriter();
pw.write("B");//在页面上打出"B"    
}
....省略其它
}
当我直接在地址栏输入:  localhost:8080/Demo02/A  -->回车得到结果如下图
结果1:----forward()
技术分享
结果是:  页面中只有一个字符:   B  
但是地址栏上的Url还是    localhost:8080/Demo02/A 
结果2:(猜猜看..)---include()
技术分享
结果是:  页面中有两个字符:   AB  
但是地址栏上的Url还是    localhost:8080/Demo02/A 
说明问题: 
Ⅰ.  正如共同点(1)说的那样,不管是forward()还是include(),地址栏的url是不变得,因为它们都是转向的方法.
Ⅱ.  从第一个结果可以看出,调用forward()方法,会失去response对象的传递,(如果用request设置的话,是可以传递到 下一个页面的,下面会讲到)用include()的话,就不会出现这个问题.
------------------------啊,我是一条华丽的分割线-------------------
那么下面进行下一个论证:调用forward()方法,request对象能传递到下一个页面么?还有定义在forward()下面的语句能被执行么?
Servlet A:
public A extends HttpServlet{
....省略其它
doGet(HttpServletRequest req,HttpServletResponse resp){
PrintWriter pw=response.getWriter(); pw.write("A");//在页面上打出"A"
//使用forward()...
request.setAttribute("name", "zhangsan");
request.getRequestDispatcher("B").forward(req, resp);//请看结果3
request.setAttribute("age", 13);
 
//使用include()的话,结果会怎样呢?请看结果4
//request.setAttribute("name", "zhangsan");
//request.getRequestDispatcher("B").include(req,resp);
//request.setAttribute("age", 13);
 
}
....省略其它
}
Servlet B:
public B extends HttpServlet{
....省略其它
doGet(HttpServletRequest req,HttpServletResponse resp){
PrintWriter pw=response.getWriter();
pw.write("B"+"\r\n");//在页面上打出"B"    
pw.write(request.getAttribute("name")+"\r\n");   //测试request对象是否可以通过forward()传递
pw.write(request.getAttribute("age")+"");  //测试写在forward()后面的语句是否可以被执行
}
....省略其它
}
结果3:---使用forward()
技术分享
结果是:页面中显示出了  在request设置的name属性:zhangsan   然而在forward()方法下设置的request属性age却是为null  说明了,执行forward()方法是可以传递request对象设置的属性或者方法的,但是写在forward()方法后面的代码,将不会被执行..
 
结果4:---使用include();
 技术分享
结果是:页面中显示的内容跟结果3是一样..!但是,include()跟forward()引起的原因是不一样,只是结果一样而已!
那么include()导致age丢失的原因是什么呢?
要知道这个原因,首先要理解include()的执行过程是怎么样的?
(---include就是包含的意思---)
现在来讲讲include()执行的过程:   (如图)
技术分享

 过程1-3都是正常的程序执行...到了第4步,程序执行到include()方法的时候,把servlet B的代码直接包含进了servlet A中,

也就是把servlet B合并到A去了,合并完的代码如下图:
技术分享
 由上图可知,include()方法之所以也会丢失age属性值,是由于,age属性调用比age属性设置早了一步,也就是说,age还没赋值呢,程序就调用,等程序调用完后,age才被赋值..
所以,得出结论,include()跟forward()方法导致age为空值得原因是不一样的..

 ----->来自呆呆的坐    也就是本人的网易博客

评论(0
© 2014 mamicode.com 版权所有 京ICP备13008772号-2  联系我们:gaon5@hotmail.com
迷上了代码!