一区二区三区在线-一区二区三区亚洲视频-一区二区三区亚洲-一区二区三区午夜-一区二区三区四区在线视频-一区二区三区四区在线免费观看

服務(wù)器之家:專注于服務(wù)器技術(shù)及軟件下載分享
分類導(dǎo)航

PHP教程|ASP.NET教程|Java教程|ASP教程|編程技術(shù)|正則表達(dá)式|C/C++|IOS|C#|Swift|Android|JavaScript|易語(yǔ)言|

服務(wù)器之家 - 編程語(yǔ)言 - Java教程 - Servlet關(guān)于RequestDispatcher的原理詳解

Servlet關(guān)于RequestDispatcher的原理詳解

2021-06-17 11:08lulipro - 代碼鋼琴家 Java教程

這篇文章主要介紹了Servlet關(guān)于RequestDispatcher的原理詳解,小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧

requestdispatcher簡(jiǎn)介

requestdispatcher 代表請(qǐng)求的派發(fā)者。它有2個(gè)動(dòng)作:forward 和 include 。客戶端對(duì)于任何一個(gè)請(qǐng)求,可以根據(jù)業(yè)務(wù)邏輯需要,選擇不同的處理辦法:

1、請(qǐng)求的是誰(shuí),誰(shuí)就自己處理并響應(yīng),例如請(qǐng)求的是一個(gè)html,則web瀏覽器顯示的就是這個(gè)html的內(nèi)容。

2、使用requestdispatcher讓其它的資源參與進(jìn)來(lái),協(xié)同完成的響應(yīng),這就是requestdispatcher的主要作用。

requestdispatcher 有一個(gè)特點(diǎn),就是瀏覽器上顯示的url是最先請(qǐng)求的目標(biāo)資源的url,不會(huì)因?yàn)槭褂昧薴orward、include方法而改變。因此forward和include的調(diào)用對(duì)于用戶來(lái)說(shuō)是透明的。

requestdispatcher 實(shí)質(zhì)是一個(gè)接口,有2個(gè)方法分別代表這2個(gè)動(dòng)作。下面一 一介紹。

?
1
2
3
4
5
6
7
8
public interface requestdispatcher
{
  public void forward(servletrequest request, servletresponse response)
      throws servletexception, ioexception;
 
  public void include(servletrequest request, servletresponse response)
      throws servletexception, ioexception;
}

requestdispatcher.forward(request, response)

這個(gè)方法將請(qǐng)求從一個(gè) servlet or jsp目標(biāo)資源 上 轉(zhuǎn)發(fā)到服務(wù)器上的另一個(gè)資源(servlet、jsp 文件或 html 文件,這些資源必須是當(dāng)前web上下文中的),讓其它的資源去生成響應(yīng)數(shù)據(jù)。

例如用戶請(qǐng)求的是目標(biāo)資源a,a接受到請(qǐng)求后,轉(zhuǎn)發(fā)到b,真正產(chǎn)生響應(yīng)數(shù)據(jù)是被轉(zhuǎn)發(fā)的資源b,而a只是起個(gè)引導(dǎo)轉(zhuǎn)發(fā)作用。瀏覽器的地址欄不會(huì)變,依然是a的url。

這個(gè)方法可以允許被請(qǐng)求的目標(biāo)資源做一些準(zhǔn)備工作后,再讓轉(zhuǎn)發(fā)的資源去響應(yīng)請(qǐng)求。例如下面的例子1。

注意事項(xiàng):  

1、在目標(biāo)資源中調(diào)用forward方法時(shí),必須保證此響應(yīng)沒(méi)有提交。也就是不要使用 servletresponse 對(duì)象的輸出流對(duì)象,因?yàn)榧幢隳銓懭肓藬?shù)據(jù)到響應(yīng)緩沖區(qū),最后也會(huì)被清空,如果緩沖區(qū)數(shù)據(jù)被刷新提交(out.flush),還會(huì)拋出illegalstateexception異常。

2、對(duì)于forward方法傳遞的request對(duì)象:雖然我們從調(diào)用上看,好像是將request對(duì)象傳遞給轉(zhuǎn)動(dòng)的資源上去了,但是我發(fā)現(xiàn)目標(biāo)資源使用的request對(duì)象和轉(zhuǎn)發(fā)的資源使用的request對(duì)象不是同一個(gè)request對(duì)象,因?yàn)榉謩e從這2個(gè)request中獲取requesturl,發(fā)現(xiàn)是不一樣的。但是在目標(biāo)資源request提取的paramter 和 attribute   ,在轉(zhuǎn)發(fā)后的資源的request對(duì)象中,依然都可以提取到,且是相同的。所以,二者只是在請(qǐng)求路徑相關(guān)的屬性上不同,其它api調(diào)用返回的都是一樣的。

3、在forward語(yǔ)句的前后,都不應(yīng)該有響應(yīng)輸出的語(yǔ)句,應(yīng)該會(huì)被忽略。

例子1:一個(gè)簡(jiǎn)單的 mvc演示。servlet充當(dāng)控制器,轉(zhuǎn)發(fā)到view層的jsp。

user.java

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
public class user{
   private string name;
   private int age;
   public string getname(){
      return name ;
   }
   public void setname( string name ){
      this .name = name ;
   }
   public int getage() {
      return age ;
   }
   public void setage( int age ){
      this .age = age ;
   }
}

usersservlet.java

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
public class usersservlet extends httpservlet {
   private static final long serialversionuid = 1l ;
 
protected void doget (httpservletrequest request, httpservletresponse response) throws servletexception , ioexception {
      /*****************一般實(shí)際開發(fā)這些用戶數(shù)據(jù)都是從數(shù)據(jù)庫(kù)查出來(lái)的*********/
      list <user > users = new arraylist <> ();
      user u1 = new user () ;
      u1 .setage ( 20) ;
      u1 .setname ( "bob") ;
      user u2 = new user () ;
      u2 .setage ( 21) ;
      u2 .setname ( "tony") ;
      users .add ( u1) ;
      users .add ( u2) ;
      /*********************************************/
      request .setattribute ( "users", users) ;  //對(duì)request 進(jìn)制預(yù)處理準(zhǔn)備工作
      request .getrequestdispatcher ( "users.jsp").forward( request , response );//轉(zhuǎn)發(fā)到users.jsp,讓他去具體響應(yīng)
  }
}

users.jsp

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
<%@ page  contenttype= "text/html; charset=utf-8" pageencoding ="utf-8" trimdirectivewhitespaces= "true"
     session ="true" %>
<%@ taglib prefix= "c" uri = "http://java.sun.com/jsp/jstl/core"  %>
 
<!doctype html>
< html>
<head>
<meta http-equiv = "content-type" content ="text/html; charset=utf-8">
<title> 用戶列表</title>
</head>
<body>
 
<p> -----------------轉(zhuǎn)發(fā)到的資源users.jsp產(chǎn)生的響應(yīng)數(shù)據(jù)------------------ </p>
 
< c:foreach var ="user" items= " ${users}" >
用戶姓名:${user.name} 用戶年齡:${user.age} <br />
</ c:foreach>
</body>
</html>

Servlet關(guān)于RequestDispatcher的原理詳解

例子2:不使用attribute,使用paramter向轉(zhuǎn)發(fā)的資源傳遞參數(shù)。

雖然request對(duì)象沒(méi)有setparameter方法來(lái)設(shè)置參數(shù),但是我們可以在轉(zhuǎn)發(fā)的url后通過(guò)querystring 的方式添加。jsp中的<jsp:foward>標(biāo)簽下的<jsp:param>標(biāo)簽就是使用的這個(gè)原理。

Servlet關(guān)于RequestDispatcher的原理詳解

aimservlet.java

?
1
2
3
4
5
6
7
8
public class aimservlet extends httpservlet {
   private static final long serialversionuid = 1l ;
 
   protected void doget( httpservletrequest request , httpservletresponse response) throws servletexception , ioexception {
 
      request .getrequestdispatcher ( "foo.jsp?num=1") . forward( request , response );
   }
}

foo.jsp

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
<%@ page  contenttype= "text/html; charset=utf-8" pageencoding ="utf-8" trimdirectivewhitespaces= "true"
     session ="true" %>
<%@ taglib prefix= "c" uri = "http://java.sun.com/jsp/jstl/core"  %>
 
<! doctype html>
<html>
<head>
<meta http-equiv = "content-type" content ="text/html; charset=utf-8">
<title> 標(biāo)題</title>
</head>
<body>
 
通過(guò)forward傳遞過(guò)來(lái)的參num=${param.num}
 
</body>
</html>

requestdispatcher.include(request, response)

此方法用于包含響應(yīng)中某個(gè)資源(servlet、jsp 頁(yè)面和 html 文件)的內(nèi)容。

調(diào)用者指定一個(gè)被包含的資源,將這個(gè)包含的資源(jsp,servlet,html)的響應(yīng)數(shù)據(jù)包含到自己的響應(yīng)體中。被包含的數(shù)據(jù)是在服務(wù)器上經(jīng)過(guò)運(yùn)行產(chǎn)生的,因此是動(dòng)態(tài)包含,而不同于jsp中的include指令,它是jsp轉(zhuǎn)譯期的靜態(tài)包含,類似于c語(yǔ)言中的宏一樣。

這個(gè)過(guò)程實(shí)質(zhì)是用一個(gè)相同的request再請(qǐng)求一次被包含的資源,將被包含的資源的響應(yīng)數(shù)據(jù)包含到原本的資源中去,構(gòu)成它的響應(yīng)數(shù)據(jù)的一部分。

 Servlet關(guān)于RequestDispatcher的原理詳解

注意事項(xiàng):

1、被包含者不能設(shè)置servletresponse的響應(yīng)狀態(tài)和響應(yīng)頭(否則并不會(huì)產(chǎn)生效果),因?yàn)檫@些都是包含者做的事,被包含者只需要產(chǎn)生響應(yīng)數(shù)據(jù)解可以了。

2、不同于 forward中的request的傳遞特性:在被包含的資源中從request中獲取請(qǐng)求路徑相關(guān)的信息,發(fā)現(xiàn)依然是原始請(qǐng)求的路徑,也就是瀏覽器地址欄相關(guān)的路徑,也就是說(shuō)被包含的資源獲得的request對(duì)象的路徑屬性和原始請(qǐng)求資源的路徑一樣(見下面的例子1)。其它的api調(diào)用也是一樣的(attribute 和parameter)。

例子1

targetservlet.java

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
public class targetservlet extends httpservlet {
   private static final long serialversionuid = 1l ;
   protected void doget( httpservletrequest request , httpservletresponse response) throws servletexception , ioexception {
 
      response .setcontenttype ( "text/html;charset=utf-8" );
      printwriter out = response .getwriter () ;
 
      out .println ( "----------來(lái)自targetservlet的告白----------------<br />" ) ;
      out .print ( "我偷懶了,下面的響應(yīng)數(shù)據(jù)并不是我自己產(chǎn)生的,而是包含的其它資源產(chǎn)生的<br/>" ) ;
      request .getrequestdispatcher ( "test.jsp") . include( request , response );
 
      out .flush () ;
      out .close () ;
   }
}

test.jsp 

?
1
2
3
4
5
6
7
8
<%@ page  contenttype= "text/html; charset=utf-8" pageencoding = "utf-8" trimdirectivewhitespaces = "true"
     session = "false"
%>
 
<p> ------------------------來(lái)自test.jsp的告白-------------------------- </p>
<p> 我輸出的響應(yīng)數(shù)據(jù)將被其它的資源包含 </p>
請(qǐng)的url是 <%= request.getrequesturl().tostring() %> ,可以看出客戶端真正請(qǐng)求的不是我,我只是幕后工作者。
<p> 但我很開心,因?yàn)轫憫?yīng)給客戶端的數(shù)據(jù)一部分來(lái)自于我 </p>

Servlet關(guān)于RequestDispatcher的原理詳解

例子2:通過(guò)包含路徑后追加querystring來(lái)向被包含資源傳遞參數(shù),以及通過(guò)request.setattribute傳遞屬性。

同樣, jsp中的<jsp:include>標(biāo)簽下的<jsp:param>標(biāo)簽就是通過(guò)在含路徑后追加querystring達(dá)到的傳遞參數(shù)的效果。

Servlet關(guān)于RequestDispatcher的原理詳解

 

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
public class targetservlet extends httpservlet {
   private static final long serialversionuid = 1l ;
   protected void doget( httpservletrequest request , httpservletresponse response) throws servletexception , ioexception {
 
      response .setcontenttype ( "text/html;charset=utf-8" );
      printwriter out = response .getwriter () ;
 
      out .println ( "----------來(lái)自targetservlet的告白----------------<br />" ) ;
      out .print ( "我偷懶了,下面的響應(yīng)數(shù)據(jù)并不是我自己產(chǎn)生的,而是包含的其它資源產(chǎn)生的<br/>" ) ;
 
      request .setattribute ( "sharedatt", "i`m shared attribute") ;
 
      request .getrequestdispatcher ( "test.jsp?sharedparam=im-shared-parameter" ). include (request , response ) ;
 
      out .flush () ;
      out .close () ;
   }
}
?
1
2
3
4
5
6
7
8
<%@ page  contenttype= "text/html; charset=utf-8" pageencoding = "utf-8" trimdirectivewhitespaces = "true"
     session = "false"
%>
 
<p> ------------------------來(lái)自test.jsp的告白-------------------------- </p>
<p> 我輸出的響應(yīng)數(shù)據(jù)將被其它的資源包含 </p>
<p> 從request中提取共享的屬性attribute : <%= request.getattribute("s haredatt") %>
<p> 從request中提取共享的參數(shù)parameter : <%= request.getparameter("sharedparam" ) %>

Servlet關(guān)于RequestDispatcher的原理詳解

以上就是本文的全部?jī)?nèi)容,希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持服務(wù)器之家。

原文鏈接:https://www.cnblogs.com/lulipro/p/7471987.html

延伸 · 閱讀

精彩推薦
主站蜘蛛池模板: 久久久亚洲国产精品主播 | 天天做日日做天天添天天欢公交车 | 日韩理论在线观看 | 性做久久久久久久久浪潮 | 欧美视频黑鬼大战白妞 | 美女张开下身让男人桶 | 成3d漫二区三区四区 | h玉足嫩脚嗯啊白丝 | 日本红色高清免费观看 | 四虎库| 欧美精品成人a多人在线观看 | 国产午夜精品理论片 | 国产成人综合手机在线播放 | 国产色在线观看 | 91亚洲精品第一综合不卡播放 | 波多野结衣伦理在线观看 | 精品久久免费视频 | 大妹子最新视频在线观看 | 97精品国产自在现线免费 | 国产视频一二三区 | 国产亚洲欧美日韩综合综合二区 | 激情婷婷综合久久久久 | 成人私人影院在线版 | 国产精品一久久香蕉产线看 | 午夜综合| 欧美性另类69xxxx | 国产在线拍 | ai换脸明星专区在线观看 | 无限时间看片在线观看 | 久久香蕉电影 | 好大好硬好湿好紧h | 506070老熟肥妇bbwxx视频 500第一精品 | 国产福利在线观看91精品 | 大胆私拍模特国模377 | 亚洲10p| 韩剧消失的眼角膜免费完整版 | 日本漫画被黄漫免费动 | 欧美激烈精交gif动态图18p | 黑人巨大爆粗亚裔女人 | 国产一区二区视频在线观看 | 玩高中女同桌肉色短丝袜脚文 |