首先,解释一下 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" } ....省略其它 }
结果是: 页面中只有一个字符: 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()执行的过程: (如图)