Directive Elements 指令元素

 的語法使用<%@%>,主要用來指定JSP網頁相關的輸出方式、引用套件、載入檔案...等相關資訊,其並不會輸出任何資料至前端網頁,其有效範圍僅限於該指令所在之JSP網頁中。

又分有以下三種類別:

 

1. Page Directive 網頁指令

◎ Page 指令 :語法使用<%@ page%>

 屬性  說明
info 此網頁的說明資訊,這個資訊最後會轉換為 Servlet 程式中使用 getServletInf() 所取得的資訊。

<%@page info="JSP Test File"%>

  public String getServletInfo() {
    return "JSP Test File";
  }

 

<%= getServletInfo() %>

contentType*
用於設定MIME型態及網頁編碼方式,此屬性的預設值為『text/html; charset= ISO-8859-1』,在這邊設定的是text/html,而編碼方式則設定Big5碼,這個部份的設定是給瀏覽器判斷該以什麼樣的方式顯示網頁文件,在Servlet中,這個部份是對應於 HttpServletResponse物件的setContentType()方法:

<%@page contentType="text/html;charset=Big5"%>

response.setContentType("text/html;charset=Big5");

pageEncoding*
用於指定JSP網頁轉為Servlet編譯時採取的編碼方式,如此在編譯時才能正確的轉換程式碼中設定的字元,例如JSP網頁中包括Big5中文字的話,必須設定<%@ page pageEncoding="Big5"%>,預設是作業系統的語系設定,在不使用 response 的setCharacterEncoding()設定時,pageEncoding也是回應時預設的編碼指定。

<%@page pageEncoding="Big5"%>

response.setContentType("text/html;charset=Big5");

language 定義JSP網頁所使用的描述語言。

<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>

response.setContentType("text/html; charset=UTF-8");

import 指定JSP網頁所使用的Java套件,即轉譯為Java語法的import。(可重覆設定)

<%@page import="javax.servlet.jsp.HttpJspPage,java.util.Date"%>

import javax.servlet.jsp.HttpJspPage;
import java.util.Date;

extends 指定JSP網頁編譯後產生的Servlet,該繼承哪一個類別(亦稱父類別)。
<%@page extends="HttpServlet"%> 

 
autoFlush 用於設定至客戶端的輸出串流是否要自動出清,預設是true,如果設定為false,而緩衝區滿了卻還沒將資料送出至客戶端,將會產生例外。
 
buffer 設定此網頁輸出時,設定至客戶端的輸出串流緩衝區大小,預設是8KB,欲自行設定時,緩衝區大小必須是8kb的倍數,若設定為none,表示輸出JSP網頁時,將不使用緩衝區。
<%@page buffer=“none|緩衝區大小kb"%>
 
errorPage 用於設定當JSP執行錯誤而產生例外時,該由哪一個頁面處理這個例外在設定errorPage屬性的網頁中,錯誤訊息將以throw敘述丟出,而被設定為錯誤訊息網頁的JSP網頁,將利用exception隱含物件取得錯誤訊息。
<%@page contentType="charset=Big5"  errorPage="errorHandler.jsp"%>
isErrorPage 用以設定JSP頁面是否為處理例外的頁面,預設值為false,當設定為true時,JSP網頁將可存取隱含的exception物件,並透過該物件取得從發生錯誤之網頁,所傳出的錯誤訊息,這個屬性要與 errorPage 配合使用。(用來處理錯誤的JSP頁面則設定 isErrorPage屬性為true即可)

<%@page contentType="text/html;charset=Big5" isErrorPage="true"%>

取得錯誤訊息的語法如下:
<%= exception.getMessage() %> 或 <%= exception.toString() %>

session 可設定是否使用session物件,預設是true,若某些頁面不需作進程追蹤,可以設成false,可以增加一些效能。
<%@page session="true|false"%>

 
isELIgnored 用以設定JSP網頁中是否忽略Expression Language,預設是false,如果設定為true,則Expression Language不會被轉譯,這個設定會推翻web.xml中的<el-ignored>設定,Expression Language在JSP 2.0成為標準規格之一。
 
isThreadSafe 決定轉譯之後的Servlet是否為執行緒安全的,預設值是true,如果設定為false,回應JSP網頁時,將產生新的行程,即轉譯之後的Servlet會實作SingleThreadModel 介面,這會引起效能問題,相當不建議這麼作。
<%@page isThreadSafe="true|false"%>

 

 

 ●  contentType v.s. pageEncoding

關於 contentType 和 pageEncoding 的差異 和 中文JSP頁的設定技巧:

contentType -- 指定的是JSP頁最終 Browser(客戶端)所見到的網頁內容的編碼.

就是 Mozilla的 Character encoding, 或者是 IE6的 encoding. 例如 JSPtw Forum 用的contentType就是 Big5.

pageEncoding -- 指定JSP編寫時所用的編碼
如果你的是 WIN98, 或 ME 的NOTEPAD記事本編寫JSP, 就一定是常用的是Big5 或 gb2312, 如果是用 WIN2k winXP的NOTEPAD時, SAVE時就可以選擇不同的編,碼, 包括 ANSI(BIG5/GB2312)或 UTF-8 或 UNIONCODE(估是 UCS 16).

因為 JSP要經過 兩次的"編碼", 第一階段會用 pageEncoding, 第二階段會用 utf-8 至utf-8, 第三階段就是由TOMCAT出來的網頁, 用的是contentType.

階段一 >>> 是 JSPC的 JSP至JAVA(.java)原碼的"翻譯", 它會跟據 pageEncoding 的設定讀取JSP. 結果是 由指定的 pageEncoding(utf-8,Big5,gb2312)的JSP 翻譯成統一的utf-8 JAVA原碼(.java). 如果pageEncoding設定錯了, 或沒設定(預設 ISO8859-1), 出來的 在這個階段 就已是中文亂碼.

階段二 >>> 是由 JAVAC的JAVA原碼至JAVA BYTECODE的編譯. 不論JSP的編寫時是用(utf-8,Big5,gb2312),經過階段一的結果全都是utf-8的ENCODING的JAVA原碼.
JAVAC 用 utf-8的ENCODING讀取AVA原碼, 編譯成字串是 utf-8 ENCODING的二進制碼(.class). 這是 JAVA VIRTUAL MACNHINE 對常數字串在 二進制碼(JAVA BYTECODE)內表?的規範.

階段三 >>> 是TOMCAT(或其的 application container)載入和執行 階段二得來的JAVA二進制碼, 輸出的結果( 也就是BROWSER(客戶端)) 見到的. 這時一早隱藏在階段一和二的參數contentType, 就發揮了功效.

<%@ page session="false" pageEncoding="big5" contentType="text/html; charset=utf-8" %>

**還有, pageEncoding 和contentType的預設都是 ISO8859-1. 而隨便設定了其中一個, 另一個就跟著一樣了(TOMCAT4.1.27是如此). 但這不是絕對, 看的各自JSPC的處理方式. 而pageEncoding不等於contentType, 更有利亞洲區的文字 CJKV系JSP網頁的開發和展示, (例pageEncoding=Big5 不等於 contentType=utf-8).

2. Include Directive 載入指令

◎ include 指令

 

在編譯時期包括(include)另一個網頁,或是在執行時期包括另一個網頁,是一種靜態的指定方式,而不能傳送參數,使用指令元素include的對象通常是一個靜態網頁。

<%@page contentType="text/html; charset=big5"%>
<%@include file="header.inc"%>
    <H1><B>include示範</B><H1>
<%@include file="foot.inc"%>

 

 ● <%@ include %> v.s. <jsp:include>

使用
<%@ include %> 主要是include靜態網頁
所包含的文件視為同一個,可真接拿來引用,例如說在a.jsp 定義String a="aaa";
在b.jsp用<%@ include %>把a.jsp 包含進來後,可視a.jsp跟b.jsp為同一份,所以不用再宣告String a(再宣告會有錯誤),可直接用a = "abcc";

<jsp:include> 可以include 動、靜態網頁
使用<jsp:include>則不行,需透過<jsp:param......的方式傳參數才可被引用,承上例,如果用<jsp:include>包含a.jsp,若直接打a = "abcc";,肯定出錯,因為他不把a.jsp跟b.jsp視為同一分文件

3. Taglib Directive 標籤資料庫指令

◎ taglib 指令

 屬性  說明
uri 用於說明 taglibrary 的存放位置。

<%@taglib uri="/supertags/"%>

prefix 用於區分多個自訂標籤。

<%@taglib prefix="super"%>
...
<super:doMagic>
...

</super:doMagic>

 

 

 


 

 

◎ Tag File ◎

在JSP 2.0之後,新增Tag File,它自身擁有tag、attrivute和variable三個指令元素,主要是讓網頁設計人員在不懂 Java 語法的情況下,也可使用自訂標籤。

Tag File通常是存放在WEB-INF/tags/目錄下,*.tag是Tag File建議的副檔名,也可以是*.tagx,Tag File也可以包括其它的Tag File。

 WEB-INF \ tags \ hello.tag
<table border="1">
   <tr><td>Hello! World!</td></tr>
</table>

 

 test.jsp
<%@taglib prefix="caterpillar" tagdir="/WEB-INF/tags" %>
<html>
<body>
  <caterpillar:hello/>
</body>
</html>

Tag File實際上會轉譯為Simple Tag,以Tomcat為例的話,您可以在 work\Catalina\localhost\myjsp\org\apache\jsp\tag\web 下找到轉譯之後的*.java與*.class檔案,名稱為hello_tag.java與hello_tag.class,是繼承 SimpleTagSupport的類別。

 work\Catalina\localhost\myjsp\org\apache\jsp\tag\web\hello_tag.java
package org.apache.jsp.tag.web;

import javax.servlet.*;
import javax.servlet.http.*;
import javax.servlet.jsp.*;

public final class hello_tag
    extends javax.servlet.jsp.tagext.SimpleTagSupport
    implements org.apache.jasper.runtime.JspSourceDependent {


  private static java.util.List _jspx_dependants;

  private JspContext jspContext;
  private java.io.Writer _jspx_sout;
  public void setJspContext(JspContext ctx) {
    super.setJspContext(ctx);
    java.util.ArrayList _jspx_nested = null;
    java.util.ArrayList _jspx_at_begin = null;
    java.util.ArrayList _jspx_at_end = null;
    this.jspContext = new org.apache.jasper.runtime.JspContextWrapper(ctx, _jspx_nested, _jspx_at_begin, _jspx_at_end, null);
  }

  public JspContext getJspContext() {
    return this.jspContext;
  }

  public Object getDependants() {
    return _jspx_dependants;
  }

  public void doTag() throws JspException, java.io.IOException {
    PageContext _jspx_page_context = (PageContext)jspContext;
    HttpServletRequest request = (HttpServletRequest) _jspx_page_context.getRequest();
    HttpServletResponse response = (HttpServletResponse) _jspx_page_context.getResponse();
    HttpSession session = _jspx_page_context.getSession();
    ServletContext application = _jspx_page_context.getServletContext();
    ServletConfig config = _jspx_page_context.getServletConfig();
    JspWriter out = jspContext.getOut();

    try {
      out.write("<table border=\"1\"> \r\n");
      out.write("   <tr><td>Hello! World!</td></tr> \r\n");
      out.write("</table>");
    } catch( Throwable t ) {
      if( t instanceof SkipPageException )
          throw (SkipPageException) t;
      if( t instanceof java.io.IOException )
          throw (java.io.IOException) t;
      if( t instanceof IllegalStateException )
          throw (IllegalStateException) t;
      if( t instanceof JspException )
          throw (JspException) t;
      throw new JspException(t);
    } finally {
      ((org.apache.jasper.runtime.JspContextWrapper) jspContext).syncEndTagFile();
    }
  }
}



在Tag File中可以使用out、config、request、response、session、application、jspContext等隱含物件,前六個的使用與JSP網頁中所使用的隱含物件是相同的,jspContext在轉譯之後,實際上則是JspContext物件。

在Tag File中可以使用<jsp:doBody>與<jsp:invoke>動作元素,前者是用來處理標籤本體文字,後者則是用來設定標籤間的Fragment。

<jsp:doBody>

 WEB-INF \ tags \ hello.tag
<%@attribute name="password"%> 

<% if(password.equals("1234")) { %>
<jsp:doBody/>
<% } else { %>
Password is wrong!
<% } %>

 

 test.jsp

<%@taglib prefix="caterpillar" tagdir="/WEB-INF/tags/" %>
<html>
<body>
 <caterpillar:check password="${ param.pwd }">
    Here is your sceret present!
 </caterpillar:check>
</body>
</html>

//密碼正確顯示 Here is your sceret present!,錯誤則顯示 Password is wrong!

 

<jsp:invoke>

 WEB-INF \ tags \ table.tag
<%@attribute name="frag1" fragment="true"%> 
<%@attribute name="frag2" fragment="true"%>
 
<table border="1">
   <tr>
       <td><b>frag1</b></td>
       <td><jsp:invoke fragment="frag1"/></td>
   </tr>
   <tr>
       <td><b>frag2</b></td>
       <td><jsp:invoke fragment="frag2"/></td>
   </tr>
</table>

 

 test.jsp

<%@taglib prefix="caterpillar" tagdir="/WEB-INF/tags/" %>
<html>
<body>
 <caterpillar:table>
    <jsp:attribute name="frag1">
        Fragment 1 here
    </jsp:attribute>
    <jsp:attribute name="frag2">
        Fragment 2 here
    </jsp:attribute>
 </caterpillar:table>
</body>
</html>

 

 

 WEB-INF \ tags \ precode.tag
<%@attribute name="preserve" fragment="true" %> 
<%@variable name-given="code" scope="NESTED" %>
 
<jsp:doBody var="code" />

<table border="1">
   <tr>
     <td>
        <pre><jsp:invoke fragment="preserve"/></pre>
     </td>
   </tr>
</table>

 

 test.jsp

<%@taglib prefix="caterpillar" tagdir="/WEB-INF/tags/" %>
<html>
<body>
 <caterpillar:precode>
    <jsp:attribute name="preserve">
       <b>${ code }</b>
   </jsp:attribute>
 
   <jsp:body>
 PROGRAM MAIN
    PRINT 'HELLO'
 END
   </jsp:body>
 </caterpillar:precode>
</body>
</html>

 

在Tag File中可以使用的指令元素有taglib、include、tag、attribute、variable五個,前兩者的使用方式與在JSP網頁中是相同的,tag指令則類似於JSP網頁中的page指令,用於指定與Tag File相關的屬性(像是pageEncoding、body-content等),attribute用以指定標籤的屬性,而variable用於設定 Tag File的Scripting Variable,以傳回JSP網頁中使用,後三者在下一個主題再介紹。

 

 

 

參考:良葛格學習筆記 JSP/Servlet

參考:[ JavaWorld@TW Java論壇 ] page指令:contentType VS. pageEncoding

參考:[ JavaWorld@TW Java論壇 ] 困擾我很久的include問題

創作者介紹
創作者 tsuozoe 的頭像
tsuozoe

隨便寫寫的新天地

tsuozoe 發表在 痞客邦 留言(1) 人氣()


留言列表 (1)

發表留言
  • hola
  • 感謝提供

    謝謝您無私的分享,