最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

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

 更新時(shí)間:2018年11月25日 14:56:32   作者:lulipro - 代碼鋼琴家  
這篇文章主要介紹了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)作。下面一 一介紹。

 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)榧幢隳銓?xiě)入了數(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

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

public class UsersServlet extends HttpServlet {
   private static final long serialVersionUID = 1L ;

protected void doGet (HttpServletRequest request, HttpServletResponse response) throws ServletException , IOException {
      /*****************一般實(shí)際開(kāi)發(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

<%@ 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>

例子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è)原理。

AimServlet.java

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

<%@ 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ù)的一部分。

 

注意事項(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)求資源的路徑一樣(見(jiàn)下面的例子1)。其它的API調(diào)用也是一樣的(Attribute 和Parameter)。

例子1

TargetServlet.java

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 

<%@ 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> 但我很開(kāi)心,因?yàn)轫憫?yīng)給客戶端的數(shù)據(jù)一部分來(lái)自于我 </p>

 

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

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

 

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 () ;
   }
}
<%@ 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" ) %>

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

相關(guān)文章

  • Logback如何將日志輸出到Kafka配置示例

    Logback如何將日志輸出到Kafka配置示例

    logback是一個(gè)功能強(qiáng)大的Java日志框架,它是log4j的繼任者,提供了豐富的功能和配置選項(xiàng),本文將介紹Logback將日志輸出到Kafka配置示例,感興趣的朋友一起看看吧
    2024-12-12
  • 詳談@Autowired和static的關(guān)系

    詳談@Autowired和static的關(guān)系

    這篇文章主要介紹了@Autowired和static的關(guān)系,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2021-08-08
  • Java NIO工作原理的全面分析

    Java NIO工作原理的全面分析

    JDK 1.4 中引入的新輸入輸出 (NIO) 庫(kù)在標(biāo)準(zhǔn) Java 代碼中提供了高速的、面向塊的 I/O。本實(shí)用教程從高級(jí)概念到底層的編程細(xì)節(jié),非常詳細(xì)地介紹了 NIO 庫(kù)。您將學(xué)到諸如緩沖區(qū)和通道這樣的關(guān)鍵 I/O 元素的知識(shí),并考察更新后的庫(kù)中的標(biāo)準(zhǔn) I/O 是如何工作的。您還將了解只能通過(guò) NIO 來(lái)完成的工作,如異步 I/O 和直接緩沖區(qū)。
    2013-02-02
  • SpringBoot實(shí)現(xiàn)異步任務(wù)的項(xiàng)目實(shí)踐

    SpringBoot實(shí)現(xiàn)異步任務(wù)的項(xiàng)目實(shí)踐

    本文將使用SpringBoot 去實(shí)現(xiàn)異步之間的調(diào)用,提高系統(tǒng)的并發(fā)性能、用戶體驗(yàn),具有一定的參考價(jià)值,感興趣的可以了解一下
    2023-10-10
  • Mybatis攔截器實(shí)現(xiàn)數(shù)據(jù)權(quán)限詳解

    Mybatis攔截器實(shí)現(xiàn)數(shù)據(jù)權(quán)限詳解

    這篇文章主要介紹了Mybatis攔截器實(shí)現(xiàn)數(shù)據(jù)權(quán)限詳解, 通過(guò)Mybatis攔截器我們可以攔截某些方法的調(diào)用,我們可以選擇在這些被攔截的方法執(zhí)行前后加上某些邏輯,需要的朋友可以參考下
    2023-11-11
  • Java權(quán)重隨機(jī)的實(shí)現(xiàn)方法

    Java權(quán)重隨機(jī)的實(shí)現(xiàn)方法

    這篇文章主要介紹了Java權(quán)重隨機(jī)的實(shí)現(xiàn)方法,實(shí)例分析了權(quán)重隨機(jī)算法的原理與完整實(shí)現(xiàn)方法,具有一定參考借鑒價(jià)值,需要的朋友可以參考下
    2015-01-01
  • 簡(jiǎn)單介紹Java編程中的線程池

    簡(jiǎn)單介紹Java編程中的線程池

    這篇文章主要介紹了Java編程中的線程池,進(jìn)程和線程的并發(fā)是Java編程中的重要環(huán)節(jié),需要的朋友可以參考下
    2015-09-09
  • SpringBoot整合EasyExcel實(shí)現(xiàn)導(dǎo)入導(dǎo)出數(shù)據(jù)

    SpringBoot整合EasyExcel實(shí)現(xiàn)導(dǎo)入導(dǎo)出數(shù)據(jù)

    這篇文章主要為大家詳細(xì)介紹了如何使用Vue、SpringBoot和EasyExcel實(shí)現(xiàn)導(dǎo)入導(dǎo)出數(shù)據(jù)功能,感興趣的小伙伴可以跟隨小編一起學(xué)習(xí)一下
    2022-05-05
  • SpringBoot整合Lucene實(shí)現(xiàn)全文檢索的詳細(xì)步驟

    SpringBoot整合Lucene實(shí)現(xiàn)全文檢索的詳細(xì)步驟

    全文搜索(Full-Text?Search)是指對(duì)大規(guī)模存儲(chǔ)在計(jì)算機(jī)系統(tǒng)中的文本數(shù)據(jù)進(jìn)行檢索和匹配的技術(shù),它允許用戶輸入關(guān)鍵字,然后從海量的文本數(shù)據(jù)中快速找到相關(guān)的信息,本文介紹了SpringBoot整合Lucene實(shí)現(xiàn)全文檢索的詳細(xì)步驟,需要的朋友可以參考下
    2024-03-03
  • MyBatis流式查詢的使用詳解

    MyBatis流式查詢的使用詳解

    流式查詢指的是查詢成功后不是返回一個(gè)集合而是返回一個(gè)迭代器,應(yīng)用每次從迭代器取一條查詢結(jié)果。流式查詢的好處是能夠降低內(nèi)存使用
    2022-08-08

最新評(píng)論

南昌县| 高尔夫| 鄂托克旗| 崇义县| 通化县| 和平县| 雅江县| 涿州市| 大冶市| 多伦县| 遵义县| 紫阳县| 榆社县| 吴川市| 福泉市| 惠来县| 应城市| 绿春县| 高台县| 无极县| 福建省| 静海县| 五台县| 宜宾市| 陆川县| 东平县| 阿荣旗| 黔南| 会泽县| 偏关县| 三台县| 鹤壁市| 富锦市| 申扎县| 民权县| 双辽市| 南昌县| 杭州市| 盘山县| 奈曼旗| 彰武县|