个人理解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()后面的语句是否可以被执行
}
....省略其它
}
结果是:页面中显示出了 在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)