1. 程式人生 > 其它 >JSP+EL+JSTL

JSP+EL+JSTL

JSP

java server page:java伺服器端頁面。其實就是一個特殊的頁面,其中即可以寫html文件,又可以寫java程式碼。JSP本質上就是一個Servlet
JSP的工作模式是請求/響應模式,客戶端首先發出HTTP請求,JSP程式收到請求後進行處理並返回處理結果。在一個JSP檔案第1次被請求時,JSP引擎(容器)把該JSP檔案轉換成為一個Servlet,而這個引擎本身也是一個Servlet。

像這種將前後端程式碼合在一起的技術成為模板引擎. Java常用的模板引擎除了 jsp 之外還有 Freemarker 和 Beetl.

使用

  1. JSP指令碼元素:是指巢狀在<%和%>之中的一條或多條Java程式程式碼。主要包括以下三種類型:

    1. JSP指令碼<% 程式碼 %>:這裡寫的程式碼會被放在service方法中,裡面定義的變數都是區域性變數。

    2. JSP宣告<%! 程式碼 %>:用於在JSP頁面中定義全域性的變數或方法,是Servlet的成員變數或成員方法。

    3. JSP表示式<%= 程式碼 %>:可以是任何Java語言的完整表示式。該表示式的最終運算結果將被轉換為字串並輸出到頁面上。相當於 out.println()

      <body>
          計算3/2=<%= 3/2 %> <%-- JSP表示式不僅可以插入網頁的文字中,用於輸出文字內容,也可以插入HTML標記中,用於動態設定屬性值。--%>
      </body>
      
  2. 註釋

    1. JSP註釋:<%-- --%> 伺服器端註釋,解析時將跳過這些程式碼,在客戶端是檢視原始碼是看不到這些註釋的。
    2. html註釋:客戶端註釋,瀏覽器檢視原始碼是可以看到這些註釋的。
  3. JSP指令:用來設定JSP頁面中的一些資訊

    1. page指令:用來對頁面的某些特性進行描述,如:頁面的編碼方式、JSP 頁面採用的語言等
      格式:<%@ page 屬性名1= "屬性值1" 屬性名2= "屬性值2" ...%>
      page指令常見屬性:

      注意:除了import屬性外,其他的屬性都只能出現一次,否則會編譯失敗。同時page指令的屬性名稱都是區分大小寫的。

      <%@ page contentType="text/html;charset=UTF-8" language="java"  pageEncoding="utf-8" %>
      
    2. include指令:在實際開發時,有時需要在JSP頁面靜態包含一個檔案,例如HTML檔案、JSP等,這時,可以通過include指令來實現。不過該指令是靜態包含,也就是說被包含檔案中所有內容會被原樣包含到該JSP頁面中,即使被包含檔案中有JSP程式碼,在包含時也不會被編譯執行。使用include指令,最終將生成一個檔案,所以在被包含和包含的檔案中,不能有相同名稱的變數。
      格式:<%@ include file="被包含的檔案地址"%>
      注意:在應用include指令進行檔案包含時,為了使整個頁面的層次結構不發生衝突,建議在被包含頁面中將<html>、<body>等標記刪除。因為在包含該頁面的文件中已經指定了這些標籤。
      top.jsp:

      <%@ page contentType="text/html;charset=UTF-8" language="java" %>
      <div style="background-color: antiquewhite;color: blue;font-size: x-large"><%="這是標題"%>></div>
      <!-- 使用include,兩個頁面的page指令必須一樣-->
      

      index.jsp:

      <%@ page contentType="text/html;charset=UTF-8" pageEncoding="UTF-8" %>
      <!DOCTYPE html>
      <html>
      <head>
          <title>Hello World</title>
      </head>
      <body>
      <%@include file="top.jsp"%>
      <h1><%= "Hello World!" %>
      </h1>
      <br/>
      <a href="hello-servlet">Hello Servlet</a>
      </body>
      </html>
      
      
    3. taglib:用來匯入外部標籤庫。<%taglib uri="" prefix=""%>

  4. 動作標識

    1. 包含檔案標識<jsp:include>用於向當前頁面中包含其他的檔案。被包含的檔案可以是動態檔案,也可以是靜態檔案。
      格式:<jsp:Include page=“url” flush=“false|true”/>

      1. <jsp:include>和include指令的比較
        1. include指令通過file屬性指定被包含的檔案,並且file屬性不支援任何表示式;<jsp:include>動作標識通過page屬性指定被包含的檔案,而且page屬性支援JSP表示式。
        2. 使用include指令時,被包含的檔案內容會原封不動地插入包含頁中,然後JSP編譯器再將合成後的檔案最終編譯成一個Java檔案;使用<jsp:include>動作標識包含檔案時,當該標識被執行時,程式會將請求轉發(注意是轉發,而不是請求重定向)到被包含的頁面,並將執行結果輸出到瀏覽器中,然後返回包含頁繼續執行後面的程式碼。因為伺服器執行的是多個檔案,所以JSP編譯器會分別對這些檔案進行編譯。
        3. 在應用include指令包含檔案時,由於被包含的檔案最終會生成一個檔案,所以在被包含檔案、包含檔案中不能有重名的變數或方法;而在應用<jsp:include>動作標識包含檔案時,由於每個檔案是單獨編譯的,所以在被包含檔案和包含檔案中重名的變數和方法是不相沖突的。
    2. 請求轉發標識<jsp:forword>:可以將請求轉發到其他的Web資源,例如,另一個JSP頁面、HTML頁面、Servlet等。
      格式:<jsp:forward page="url" />

    3. 引數傳遞標識<jsp:param>:可以作為其他標識的子標識,用於為其他標識傳遞引數。
      格式:<jsp:param name="引數名" value="值">

      <jsp:forward page="login.jsp" />
      	<jsp:param name="username" value="zhangsan" />
      </jsp:forward>
      

      通過<jsp:param>動作標識指定的引數,將以“引數名=值”的形式加入請求中。它的功能與在檔名後面直接加“?引數名=引數值一樣。

9個內建物件

JSP提供了一些內建物件,不需要例項化就可以直接使用

  1. out:字元輸出流物件。可以將資料輸出到頁面上,和resp.getWriter()類似。
    resp.getWriter()和out.write()的區別:在tomcat伺服器真正給客戶端做出響應之前,會先找resp緩衝區資料,再找out緩衝區資料。所以resp.getWriter()資料輸出永遠在out.write()之前

    out物件提供了print()和println()兩種向頁面中輸出資訊的方法。不過使用println方法在頁面中看不到換行的效果。out.println()相當於<%= %>

  2. page:代表當前JSP頁面本身,本質是包含當前Servlet介面引用的變數,可以看作是this關鍵字的別名。
    page物件常用方法

  3. exception:用來處理JSP檔案執行時發生的所有錯誤和異常。只有在page指令中設定為isErrorPage屬性值為true的頁面中才可以被使用,在一般的JSP頁面中使用該物件將無法編譯JSP檔案。
    exception物件幾乎定義了所有異常情況,在Java程式中,可以使用try...catch關鍵字來處理異常情況,如果在JSP頁面中出現沒有捕捉到的異常,就會生成exception物件,並把exception物件傳送到在page指令中設定的錯誤頁面中,然後在錯誤頁面中處理相應的exception物件。
    index.jsp頁面產生錯誤,並傳遞給error.jsp

    <%@ page import="java.util.Date" %>
    <%@ page import="java.text.SimpleDateFormat" %>
    <%@ page contentType="text/html;charset=UTF-8" pageEncoding="UTF-8" errorPage="error.jsp" %>
    <!DOCTYPE html>
    <html>
    <head>
        <title>Hello World</title>
    </head>
    <body>
    <%
        String str = "100元";
        Float price = Float.parseFloat(str);
    %>
    </body>
    </html>
    

    在error.jsp列印錯誤資訊

    <%@ page contentType="text/html;charset=UTF-8" language="java" isErrorPage="true" %>
    <html>
    <head>
    </head>
    <body>
    <%=exception.getMessage() %>
    </body>
    </html>
    
    
  4. PageContext:jsp獨有的,Servlet中沒有。是四大域物件(應用域ServletContext、會話域HttpSession、請求域ServletRequest、PageContext)之一的頁面域物件,還可以操作其他三個域物件中的屬性。生命週期和隨著jsp的建立而存在,隨著jsp的結束而消失。
    常用方法:

    父類JspContext的方法

案例:使用JSP獲取上次訪問頁面的時間

<%@ page import="java.util.Date" %>
<%@ page import="java.text.SimpleDateFormat" %>
<%@ page contentType="text/html;charset=UTF-8" pageEncoding="UTF-8" %>
<!DOCTYPE html>
<html>
<head>
</head>
<body>
<%
    long lastAccessedTime = session.getLastAccessedTime();//獲取上次訪問時間的毫秒數
    Date date = new Date();
    date.setTime(lastAccessedTime);//將毫秒數轉成日期物件
    SimpleDateFormat sdf = new SimpleDateFormat("yyyy/MM/dd HH:mm:ss");
    String str_date = sdf.format(date);//格式化日期物件
%>
<%= str_date%>
</body>
</html>

JSP最佳實戰-MVC模型

MVC模式:model + view + controller 模型+檢視+控制器,是一種軟體設計典範。

M:model,通常用於封裝資料。具體的方法由普通的Java類實現, 一般起名為 xxxService. 如果要進行持久化儲存, 還需要 dao 和 bean, 以便於和資料庫互動.

V:view ,通常用於展示資料。動態展示用jsp頁面,靜態資料展示用html。

C:controller ,通常用於處理請求和響應。一般指的是Servlet。

JavaBean

Java規定了標準的類定義格式,符合這種格式的Java類就是一個JavaBean。要求如下:

  1. 所有屬性為private
  2. 提供公共的無參構造方法
  3. 提供getter和setter
  4. 實現serializable介面

JavaBean在Java EE開發中,通常用於封裝資料,對於遵循以上寫法的JavaBean元件,其它程式可以通過反射技術例項化JavaBean物件(內省機制),並且通過反射那些遵循命名規範的方法,從而獲知JavaBean的屬性,進而呼叫其屬性儲存資料。

所以符合JavaBean規範的類,就算成員變數是私有的,也可以直接使用物件名.屬性名修改。大大簡化了jsp的程式碼。

EL

Expression Language表示式語言。用來替換和簡化jsp頁面中java程式碼的編寫。

語法:${表示式}。注意EL用在jsp的java程式碼中,jQuery用在JavaScript中。

使用

獲取四大域中的資料
找到了就輸出,沒找到就空著,不會輸出null,比較美觀。

  1. el表示式只能從域物件中獲取值

  2. ${域名稱.鍵名}:從指定域中獲取指定鍵的值
    pageScope --> pageContext
    requestScope --> request
    sessionScope --> session
    applicationScope --> application(ServletContext)

  3. ${鍵名}:表示依次從最小的域中查詢是否有該鍵對應的值,直到找到為止。

  4. 獲取引數:${param.引數名} param是EL內建的物件

  5. 獲取物件、List集合、Map集合的值

    1. 物件:${域名稱.物件名.屬性名}

      package com.example.JSPDemo;//定義一個JavaBean類
      public class Person {   
          private String name;//屬性都是私有的    
          private Date birthday;    
          public Person(){} //提供無參構造   
          //getter、setter略    
          //成員方法    
          public String getInfo() {        
              SimpleDateFormat sdf = new SimpleDateFormat("yyyy/MM/dd HH:mm:ss");       
              return name + "出生於:"+sdf.format(birthday) ; }
      }
      
      <%@ page import="com.example.JSPDemo.Person" %>
      <%@ page import="java.util.Date" %>
      <%@ page contentType="text/html;charset=UTF-8" language="java" %>
      <html>
          <head>
          </head>
          <body>
              <%    //先使用java程式碼建立一個物件,再儲存到域物件中,就可以使用EL表示式來訪問了   
              Person person = new Person();    
              person.setBirthday(new Date());   
              person.setName("zhangsan");    
              request.setAttribute("p",person);//這一步是必需的,物件必須儲存到域中,才可以用EL來訪問    %>
              ${p.name}<br/>
              ${p.birthday}<br/>
              ${p.info}<br/><%--像訪問屬性一樣呼叫方法,注意去掉方法名前的get、set,然後名稱一律小寫,直接呼叫--%>
          </body>
      </html>
      
    2. List集合:${域名稱.集合名[索引]}

    3. Map集合:${域名稱.集合名.key}或${域名稱.集合名["key"]}

運算子

<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>
<%@ page import="com.itheima.domain.User" %>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
	<head>
		<title>EL兩個特殊的運算子</title>
	</head>
	<body>
		<%--空運算子: empty
            功能:用於判斷字串、集合、陣列物件是否為null或者長度是否為0
            ${empty list}:判斷字串、集合、陣列物件是否為null或者長度為0
            ${not empty str}:表示判斷字串、集合、陣列物件是否不為null 並且 長度>0
		--%>
		<% String str = null;
		  String str1 = "";
		  List<String> slist = new ArrayList<String>();
		  pageContext.setAttribute("str", str);
		  pageContext.setAttribute("str1", str1);
		  pageContext.setAttribute("slist", slist);
		%>
		${empty str}============當物件為null返回true<br/>
		${empty str1 }==========當字串為空字串是返回true(注意:它不會呼叫trim()方法)<br>
		${empty slist}==========當集合中的元素是0個時,是true
		<hr/>
		<%--三元運算子 
			 條件?真:假
		--%>
		<% request.setAttribute("gender", "female"); %>
		<input type="radio" name="gender" value="male" ${gender eq "male"?"checked":""} >男
		<input type="radio" name="gender" value="female" ${gender eq "female"?"checked":""}>女
	</body>
</html>

11個內建物件

EL表示式也為我們提供隱式物件,可以讓我們不宣告直接來使用,十一個物件見下表,需要注意的是,它和JSP的隱式物件不是一回事:

EL中的隱式物件 型別 對應JSP隱式物件 備註
PageContext Javax.serlvet.jsp.PageContext PageContext 完全一樣
ApplicationScope Java.util.Map application 應用層範圍
SessionScope Java.util.Map session 會話範圍
RequestScope Java.util.Map request 請求範圍
PageScope Java.util.Map 沒有 頁面層範圍
Header Java.util.Map 沒有 請求訊息頭key,值是value(一個)
HeaderValues Java.util.Map 沒有 請求訊息頭key,值是陣列(一個頭多個值)
Param Java.util.Map 沒有 請求引數key,值是value(一個)
ParamValues Java.util.Map 沒有 請求引數key,值是陣列(一個名稱多個值)
InitParam Java.util.Map 沒有 全域性引數,key是引數名稱,value是引數值
Cookie Java.util.Map 沒有 Key是cookie的名稱,value是cookie物件

注意:jsp和EL的pageContext物件其實就是同一個物件。

注意

EL沒有空指標異常、沒有索引越界異常、沒有字串拼接的效果

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
  <head>
    <title>EL表示式的注意事項</title>
  </head>
  <body>
    <%--EL表示式的三個沒有--%>
    第一個:沒有空指標異常<br/>
    <% String str = null;
       request.setAttribute("testNull",str);
    %>
    ${testNull}
    <hr/>
    第二個:沒有陣列下標越界<br/>
    <% String[] strs = new String[]{"a","b","c"};
       request.setAttribute("strs",strs);
    %>
    取第一個元素:${strs[0]}
    取第六個元素:${strs[5]}
    <hr/>
    第三個:沒有字串拼接<br/>
    <%--${strs[0]+strs[1]}--%>
    ${strs[0]}+${strs[1]}
  </body>
</html>

JSTL

JSP tag library JSP標準標籤庫,用於簡化和替換jsp頁面上的java程式碼。由以下5個部分組成:

組成 作用 說明
Core 核心標籤庫。 通用邏輯處理
Fmt 國際化有關。 需要不同地域顯示不同語言時使用
Functions EL函式 EL表示式可以使用的方法
SQL 操作資料庫。 不用
XML 操作XML。 不用

使用步驟:

  1. 匯入jstl相關jar包
  2. 引入標籤庫:taglib指令:<%@ taglib prefix="c" uri="http://java.sun.com/jstl/core" %>
  3. 使用標籤

核心標籤庫

  1. if:相當於java程式碼的if語句

    1. 屬性:
      • test 必須屬性,接受boolean表示式
        • 如果表示式為true,則顯示if標籤體內容,如果為false,則不顯示標籤體內容
        • 一般情況下,test屬性值會結合el表示式一起使用
      1. 注意:c:if標籤沒有else情況,想要else情況,就再定義一個c:if
  2. choose:相當於java程式碼的switch語句

    1. 使用choose標籤宣告 相當於switch宣告
    2. 使用when標籤做判斷 相當於case
    3. 使用otherwise標籤做其他情況的宣告 相當於default
  3. foreach:相當於java程式碼的for語句

<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>
<%--匯入jstl標籤庫 --%>
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
  <head>
    <title>JSTL的常用標籤</title>
  </head>
  <body>
    <%-- c:if  c:choose   c:when c:otherwise --%>
    <% pageContext.setAttribute("score","F"); %>
    <c:if test="${pageScope.score eq 'A' }">
    	優秀
    </c:if>
    <c:if	test="${pageScope.score eq 'C' }">
    	一般
    </c:if>
    <hr/>
    <c:choose>
    	<c:when test="${pageScope.score eq 'A' }">
    		AAA
    	</c:when>
    	<c:when test="${pageScope.score eq 'B' }">BBB
    	</c:when>
    	<c:when test="${pageScope.score eq 'C' }">CCC
    	</c:when>
    	<c:when test="${pageScope.score eq 'D' }">DDD
    	</c:when>
    	<c:otherwise>其他</c:otherwise>
    </c:choose>
    
    <%-- c:forEach 它是用來遍歷集合的
    	 屬性:
    	 	items:要遍歷的集合,它可以是EL表示式取出來的
    	 	var:把當前遍歷的元素放入指定的page域中。 var的取值就是key,當前遍歷的元素就是value
    	 		注意:它不能支援EL表示式,只能是字串常量
    	 	begin:開始遍歷的索引
    	 	end:結束遍歷的索引
    	 	step:步長。i+=step
    	 	varStatus:它是一個計數器物件。裡面有兩個屬性,一個是用於記錄索引。一個是用於計數。
    	 			   索引是從0開始。計數是從1開始
    --%>
    <hr/>
    <% List<String> list = new ArrayList<String>();
       list.add("AAA");
       list.add("BBB");
       list.add("CCC");
       list.add("DDD");
       list.add("EEE");
       list.add("FFF");
       list.add("GGG");
       list.add("HHH");
       list.add("III");
       list.add("JJJ");
       list.add("KKK");
       list.add("LLL");
       pageContext.setAttribute("list",list);
     %>
	<c:forEach items="${list}" var="s" begin="1" end="7" step="2">
    	${s}<br/>
    </c:forEach>
    <hr/>
    <c:forEach begin="1" end="9" var="num">
    	<a href="#">${num}</a>
    </c:forEach>
    <hr/>
    <table>
    	<tr>
    		<td>索引</td>
    		<td>序號</td>
    		<td>資訊</td>
    	</tr>
    <c:forEach items="${list}" var="s" varStatus="vs">
    	<tr>
    		<td>${vs.index}</td>
    		<td>${vs.count}</td>
    		<td>${s}</td>
    	</tr>
    </c:forEach>
    </table>
  </body>
</html>

fmt格式化標籤庫