1. 程式人生 > >JavaWeb(三)JSP之3個指令、6個動作、9個內置對象和4大作用域

JavaWeb(三)JSP之3個指令、6個動作、9個內置對象和4大作用域

不用 context 請求 判斷 自定義 except -c 一次 導航欄

前言

  前面大概介紹了什麽是JSP,今天我給大家介紹一下JSP的三個指令、6個動作以及它的9大內置對象。接下來我們就直接進入正題

一、JSP的3個指令

JSP指令(directive)是為JSP引擎而設計的,它們並不直接產生任何可見輸出,而只是告訴引擎如何處理JSP頁面中的其余部分

指令用來申明JSP頁面的一些屬性,比如編碼方式,文檔類型。我們在servlet中也會申明我們使用的編碼方式和響應的文檔類型的,而JSP就是用指令來申明。上面我們也說到了一條指令,也就是page指令。

JSP指令格式:<%@ directive {attribute=value}* %>(<%@ 指令名稱 屬性1=“屬性值1” 屬性2=“屬性值2”。。。%>)

  分析:  

    directive:指令名稱,例如page指令

    attribute=value:緊跟指令名稱後面的就是各種屬性,以鍵值對的形式書寫

    *:代表後面能跟0個或多個屬性。

1.1、page指令(用來聲明JSP頁面的屬性等)

  <%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>  page指令,後面跟著三個屬性,分別是language、contentType、pageEncoding。

  這只是其中的幾個屬性,並沒有寫全,page指令允許的屬性如下表所示: 

        屬性名稱        取值範圍          描述

        language        java      解釋該JSP文件時采用的語言,一般為java語言,默認為java

        extends        任何類的全名   編譯該JSP文件時繼承哪個類,JSP為Servlet,因此當指明繼承普通類時需要實現Servlet的init、destroy等方法

        import         任何包名、類名  引入該JSP中用到的類、包等,import是唯一可以聲明多次的page指令屬性,一個import可以引用uogelei,中間用英文逗號隔開,

                              如<%@ page import="java.util.List,java.util.ArrayList"%>

        session        true、false    該JSP內是否內置Session對象,如果為true,則內置Session對象,可直接使用,否則反之,默認為true

        autoFlush       true,false    是否運行緩存,如果為true,則使用out.println()等方法輸出的字符串並不是立刻到達客戶端服務器的,而是暫時存到緩存裏,緩存滿

                             了或者程序執行完畢或者執行out.flush()操作時才到客戶端,默認為true。

        buffer        none或者數字KB   指定緩存大小,當autoFlush設為true時有效,例如<%@ page buffer=10kb%>

        isThreadSafe      true,false    是否線程安全,如果為true,則運行多個線程同時運行該jsp程序,否則只運行一個線程,其余線程等待,默認為false

        isErrorPage      true,false     指定該頁面是否為錯誤顯示頁面,如果為true,則該JSP內置有一個Exception對象exception,可直接使用,否則沒有,默認為false

        errorPage     某個JSP頁面的相對路徑  指明一個錯誤頁面,如果該JSP程序拋出一個未捕捉的異常,則轉到errorPage指定的頁面,errorPage指定的頁面通常

                               isErrorPage屬性為true,且內置的exception對象為未捕捉的異常

        contentType     有效的文檔類型    客戶端瀏覽器根據該屬性判斷文檔類型,例如 HTML格式為text/html、純文本格式為text/plain、JPG圖像為image/jpeg、GIF圖像為image/gif、

                              WORD文檔為application/msword,該屬性常跟著charset設置編碼一起,作用是通知服務器和瀏覽器都使用同一個碼表

        info          任意字符串      指明JSP的信息,該信息可以通過Servlet.getServletInfo()方法獲取到

    trimDirective Whitespaces    true、false     是否去掉指令前後的空白字符,默認為false

        pageEncoding    UTF-8,ISO-8859-1等    指定一張碼表來對該JSP頁面進行編碼

1.2、include指令

  比較簡單,只有一種形式 <%@ include file="relativeURL"%>  relativeURL:本應用程序內另一個JSP文件或者HTML文件的路徑,例如,網址內所有頁面均有一個統一風格的導航欄和頁腳版權,那麽就可以使用該指令將其包含進來。

  特點:include指令會將包含頁面的源代碼添加到使用include指令的頁面中來,然後編譯成class文件,而等下會講到的一個JSP行為,<jsp:include page="relativeURL">作用跟include指令一樣,

      但是不同的是,include行為是運行時單獨執行包含頁面,然後把執行的結果包含到本頁面來,屬於先運行後包含。  

  註意:  

    靜態包含:把其它資源包含到當前頁面中。
      <%@ include file="/include/header.jsp" %>
    動態包含:
      <jsp:include page="/include/header.jsp"></jsp:include>

    兩者的區別:翻譯的時間段不同
      前者:在翻譯時就把兩個文件合並
      後者:不會合並文件,當代碼執行到include時,才包含另一個文件的內容。

    原則:能用靜的就不用動的。

1.3、taglib指令

  JSP支持標簽技術,後面會講到標簽的用法,jstl標簽庫的使用等,

  作用:用來指明JSP頁面內使用的JSP標簽庫,taglib指令有兩個屬性,uri為類庫的地址,prefix為標簽的前綴

  <%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c"%>

二、JSP的6個動作(行為)

前面講了JSP語法,介紹了JSP頁面中的內容有哪些,分別有什麽作用,就兩個東西,模塊數據和元素。其中元素有包括腳本,指令,標簽,腳本就是JSP中嵌入java代碼,指令作用就是申明頁面的屬性,

那標簽是幹嘛的,標簽分為JSP自帶內置的標簽,和通過taglib指令來使用JSP標簽庫,或者自定義標簽。現在我們先來講一些JSP內置的標簽。 

JSP內置的標簽就被稱為JSP行為(JSP Actions)。只要書寫很少的標記代碼就能使用JSP提供的豐富功能,JSP行為其實是對常用的JSP功能的抽象與封裝,可以取代jsp腳本,讓JSP中就少一些嵌入java代碼的地方

簡單的說就是使用標簽的形式來表示一段java代碼 

格式:<jsp:elements {attribute="value"}* />  

  分析:

     jsp:標簽的前綴,說明是jsp內置的標簽,

     elements:行為的名稱,

     attribute=value:使用鍵值對來編寫屬性

     *:能指定0個或多個屬性對

2.1、<jsp:include />行為(動態包含)

  <jsp:include page="/include/header.jsp"></jsp:include>

  include行為用於運行時包含某個文件,如果被包含的文件為JSP程序,則先會執行JSP程序,然後在把執行的結果包含進來。 

  作用是跟include指令一樣的,唯一的區別就在於,include指令是將被包含的文件的源碼加入到了本JSP程序中,然後在進行編譯,屬於靜態包含,而include行為只是將被包含的文件的運行結果包含進自己。屬於動態包含。

    技術分享

2.2、Java bean行為

  是一組與Java Bean 相關的行為,包括useBean行為、setProperty行為、getProperty行為    

  Java Bean就是普通的Java類,也被稱為POJO,只有私有的屬性與對應的getter方法和setter方法,註意其中當私有的屬性為boolean類型時,習慣上一般把getter方法寫成isXxx();而不是getXxx();  

  1)userBean行為

    <jsp:useBean id="beanObject" class="className" scope="Value">  作用:在jsp中定義一個java bean對象

    分析:   

      id:指明Java Bean對象的名稱,JSP中可以使用該名稱引用該Java Bean對象,相當於給new出來的對象取一個變量名,

      class:Java Bean類的全名

      scope:該java bean對象的作用範圍,可以寫的就四個,也就是JSP的四大作用域,page、request、session、application

        page:只能在當前JSP頁面使用,如果不在JSP頁面,那麽就會失效

        request:這個前面學過,A頁面請求轉發到B頁面,那麽使用的是同一個request,那麽A,B頁面都算是request的作用域,也就是通過請求轉發的頁面都是其作用域

        session:該作用域在一個web項目下任何位置應該讀訪問的到,只要cookie不關閉,並且cookie設置  的訪問路徑為"/",

        application:其實就是Servlet中的servletContext,服務器下的所有項目都能訪問到。

  2)setProperty行為

    <jsp:setProperty name="beanName" property="propertyName" value="">

    分析:

      對Java Bean對象進行屬性的設置

      name:java bean對象的名稱,也就是在useBean行為中的id

      property:對象中的屬性名,

      value:要對其屬性進行賦值的值

  3)getProperty行為

    <jsp:getProperty name="beanName" property="propertyName" />

    分析:            

      獲取JavaBean對象的某個屬性值

      name:java bean 對象的名稱,也就是在useBean行為中的id

      property:對象的屬性名

  舉例:javabean:User.java、NewFile.jsp

  User.java

技術分享
package a;

public class User {
    private int id;
    private String username;
    private String password;
    public int getId() {
        return id;
    }
    public void setId(int id) {
        this.id = id;
    }
    public String getUsername() {
        return username;
    }
    public void setUsername(String username) {
        this.username = username;
    }
    public String getPassword() {
        return password;
    }
    public void setPassword(String password) {
        this.password = password;
    }
    
    
}
User

  NewFile.jsp

技術分享
<body>
    <!-- 創建一個新的javabean對象user,會先判斷在page作用域內是否有叫user對象的javabean,如果有則取它,如果沒有則創建新的javabean對象  -->
    <jsp:useBean id="user" class="a.User" scope="page"></jsp:useBean>
    <!-- 對javabean對象的username進行賦值 -->
    <jsp:setProperty property="username" name="user" value="faker"/>
    <!-- 獲取javabean對象的username屬性 -->
    <jsp:getProperty property="username" name="user"/>
</body>
NewFile.jsp

  可以查看NewFile.jsp變為servlet後的源代碼,看看我們寫的javabean行為會被轉換為何種語句:

  技術分享

  這裏出現了一個JSP九大內置對象中的一個,pageContext。現在簡單提一句,pageContext就是JSP頁面的管理者(上下文),其中的getAttribute(name,scope)方法是獲取指定作用域中的數據的,

  如果getAttribute(name)方法的話,默認是對page作用域進行操作,findAttribute(name)依次從page、request、session、application獲得內容。

  在第一個紅框中,就代表中我們的useBean行為,其中進行了一次判斷,就是如果在page作用域中找不到user這個對象,那麽就創建一個新的,否則就使用找到的這個user對象,

  第二個紅框中,代表著我們的setProperty行為,先找到user對象,然後在對其屬性進行賦值

  第三個紅框中,代表著我們的getProperty行為,也是先找到user對象,然後在獲取其屬性的值。

  註意:對於javabean行為來說,有一個特點的地方,就是當請求過來的參數對應javabean的屬性時,可以為其一次性設置所有的值

      <jsp:setProperty name="user" property="*" /> //設置user的所有屬性,屬性值從request中自動取得,*代表所有屬性。

2.3、<jsp:forward />行為

  實現請求轉發功能,Servlet中通過request.getRequestDispatcher("someServlet").forward(request,response);而在JSP中也能夠實現相同的功能,只不過用的是<jsp:forward />行為,實際上forward行為就是對其進行了封裝。  

  格式:

        <jsp:forward page="someServlet">
           <jsp:param name="param1" value="value1"/>
           <jsp:param name="param2" value="value2"/>
        </jsp:forward>

  分析:page:需要跳轉到的頁面或者servlet、<jsp:param/>參數行為,帶一些參數過去,name、value是以鍵值對的形式帶過去的     

  舉例:

    在NewFile.jsp中

    技術分享

    在ForwardTestServlet中

    技術分享

    訪問:http://localhost:8080/Web_Jsp/NewFile.jsp

    技術分享

    瀏覽器地址欄沒有改變,說明是請求轉發

2.4、<jsp:directive/>行為

  directive行為,就相當於JSP指令,比如<jsp:directive.page/>相當於<%@ page %>指令,等等其它指令是一樣的書寫格式。

總結:

  在我們開發中,經常要用到的6個行為是

    <jsp:include > 動態包含
    <jsp:forward> 請求轉發
    <jsp:param> 設置請求參數

    <jsp:useBean> 創建一個對象
    <jsp:setProperty> 給指定的對象屬性賦值
    <jsp:getProperty> 取出指定對象的屬性值

三、JSP隱藏的九大內置對象

我們知道JSP中的內容就只有兩種,模版數據和元素,元素就包括了指令,腳本,標簽(行為)腳本會慢慢被標簽全部代替,也就是說JSP中基本上不會嵌入Java代碼,但是我們也知道JSP會轉換為servlet,

在Servlet中,輸出數據時,都需要通過response.getWrite();但是在JSP中,直接使用out對象進行輸出,為什麽呢?這就是因為out為JSP的一個隱藏對象,JSP中內置了9個隱藏對象,使得JSP比Servlet使用起來更簡單,更方便。

3.1、九大內置對象概述

  技術分享

  分析:

    request:請求對象,  類型:httpServletRequest

    response:響應對象  類型:httpServletResponse

    session:表示一次會話,在服務器端記錄用戶狀信息的技術

    application:標識web應用上下文,類型:ServletContext,詳情就看Servlet中的ServletContext的使用

    exception 表示發生異常對象,類型 Throwable,在上面我們介紹page指令中的一個errorPage屬性時就有說到他

    page:page對象代表當前JSP頁面,是當前JSP編譯後的Servlet類的對象。相當於this。

    config:標識Servlet配置,類型:ServletConfig,api跟Servlet中的ServletConfig對象是一樣的,能獲取該servlet的一些配置信息,能夠獲取ServletContext

    out:輸出響應體 類型:JspWriter

    pageContext:表示 jsp頁面上下文(jsp管理者) 類型:PageContext

    註意:標記了紅色的對象就是JSP獨有的,其他的都是Servlet中的老東西。

  技術分享

  在這個由jsp轉換為servlet的文件中,只能看到8個內置對象,少了exception對象,因為我們在將page指令時,說過一個isErrorPage屬性,默認是false,被關閉了,所以其中並沒有exception對象。

3.2、pageContext(重要)

  這個功能就比較強大了,基本上什麽他都有,因為是它是JSP頁面的管理者(上下文),所以JSP中的內置對象呀,它統統能夠獲得,下面介紹它的api:

  1)獲得其它八大內置對象 getXxx()

    在普通類中可以通過PageContext獲取其他JSP隱式對象。自定義標簽時就使用。

    pageContext.getOut();  //獲得out對象

    pageContext.getApplication();  //獲得application對象

    等等....

  2)對作用域的屬性進行操作(四大作用域)

    對默認作用域的屬性進行操作。page

    Object getAttribute(String name);  //獲得page作用域數據

    void setAttribute(String name,Object o);  //給page作用域設置內容

    void removeAttribute(String name);  //給page作用域移除內容

  3)對指定作用域的屬性進行操作

    Object getAttribute(String name,int Scope);  //獲得 指定作用域中的數據

    void setAttribute(String name,Object o,int Scope);  //給指定作用域設置內容

    void removeAttribute(String name,int Scope); // 移除指定作用域的內容(page/request/session/application)

  4)提供作用域常量

    PageContext.PAGE_SCOPE  page

    PageContext.REQUEST_SCOPE  request      

    PageContext.SESSION_SCOPE  response

    PageContext.APPLICATION_SCOPE  application

  5)一次獲得指定名稱內容

    page中最厲害的方法是:

      findAttribute(String name); //自動從page request session application依次查找,找到了就取值,結束查找。

  實例:

    在1.jsp中:

    技術分享

    在2.jsp中

    技術分享

  6)提供了的簡易方法  

    pageContext.forward("2.jsp");
    pageContext.include("2.jsp");

3.3、out對象

  類型:JspWriter

  jsp 輸出底層使用 response.getWriter();什麽意思呢?這裏就要講解一下JSP緩存和Servlet緩存了,輸出的過程是這樣的

  技術分享

  JSP頁面轉換為Servlet後,使用的out對象是JspWriter類型的,所以是會先將要發送的數據存入JSP輸出緩存中,然後,等JSP輸出緩存滿了在自動刷新到servlet輸出緩存,

    等serlvet輸出緩存滿了,或者程序結束了,就會將其輸出到瀏覽器上。除非手動out.flush()。

  驗證servlet輸出緩存和JSP輸出緩存和我們上面所說的是正確:

    技術分享

     結果:

       技術分享

    分析:

      如果按沒有jsp緩存和servlet緩存的話,輸出的結果應該是aaaabbbbcccc,但是輸出的卻是bbbbaaaacccc,為什麽呢?按照我們上面所說的原理進行分析,out對象是先將其輸出到JSP緩存中,所以aaaa加入了jsp緩存,

      而response.getWriter().print("bbbb")是直接將bbbb輸出到servlet緩存中,然後又使用out對象將cccc輸出到jsp緩存,到程序結束,servlet緩存中有bbbb,然後jsp會將緩存中的內容就刷新到servlet緩存中,

      serlvet就是bbbbaaaacccc了,然後到瀏覽器也就得到我們的輸出結果了。如果在12行將註釋去掉,那麽輸出的結果又會是什麽呢?答案就是aaaabbbbcccc,過程自行分析。

      技術分享

3.4、config對象

  類型:ServletConfig

  能夠獲取servlet的初始化參數,獲取servletContext對象,獲取servletName。

  這個我在servlet中詳細的講解了,可以去查看!

3.5、exception異常對象

  包含了異常的信息

  使用它,必須結合page指令中的isErrorPage屬性和errorPage屬性

  exception.jsp  拋異常的一個NullPointException,並且跳轉到error.jsp錯誤顯示頁面  errorPage屬性的意思是如果發生未捕捉到的異常,將會跳轉到error.jsp頁面

  舉例:

    技術分享

    error.jsp  isErrorPage屬性說明該頁面是一個錯誤顯示頁面,則可以使用exception對象

    技術分享

  訪問:訪問http://localhost:8080/Web_Jsp/exception.jsp

    技術分享

總結:九大內置對象和servlet中對象的關系  

  page就是jsp轉換為servletservlet對象本身,也就是this

  config -- Servlet中的servletConfig

  application -- Servlet中的ServletContext

  request  -- Servlet中的request

  response  -- Servlet中的response

  session  -- Servlet中的session    

  out  -- JspWriter

  exception  -- 異常對象

  pageContext  -- 表示 jsp頁面上下文(jsp管理者) 類型:PageContext

  其中pageContext是最厲害的,因為它可以得到其他8個內置對象  

四、JSP四大作用域

這四大作用域,其實就是其九大內置對象中的四個,為什麽說他們也是JSP的四大作用域呢?

  因為這四個對象都能存儲數據,比如request.setAttribute()註意和request.setParameter()區分開來,一個是存儲在域中的、一個是請求參數,session.setAttribute()、application其實就是SerlvetContext,自然也有setAttribute()方法。

  而page作用域的操作就需要依靠pageContext對象來進行了。在上面我們也有提到JSP的四大作用域。

1)page作用域

  代表變量只能在當前頁面上生效

2)request作用域

  代表變量能在一次請求中生效,一次請求可能包含一個頁面,也可能包含多個頁面,比如頁面A請求轉發到頁面B。

3)session作用域

  代表變量能在一次會話中生效,基本上就是能在web項目下都有效,session的使用也跟cookie有很大的關系。一般來說,只要瀏覽器不關閉,cookie就會一直生效,cookie生效,session的使用就不會受到影響

4)application作用域

  代表變量能一個應用下(多個會話),在服務器下的多個項目之間都能夠使用。比如baidu、wenku等共享帳號。

  

喜歡就點個“推薦”哦!   

JavaWeb(三)JSP之3個指令、6個動作、9個內置對象和4大作用域