1. 程式人生 > >Jsp入門實戰上

Jsp入門實戰上

前面講了servlet入門實踐現在開始介紹jsp入門實踐,開發環境的搭建請參考我前面的tomcat的文章,jsp入門教程分為上下兩部分,第一部分簡單講解:jsp語法的規範,以及三大編譯指令,七個動作指令和九大內建物件,生命週期講解等。


全部程式碼下載:連結

1.jsp簡介:

JSP全名為Java Server Pages,中文名叫java伺服器頁面,其根本是一個簡化的Servlet設計,它[1] 是由Sun Microsystems公司倡導、許多公司參與一起建立的一種動態網頁技術標準。JSP技術有點類似ASP技術,它是在傳統的網頁HTML(標準通用標記語言的子集)檔案(.htm,

.html)中插入Java程式段(Scriptlet)和JSP標記(tag),從而形成JSP檔案,字尾名為(*.jsp)。 用JSP開發的Web應用是跨平臺的,既能在Linux下執行,也能在其他作業系統上執行。
第一個jsp程式:
1. 在eclipse中建立動態web工程
2. 在WebContent上右擊建立jsp檔案
3. 在jsp檔案中輸入如下:

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html> <head> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> <title>Insert title here</title> </head> <body> <% out.print("hello peace"); %> </body> </html>
  1. JSP作為servlet的變體,jsp的檔案會被翻譯成servlet檔案:檔案位置為Tomcat按住給你目錄:apache-tomcat-7.0.64/work/Catalina/localhost/stuJsp/org/apache/jsp
    02

    開啟java檔案可以看到該檔案根servlet的檔案類似:有_jspInit(),jspDestroy(),_jspService()方法。並將jsp檔案中的程式碼生成了_jspService()方法中的程式碼
    03

2.JSP語法:

2.1.JSP指令碼:

    指令碼程式,就是為了在HTML中穿插java程式碼,可以包含任意語法真確的java語句,變數,方法或表示式。生成servlet原始碼時該處的程式碼被放到_jspService()方法中
1. 指令碼程式的語法:
<% 程式碼片段 %>
就像第一個jsp程式那樣

<%
  out.print("hello peace");
%>
  1. 注意:指令碼中不能出現標籤和jsp元素,記住只能寫java就行;但是可以穿插寫:如下:
<%
  for(int i=0;i<5;i++)
  {
    out.print("hello peace"+i);
%>
  <br/>
 <%
   out.print("換行符穿插在中間了,一樣會被迴圈輸出");
  }//for迴圈結束
 %>

2.2.JSP宣告:

    一個宣告語句可以宣告一個或多個變數、方法,供後面的Java程式碼使用。在JSP檔案中,您必須先宣告這些變數和方法然後才能使用它們。生成servlet原始碼時該處的程式碼成為類的屬性和方法;
1. JSP宣告的語法:
<%! declaration; [ declaration; ]+ … %>
2. 演示如下:

<%! private int i=10; %> 
 <%!
    public void test(){
     int a=0;
     int b=2;
     a=a+b;
     System.out.print(a);
 }
 %>
  1. 檢視生成的servlet檔案可以知道剛才在jsp宣告的變數和方法,成為了相應的屬性和方法

2.3JSP表示式:

    一個JSP表示式中包含的指令碼語言表示式,先被轉化成String,然後插入到表示式出現的地方,作用相當於指令碼中的out(輸出)
由於表示式的值會被轉化成String,所以您可以在一個文字行中使用表示式而不用去管它是否是HTML標籤。
表示式元素中可以包含任何符合Java語言規範的表示式,但是不能使用分號來結束表示式。
生成servlet原始碼時該處的程式碼被放到_jspService()方法中
1. JSP表示式的語法格式
<%= 表示式 %>
2. 演示如下:

<%--在指令碼處宣告的變數是區域性變數不能帶有修飾符 --%>
    <%
      String nick="sisi";
      int a=10,b=10;
    %>
    3.jsp表示式:<br/>
    <%--表示式可以輸出相當於out.write 不需要分號結束--%>
      <%=(a-b) %>
      <%=nick %>
      <hr/>

2.4JSP註釋:

    JSP註釋不會出現在html的原始碼中 可以用來註釋jsp的程式碼,html註釋會出現在html的原始碼中;
1. JSP註釋的語法格式:
<%– 這裡可以填寫 JSP 註釋 –%>
2. 演示如下:

 1.jsp註釋:<br/>
  <%-- 這些註釋不會出現在html的原始碼中 可以用來註釋jsp的程式碼--%>

3.三大編譯指令:

JSP編譯指令用來設定與整個JSP頁面相關的屬性;
主要有三大編譯指令:

<%@ page ... %>    定義頁面的依賴屬性,比如指令碼語言、error頁面、快取需求等等
<%@ include ... %>    包含其他檔案
<%@ taglib ... %>    引入標籤庫的定義,可以是自定義標籤

3.1page指令介紹:

Page指令為容器提供當前頁面的使用說明。一個JSP頁面可以包含多個page指令。
1. Page指令的語法格式:
<%@ page attribute=”value” %>
2. 屬性:
04
3. 演示如下:

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

3.2include指令介紹:(靜態包含)

JSP可以通過include指令來包含其他檔案。被包含的檔案可以是JSP檔案、HTML檔案或文字檔案。包含的檔案就好像是該JSP檔案的一部分,會被同時編譯執行。
1. Include指令的語法格式如下:
<%@ include file=”url” %>
2. Include指令中的檔名實際上是一個相對的URL。如果您沒有給檔案關聯一個路徑,JSP編譯器預設在當前路徑下尋找。
3. 演示如下:

<%--  1.原理是把被包含的頁面(header.jsp)
的內容翻譯到包含頁面(index.jsp)中,合併成翻譯成一個java原始檔,
再編譯執行!!,這種包含叫靜態包含(原始碼包含)
  2.被包含頁面中不需要出現全域性的html標籤了!!!
(如html、head、body)--%>
<%@include file="/common/header.jsp"%>

3.3taglib指令介紹:

JSP API允許使用者自定義標籤,一個自定義標籤庫就是自定義標籤的集合。Taglib指令引入一個自定義標籤集合的定義,包括庫路徑、自定義標籤。
1. taglib指令的語法:
<%@ taglib uri=”uri” prefix=”prefixOfTag” %>
2. uri為屬性確定的標籤位置,prefix屬性指定標籤庫的字首。此處後面會進一步介紹;
3. 演示如下:

自己定義的標籤庫
<%@ taglib uri="http://rlovep.com" prefix="rlovep" %>

4.七大動作指令介紹:

動作指令與編譯指令不同,編譯指令時通知servlet引擎的處理訊息,而動作指令只是執行時的動作。編譯指令在將JSP編譯成Servlet時起作用,而處理指令通常可替換成JSP指令碼,它只是JSP指令碼的標準化寫法。
(1)JSP:forward 執行頁面轉向,將請求的處理轉發到下一個頁面。
(2)JSP:param 用於傳遞引數,必須與其他支援引數的標籤一起使用
(3)JSP:include 用於動態引入一個JSP頁面
(4)JSP:plugin 用於下載JavaBean或者Applet到客戶端執行
(5) JSP:useBean 建立一個Javabean例項
(6) JSP:setProperty 設定JavaBean例項的屬性值
(7)JSP:getProperty 獲取JavaBean例項的屬性值

4.1jsp:forward指令 

jsp:forward動作把請求轉到另外的頁面。jsp:forward標記只有一個屬性page。
1. 語法格式如下所示:

2. page屬性:page屬性包含的是一個相對URL。page的值既可以直接給出,也可以在請求的時候動態計算,可以是一個JSP頁面或者一個 Java Servlet.
3. 執行forward指令時,使用者請求的地址依然沒有發生改變,仍然是一次請求,但頁面內容完全變為被forward目標頁的內容。執行forward指令轉發請求時,客戶端的請求引數不會丟失。類似於servlet中的
getRequestDispatcher(“/GetData”).forward(request, response);
4. 可以附帶增加額外的請求引數:配合JSP:param動作指令

<%--轉發 jsp:foward
    引數 jsp:param
<jsp:forward page="/action2.jsp">
    <jsp:param value="peace" name="name"/>
    <jsp:param value="123456" name="pass"/>
</jsp:forward>
--%>

4.2jsp:include指令(動態包含)

jsp:include>動作元素用來包含靜態和動態的檔案。該動作把指定檔案插入正在生成的頁面
1. 語法格式如下:

2. 前面介紹過include的編譯指令與前面不同的是這裡的是動態包含,靜態包含是在JSP檔案被轉換成Servlet的時候引入檔案,而這裡的jsp:include動作不同,插入檔案的時間是在頁面被請求的時候。如果被包含的頁面是jsp一樣會另一個生成servlet;
3. 屬性介紹:
page:被包含頁面的url
flush:布林屬性,定義在包含資源前是否重新整理快取區。
4. 可以附帶增加額外的請求引數:配合JSP:param動作指令

<%--動態包括 --%>
動態包括:
<jsp:include page="/common/header1.jsp">
     <jsp:param value="lucc" name="name"/>
</jsp:include>

05

4.3jsp:userBean,setProperty,getProperty指令

這三個指令都是與JavaBean相關的指令,其中userBean指令用於在JSP頁面中初始化一個java例項,setProperty指令用於為JavaBean例項的屬性設定值;getProperty指令用於輸出JavaBean例項的屬性。
1. jsp:useBean動作簡單的語法為:

其中,id屬性是JavaBean的例項名,class屬性確定JavaBean的實現類。scope屬性用於指定JavaBean例項的作用範圍。
2. jsp:setProperty的語法格式:

其中,name屬性是要確定JavaBean的例項名,property屬性要確定設定屬性的屬性名,value屬性時要確定屬性名對應的值。
3. jsp:getProperty的語法格式:

其中,name屬性時要確定JavaBean的例項名,name屬性是指定要獲取的屬性名對應的值。
4. 演示如下:

<%--useBean setProperty getProperty --%>
<%--建立Student的例項 
例項名稱為student
屬性範圍為page
--%>
<hr/>
<jsp:useBean id="student" class="com.rlovep.entity.Student" scope="page"/>
<%--設定student的name值 --%>
<jsp:setProperty name="student" property="name" value="peace"/>
<%--輸出 student的name值--%>
name:<jsp:getProperty name="student" property="name" />

4.3jsp:param,plugin指令

param用於設定引數值,這個指令本身不能單獨使用,因此單獨的param指令沒有實際意義,param指令可以與以下指令結合使用
jsp:include jsp:forward jsp:plugin。使用方法上面已經介紹;
plugin指令主要用於下載伺服器端的JavaBean或Applet到到客戶端執行,由於程式在客戶端執行,因此客戶端必須安裝虛擬機器。該指令用處較少,不做介紹;

4.4整體演示如下:

需要建立,action.jsp本檔案,以級轉發頁面action2.jsp,被包含頁面/common/header1.jsp,JavaBean:Student類

<%--轉發 jsp:foward
    引數 jsp:param
<jsp:forward page="/action2.jsp">
    <jsp:param value="peace" name="name"/>
    <jsp:param value="123456" name="pass"/>
</jsp:forward>
--%>
<%--動態包括 --%>
動態包括:
<jsp:include page="/common/header1.jsp">
     <jsp:param value="lucc" name="name"/>
</jsp:include>
<%--useBean setProperty getProperty --%>
<%--建立Student的例項 
例項名稱為student
屬性範圍為page
--%>
<hr/>
<jsp:useBean id="student" class="com.rlovep.entity.Student" scope="page"/>
<%--設定student的name值 --%>
<jsp:setProperty name="student" property="name" value="peace"/>
<%--輸出 student的name值--%>
name:<jsp:getProperty name="student" property="name" />

5. 9大內建物件介紹

JSP指令碼中包含9個內建物件,這9個內建物件都是Servlet API介面的例項,只是JSP規範對他們預設進行了初始化(由JSP頁面對應的Servlet的_jspService()方法來建立這些例項)。也就是它們已經是物件,可以直接使用。
06
JSP初始化該9個物件的地方可以通過生成的servlet類看到如下:
07
request、response兩個物件是_jspService()方法的形參,當Tomcat呼叫該方法時會初始化這兩個物件。而page、pageContext、application、config、session、out都是_jspService()方法的區域性變數,由該方法完成初始化。

5.1稍簡單再介紹:詳細介紹可以觀看我的Servlet入門實踐

  1. application:javax.servlet.ServletContext的例項,該例項代表JSP所屬的Web應用本身,可用於JSP頁面,或者在Servlet之間交換資訊。常用的方法有getAttribute(StringattName)、setAttribute(String attName , String attValue)和getInitParameter(StringparamName)等。
  2. config:javax.servlet.ServletConfig的例項,該例項代表該JSP的配置資訊。常用的方法有getInitParameter(StringparamName)和getInitParameternames()等方法。事實上,JSP頁面通常無須配置,也就不存在配置資訊。因此,該物件更多地在Servlet中有效。
  3. exception:java.lang.Throwable的例項,該例項代表其他頁面中的異常和錯誤。只有當頁面是錯誤處理頁面,即編譯指令page的isErrorPage屬性為true時,該物件才可以使用。常用的方法有getMessage()和printStackTrace()等。
  4. out:javax.servlet.jsp.JspWriter的例項,該例項代表JSP頁面的輸出流,用於輸出內容,形成HTML頁面。
  5. page:代表該頁面本身,通常沒有太大用處。也就是Servlet中的this,其型別就是生成的Servlet類,能用page的地方就可用this。
  6. pageContext:javax.servlet.jsp.PageContext的例項,該物件代表該JSP頁面上下文,使用該物件可以訪問頁面中的共享資料。常用的方法有getServletContext()和getServletConfig()等。這個物件儲存了request物件和response物件的引用。application物件,config物件,session物件,out物件可以通過訪問這個物件的屬性來匯出。PageContext類定義了一些欄位,包括PAGE_SCOPE,REQUEST_SCOPE,SESSION_SCOPE, APPLICATION_SCOPE。它也提供了40餘種方法,有一半繼承自javax.servlet.jsp.JspContext 類。其中一個重要的方法就是removeArribute(),它可接受一個或兩個引數。比如,pageContext.removeArribute(“attrName”)移除四個scope中相關屬性,但是下面這種方法只移除特定scope中的相關屬性:
    pageContext.removeAttribute(“attrName”, PAGE_SCOPE);
  7. request:javax.servlet.http.HttpServletRequest的例項,該物件封裝了一次請求,客戶端的請求引數都被封裝在該物件裡。這是一個常用的物件,獲取客戶端請求引數必須使用該物件。常用的方法有getParameter(String paramName)、getParameterValues(StringparamName)、setAttribute(String 8. 8/ attrName,Object attrValue)、getAttribute(StringattrName)和setCharacterEncoding(String env)等。
  8. response:javax.servlet.http.HttpServletResponse的例項,代表伺服器對客戶端的響應。通常很少使用該物件直接響應,而是使用out物件,除非需要生成非字元響應。而response物件常用於重定向,常用的方法有getOutputStream()、sendRedirect(java.lang.String location)等。
  9. session:javax.servlet.http.HttpSession的例項,該物件代表一次會話。當客戶端瀏覽器與站點建立連線時,會話開始;當客戶端關閉瀏覽器時,會話結束。常用的方法有:getAttribute(String attrName)、setAttribute(StringattrName, Object attrValue)等。

5.2四個域物件:

  1. 四個域物件:
    pageContext——– page域
    request ——– request域
    session——– session域
    application ——–context域
  2. 域物件作用:
    儲存資料 和 獲取資料 ,用於資料共享。
  3. 域物件方法:
    setAttribute(“name”,Object) 儲存資料
    getAttribute(“name”) 獲取資料
    removeAttribute(“name”) 清除資料
  4. 域物件作用範圍:
    page域: 只能在當前jsp頁面中使用(當前頁面)
    request域: 只能在同一個請求中使用(轉發)
    session域: 只能在同一個會話(session物件)中使用(私有的)
    context域: 只能在同一個web應用中使用。(全域性的)

5.3 整體演示如下:

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"
    %>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Insert title here</title>
</head>
<body>
<%--out物件:對應jspwriter
 --%>
<%
  /* for(int i=0;i<=1024;i++){
      out.write("a");
  }
System.out.println("當前快取區大小:"+out.getBufferSize());
System.out.println("剩餘快取區大小:"+out.getRemaining()); */
//如果不重新整理則,123先輸出;
//out.flush();
response.getWriter().write("123");
%>
<%--
application物件:對應servlet中的context
儲存的屬性,是整個應用共享的;同樣可以獲得配置引數;
 --%>
<%
//儲存屬性
application.setAttribute("name", "peace");
%>
<%=application.getInitParameter("keys") %>
<%--
config物件:對應servlet中的config
用處不是很大
 --%>
 <%=config.getServletName() %>
 <%--
exception物件:在錯誤頁面中有效,可以獲得異常屬性
親發生錯誤:該物件只有當編譯指令page的isErrorPage="true"才有效
<%=exception.getMessage() %>
 --%>
 <%--
request物件:對應servlet中的request
 --%>
 <%=request.getLocalName() %>
 <%--
response物件:對應servlet中的response
 --%>
<%
    response.getWriter().println("hello respose");
%>
<%--
session物件:對應servlet中的session
 --%>
 <%
    session.setAttribute("pass", "567");
 %>
 <%--
pagecontext物件:jsp的頁面物件
可以獲得其他八個物件:
 --%>
 <%
    //獲得其他物件
    response.getWriter().write("是否相等?"+(out==pageContext.getOut())+"<br/>");
 %>
 <%--可以往不同的域中存物件 --%>
 <%
    pageContext.setAttribute("message", "wang");
    pageContext.setAttribute("age", "22", PageContext.REQUEST_SCOPE);
    pageContext.setAttribute("qq", "374126165", pageContext.SESSION_SCOPE);
    pageContext.setAttribute("tl","1881679",pageContext.APPLICATION_SCOPE);
    //重定向到另一個頁面取得資料:
    response.sendRedirect(request.getContextPath()+"/pageget.jsp");
    //刪除儲存的物件
    pageContext.removeAttribute("age",PageContext.REQUEST_SCOPE );
 %> 
</body>
</html>

6.JSP生命週期講解:

理解JSP底層功能的關鍵就是去理解它們所遵守的生命週期。JSP生命週期就是從建立到銷燬的整個過程,類似於servlet生命週期,區別在於JSP生命週期還包括將JSP檔案編譯成servlet。

6.1JSP執行過程:

訪問:http://localhost:8080/工程名/NewFile.jsp
1. 訪問到NewFile.jsp頁面,tomcat掃描到jsp檔案,在/work/Catalina/localhost/stuJsp/org/apache/jsp把jsp檔案翻譯成java原始檔
(NewFile.jsp -> NewFile_jsp.java) (翻譯)
2. tomcat伺服器把java原始檔編譯成class位元組碼檔案 (編譯)
(NewFile_jsp.java ->NewFile_jsp.class)
3. tomcat伺服器構造NewFile_jsp類物件
4. tomcat伺服器呼叫NewFile_jsp類裡面方法,返回內容顯示到瀏覽器。

第一次訪問jsp:走(1)(2)(3)(4)
之後的訪問:走(4)
注意:jsp檔案修改了或jsp的臨時檔案被刪除了,要重新走翻譯(1)和編譯(2)的過程

6.2JSP生命週期:

  1. JSP編譯:
    當瀏覽器請求JSP頁面時,JSP引擎會首先去檢查是否需要編譯這個檔案。如果這個檔案沒有被編譯過,或者在上次編譯後被更改過,則編譯這個JSP檔案。編譯為servlet;
  2. JSP初始化:
    容器載入JSP檔案後,它會在為請求提供任何服務前呼叫jspInit()方法。你可以重寫該方法:在jsp宣告段
<%! 
public void jspInit(){
    initVar++;
   System.out.println("jspInit(): JSP被初始化了"+initVar+"次");
}
%>
  1. JSP執行:
    這一階段描述了JSP生命週期中一切與請求相關的互動行為,直到被銷燬。每一次服務請求都會執行_jspService()方法。
  2. JSP清理:
    JSP生命週期的銷燬階段描述了當一個JSP網頁從容器中被移除時所發生的一切,一般只有在容器停止部署該工程才執行:jspDestroy()方法 你可以進行重寫
<%!
 public void jspDestroy(){ 
          destroyVar++;   
        System.out.println("jspDestroy(): JSP被銷燬了"+destroyVar+"次"); 
  } %>
  1. JSP與servlet的生命週期對比
Servlet的生命週期:
    1)構造方法(第1次訪問)
    2)init方法(第1次訪問)
    3)service方法
    4)destroy方法
Jsp的生命週期:
    1)翻譯: jsp->java檔案
    2)編譯: java檔案->class檔案(servlet程式)
    3)構造方法(第1次訪問)
    4)init方法(第1次訪問):_jspInit()
    5)service方法:_jspService()
    6)destroy方法:_jspDestroy()

6.3演示如下:

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Insert title here</title>
</head>
<body>
<%! 
  //記錄執行次數:
  private int initVar=0;
  private int serviceVar=0;
  private int destroyVar=0;
%>
<%!
  public void jspInit(){
    initVar++;
    System.out.println("jspInit(): JSP被初始化了"+initVar+"次");
  }
  public void jspDestroy(){
    destroyVar++;
    System.out.println("jspDestroy(): JSP被銷燬了"+destroyVar+"次");
  }
%>
<%
  serviceVar++;//
  System.out.println("_jspService(): JSP共響應了"+serviceVar+"次請求");
  //對各個的執行次數計數
  String content1="初始化次數 : "+initVar;
  String content2="響應客戶請求次數 : "+serviceVar;
  String content3="銷燬次數 : "+destroyVar;
%>
<%-- 輸出顯示 --%>
<h1><%=content1 %></h1>
<h1><%=content2 %></h1>
<h1><%=content3 %></h1>
</body>
</html>

顯示如下:
08
來自一條小鯊魚wpeace(rlovep.com)