一,動作元素(Action):預定義的java代碼。目的在於代碼的可重用性。
1,為要求階段提供資訊,允許在頁面之間轉移控制權。
2,JSP2.0規範定義了標準動作,標準動作是一些標籤,影響JSP運行時的行為和對客戶請求的響應。
在頁面被轉換為Servlet時,JSP容器遇到這些標籤,就使用預先定義的對應於該標籤的java代碼來代替它。
3,動作元素文法基於xml的形式。
<jsp:ActionName attr="value" .... ></jsp:ActionName>
4,JSP標準動作在用戶端請求時執行。
5,動作元素標籤是這些行為在jsp中的使用形式。
6,我們可以自訂動作,使用自訂標籤來實現。
300 425
二,<jsp:userBean>,<jsp:setProperty>和<jsp:getProperty>: 在JSP使用JavaBean,代碼將按出現位置插入到_jspService方法中。
1,<jsp:userBean>用於執行個體化Bean,或定位存在的Bean執行個體。
文法:<jsp:userBean id="Bean的唯一標識" class="package.Class" scop="Bean的可見度" ></jsp:userBean>
Bean的可見度:page(預設),request,session,application
* 執行個體化class指定的類,並將執行個體化後的對象綁定到_jspService中的變數,變數由id指定名稱而類型為自身或type指定。
* 在使用class屬性指定bean類時,不要依賴於page指令的import來匯入類的包。
** Bean共用時,僅當不存在相同id和scope的Bean時才執行個體化新的對象。
* type屬性用於將bean執行個體指向由id指定名稱類型為type指定的變數。類型可以為父類,實現的介面,或者為自身。
例子:假定package.MyBean繼承自java.beans.SimpleBeanInfo
<jsp:userBean id="myBean" class="package.MyBean" scop="session" type="java.beans.SimpleBeanInfo"></jsp:userBean>
在servlet中產生為:java.beans.SimpleBeanInfo myBean = new package.MyBean();
* jsp:userBean起始標籤和結束標籤之間的代碼,只有在執行個體化Bean的時候才執行。所以依賴於scope指定的Bean生命週期。
所以可以將設定bean屬性的代碼(<jsp:setProperty>)放在標籤內。
(<jsp:userBean>標籤內部的代碼</jsp:userBean>)
執行過程:
1,JSP容器在scope屬性指定的範圍尋找指定id的JavaBean執行個體。
2,找到該執行個體,該被執行個體被共用。“該標籤內的代碼也不會被執行。"
3,沒有找到,只指定了class屬性,則根據class屬性來建立一個新執行個體。
沒有找到,只指定了beanName屬性,則使用beanName作為參數調用java.bean.Beans類中的instantiate方法建立新的bean執行個體。
4,將變數儲存到scope屬性指定的範圍中。使用setAttribute方法必須以id的值為key(這由容器自動處理)。
Bean的共用:bean都會綁定到_jspService方法中做為局部變數。
page(預設):由於每個頁面都有不同的PageContext對象,所以不共用bean,對每個請求都建立新的bean。(include指令包含的頁面除外)
request: 在處理當前請求時,將bean放入HttpServletRequest對象中,看起來確實不共用bean,
但在使用include指令和動作,forward轉寄的時候會形成幾個頁面共用一個reqeust對象,也就共用bean了。
session: 當前會話中共用。
application:web應用中共用。
2,<jsp:setProperty>:設定Bean的屬性,對應(而不是簡單的調用)Bean的setXxx方法。
重要:Bean的屬性命名規則和jsp:setProperty標籤的命名規則的一致性,Bean的屬性命名的不規範會導致org.apache.jasper.JasperException異常。
這些規範在java.beans.Beans中定義,由開發工具來調用對類做檢查。Bean之所以是個Bean是由其規範來決定的,而不是由父類來決定的。
bean分析器會執行一個“字母小寫化的過程”來推匯出屬性的名字,將get/set之後的第一個字元轉化為小寫字母。這可能導致屬性和參數名稱的不一致。
要命的在於對於get/set之後二個字母都為大寫字母的屬性,那麼屬性的第一個字母不會被改寫為小寫字母。
假設方法名字為getURL 解析出的的屬性為URL 而不是uRL。如果你聲明屬性為uRL的話,預設的方法命名為getURL。作為屬性uRL和URL顯然是不同的。
所以在命名bean屬性的時候要麼前面2個字母都大寫,要麼前面2個字母都大寫。
在JSP中發生了什麼呢?
在使用<jsp:setProperty>和<jsp:getProperty>的時候,得到所有請求參數的名稱列表,JSP容器通過請求參數來推匯出要設定的相應屬性的get/set方法,調用這個方法。這裡沒有問題。
bean分析器根據bean屬性名稱推匯出方法名,這時JSP容器推匯出來的方法名和bean分析器推匯出的方法名字也沒有問題。
問題來了,在設定屬性值的時候,二者通過方法名推匯出屬性名稱的時候,二者都遇到了麻煩!
文法:<jsp:setProperty name="Bean的ID" property="屬性名稱" value="屬性值"></jsp:setProperty>
<jsp:setProperty name="Bean的ID" property="屬性名稱" param="參數名"></jsp:setProperty>
* param屬性不能和value屬性一起使用。
* 使用value屬性和param屬性的區別:
使用value屬性 : 需要手動將bean屬性和請求參數類型進行匹配轉換。
使用param屬性 : 對於基本類型和封裝類,容器自動將屬性和請求參數的類型進行轉換匹配。匹配失敗不採取任何動作,也就是不會傳遞null。
* 如果bean屬性名稱本與請求參數名相同,那可以不指定parm屬性。
3,<jsp:getProperty>:訪問並輸出Bean的屬性值,對應(而不是簡單的調用)Bean的getXxx方法。
重要:同上;
文法:<jsp:getProperty name="Bean的ID" property="屬性名稱"></jsp:setProperty>
* 把屬性的值轉換為String後發送到輸出資料流輸出,如果屬性是一個對象,將調用該對象的toString()方法。所以有必要為我們的類實現toString方法,而不是依賴Object的預設toString方法;
三,<jsp:param>:以"名-值"對的形式增加或替換首頁面中發送到被包含頁面的請求參數。一般和include指令和動作,forward動作等一起使用;
1,文法:<jsp:param name="參數名" value="參數值"></jsp:param>
2,參數的可見度:首頁面不可以訪問被包含頁面的參數,而被包含頁面可以訪問首頁面的參數。
四,<jsp:include> :在“請求”期間將其他頁面的“輸出”包含進來。這樣的行為和RequestDispatcher類的include方法完全相同。
*當被包含頁面需要改變回應標頭和設定前序時,對於這樣的情況使用include指令。
那怎麼既可以使用jsp:include元素又設定回應標頭和設定前序呢?還有種方法是設定緩衝區,在輸出資料流真正輸入給用戶端之前,設定回應標頭和設定前序。
五,<jsp:forward> :對於處理複雜情況,避免使用該動作。使用servlet的RequestDispatcher的forward方法。
六,<jsp:element>,<jsp:attribute>和<jsp:body>:指定動態定義一個xml元素的標籤。
文法:<jsp:element name="元素名">
<jsp:attributee name="元素屬性名稱" trim="如何處理空格">元素屬性的值</jsp:attributee>
<jsp:body>元素的內容</jsp:body>
</jsp:element>
產生結果:<元素名 元素屬性名稱="元素屬性的值">元素的內容</元素名>
七,其他動作一般與定義jsp文檔的xml有關。