转发与重定向

来源:互联网 发布:手机淘宝排名提升 编辑:程序博客网 时间:2024/06/05 04:21

我们知道,请求转发和请求包含都是在一个请求内,涉及到多个Servlet。既然转发和包含都在一个请求内,那么说明多个Servlet共用同一个request对象和response对象。这个时候就存在request域。

1.request 

Servlet的三大域对象:requestsessionapplication。其中request域是三大域对象中范围最小的域对象,application对象其实就是ServletContext对象;session域会在后面讲解。request域只会在请求转发和请求包含时存在。它的域范围就是整个请求链,如图所示。例如:由AServlet请求转发到BServlet,这时在AServlet中向request域中存放数据,然后在BServlet中从request域中获取数据。如果BServlet又转发给其他的Servlet,那么在其他Servlet中也可以从request域中获取数据。转发过程中经过的这些Servlet都在一个请求链中。

2.request域相关方法介绍

以后只要是域对象,那么它必然会有以下三个方法:

  • void setAttribute(String name,Object value)

    该方法是向域中保存域属性,例如:setAttribute(username,zhangsan),其中,username是域属性的名称,zhangsan是域属性的值。如果多次调用该方法,且属性名称相同,那么后保存的数据会覆盖先保存的数据。

  • Object getAttribute(String name)

     该方法是根据属性名称从域中获取域属性的值,如果之前没有调用setAttribute()方法保存数据,那么调用getAttribute()方法返回值是null

  • void removeAttribute(String name)

     该方法是从域中移出指定名称的域属性,如果该名字的域属性不存在,则该方法什么都不做。

3.域属性和请求参数的区别

很多人在学习域属性的时候会将域属性和请求参数弄混淆,认为域属性就是请求参数。其实这个认知是错误的。下面我们来看域属性和请求参数有哪些区别:

  1. 来源不同

请求参数是由客户端发送给服务器的,而域属性是在服务器内部,在Servlet中向域中添加的;

  1. 相关方法不同

请求参数只能获取,不能修改、删除和添加,而域属性在获取的基础上还可以添加和删除。

为了让大家更加直观的区分它们,下面我们来看一张图

由图可知,域属性是请求转发或请求包含时,在Servlet之间传递的数据。

4.请求转发和重定向的区别

我们已经知道重定向的一些特点,现在根据请求转发的特性,我们将请求转发和重定向做了以下比较:

(1)请求转发是一次请求一次响应,而重定向是两次请求两次响应;

(2)请求转发地址栏不会改变,而重定向地址栏会显示第二次请求的地址;

(3)请求转发只能转发给本项目的其他资源,而重定向不仅可以重定向到本项目的其他资源,还可以重定向到其他项目;

(4)请求转发是服务器端的行为,转发时只需要给出转发的资源路径即可,如Servlet的访问路径;而重定向需要给出全路径,即路径要包含项目名;

(5)请求转发比重定向的效率高,因为请求转发是一个请求。

在以后的开发中,如果需要地址栏的地址发生改变,就选择重定向;如果需要在Servlet之间通过request域进行数据通信,就选择请求转发。

下面通过一个案例来了解request域属性的设置和获取,如下所示:

(1)创建web应用,Example11,在该应用下新建一个Servlet类,FirstServlet,主要代码如例1-1所示:

public classFirstServlet extends HttpServlet {

public voiddoGet(HttpServletRequest request, HttpServletResponse response)

throwsServletException, IOException {

       System.out.println("FirstServlet...");

       request.setAttribute("username","zhangsan");

       request.getRequestDispatcher("/SecondServlet").forward(request,

        response);

}

}

上例中,先在控制台打印“FirstServlet…”,然后向request域中添加域属性,最后再进行转发。需要注意的是,添加域属性的代码不能放在转发代码的后面,否则在SecondServlet中将会获取不到域属性。

(2)再次新建一个Servlet类,SecondServlet,主要代码如下例所示:

public classSecondServlet extends HttpServlet {

public voiddoGet(HttpServletRequest request, HttpServletResponse response)

throwsServletException, IOException {

          System.out.println("SecondServlet...");

          System.out.println(request.getAttribute("username"));

}

}

上中,先在控制台上打印“SecondServlet…”,再打印从域中取出的域属性的值。

(3)FirstServletweb.xml中的访问路径配置为:“/FirstServlet”;SecondServletweb.xml中的访问路径配置为:“/SecondServlet”。

(4)Example11发布到Tomcat中,然后启动服务器,在浏览器地址栏上输入:http://localhost:8080/Example11/FirstServlet,控制台打印结果如图所示:

 

request域在请求转发和请求包含时存在,因为转发和包含都是在同一个请求中,而重定向是两个请求,当我们在第一个请求中,往request域中存放数据,当发送第二次请求时,服务器又会创建一个新的request对象,由于第一个request对象就已经死亡,所以它里面的域属性自然也就不存在了。



原文地址:http://blog.csdn.net/bemavery/article/details/44245281

原创粉丝点击