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

JSP 做棵大树 来源:呆呆的坐 6年前 (2017-12-20) 1855次浏览 0个评论

首先,解释一下 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()

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

结果是:  页面中只有一个字符:   B  
但是地址栏上的 Url 还是    localhost:8080/Demo02/A 
结果 2:(猜猜看..)---include()
个人理解 request.getRequestDispatcher()的两个方法 forward()/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.getRequestDispatcher()的两个方法 forward()/include()。哪里错了,还麻烦各位提醒!
结果是:页面中显示出了  在 request 设置的 name 属性:zhangsan   然而在 forward()方法下设置的 request 属性 age 却是为 null  说明了,执行 forward()方法是可以传递 request 对象设置的属性或者方法的,但是写在 forward()方法后面的代码,将不会被执行..
 
结果 4:---使用 include();
个人理解 request.getRequestDispatcher()的两个方法 forward()/include()。哪里错了,还麻烦各位提醒!
结果是:页面中显示的内容跟结果 3 是一样..!但是,include()跟 forward()引起的原因是不一样,只是结果一样而已!
那么 include()导致 age 丢失的原因是什么呢?
要知道这个原因,首先要理解 include()的执行过程是怎么样的?
(---include 就是包含的意思---)
现在来讲讲 include()执行的过程:   (如图)
个人理解 request.getRequestDispatcher()的两个方法 forward()/include()。哪里错了,还麻烦各位提醒!

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

也就是把 servlet B 合并到 A 去了,合并完的代码如下图:
个人理解 request.getRequestDispatcher()的两个方法 forward()/include()。哪里错了,还麻烦各位提醒!
 由上图可知,include()方法之所以也会丢失 age 属性值,是由于,age 属性调用比 age 属性设置早了一步,也就是说,age 还没赋值呢,程序就调用,等程序调用完后,age 才被赋值..
所以,得出结论,include()跟 forward()方法导致 age 为空值得原因是不一样的..

做棵大树 , 版权所有丨如未注明 , 均为原创丨本网站采用BY-NC-SA协议进行授权 , 转载请注明个人理解 request.getRequestDispatcher()的两个方法 forward()/include()。哪里错了,还麻烦各位提醒!
喜欢 (0)
[欢迎投币]
分享 (0)
关于作者:
一个整天无所事事的,有时候忽然热血的孩子
发表我的评论
取消评论
表情 贴图 加粗 删除线 居中 斜体 签到

Hi,您需要填写昵称和邮箱!

  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址