1. 程式人生 > >Java Web複習(12)EL表示式jstl標籤庫

Java Web複習(12)EL表示式jstl標籤庫

1 EL概述

1.1 EL的作用

JSP2.0要把html和css分離、要把html和javascript分離、要把Java指令碼替換成標籤。標籤的好處是非Java人員都可以使用。

JSP2.0 – 純標籤頁面,即:不包含<% … %>、<%! … %>,以及<%= … %>

EL(Expression Language)是一門表示式語言,它對應<%=…%>。我們知道在JSP中,表示式會被輸出,所以EL表示式也會被輸出。

1.2 EL的格式

格式:${…}

例如:${1 + 2}

1.3 關閉EL

如果希望整個JSP忽略EL表示式,需要在page指令中指定isELIgnored=”true”。

如果希望忽略某個EL表示式,可以在EL表示式之前新增“\”,例如:\${1 + 2}。

1.4 EL運算子

運算子

說明

範例

結果

+

${17+5}

22

-

${17-5}

12

*

${17*5}

85

/或div

${17/5}或${17 div 5}

3

%或mod

取餘

${17%5}或${17 mod 5}

2

==或eq

等於

${5==5}或${5 eq 5}

true

!=或ne

不等於

${5!=5}或${5 ne 5}

false

<或lt

小於

${3<5}或${3 lt 5}

true

>或gt

大於

${3>5}或${3 gt 5}

false

<=或le

小於等於

${3<=5}或${3 le 5}

true

>=或ge

大於等於

${3>=5}或${3 ge 5}

false

&&或and

並且

${true&&false}或${true and false}

false

!或not

${!true}或${not true}

false

||或or

或者

${true||false}或${true or false}

true

empty

是否為空

${empty “”},可以判斷字串、資料、集合的長度是否為0,為0返回true。empty還可以與not或!一起使用。${not empty “”}

true

1.5 EL不顯示null

  當EL表示式的值為null時,會在頁面上顯示空白,即什麼都不顯示。

2 EL表示式格式

先來了解一下EL表示式的格式!現在還不能演示它,因為需要學習了EL11個內建物件後才方便顯示它。

l  操作List和陣列:${list[0]}、${arr[0]};

l  操作bean的屬性:${person.name}、${person[‘name’]},對應person.getName()方法;

l  操作Map的值:${map.key}、${map[‘key’]},對應map.get(key)。

3 EL內建物件

EL一共11個內建物件,無需建立即可以使用。這11個內建物件中有10個是Map型別的,最後一個是pageContext物件。

l  pageScope

l  requestScope

l  sessionScope

l  applicationScope

l  param;

l  paramValues;

l  header;

l  headerValues;

l  initParam;

l  cookie;

l  pageContext;

3.1 域相關內建物件(重點)

域內建物件一共有四個:

l  pageScope:${pageScope.name}等同與pageContext.getAttribute(“name”);

l  requestScope:${requestScope.name}等同與request.getAttribute(“name”);

l  sessionScoep: ${sessionScope.name}等同與session.getAttribute(“name”);

l  applicationScope:${applicationScope.name}等同與application.getAttribute(“name”);

如果在域中儲存的是JavaBean物件,那麼可以使用EL來訪問JavaBean屬性。因為EL只做讀取操作,所以JavaBean一定要提供get方法,而set方法沒有要求。

Person.java

publicclass Person {

private String name;

privateintage;

private String sex;

public String getName() {

returnname;

}

publicvoid setName(String name) {

this.name = name;

}

publicint getAge() {

returnage;

}

publicvoid setAge(int age) {

this.age = age;

}

public String getSex() {

returnsex;

}

publicvoid setSex(String sex) {

this.sex = sex;

}

}

  全域查詢:${person}表示依次在pageScope、requesScopet、sessionScope、appliationScope四個域中查詢名字為person的屬性。

3.2 請求引數相關內建物件

  param和paramValues這兩個內建物件是用來獲取請求引數的。

l  param:Map<String,String>型別,param物件可以用來獲取引數,與request.getParameter()方法相同。

注意,在使用EL獲取引數時,如果引數不存在,返回的是空字串,而不是null。這一點與使用request.getParameter()方法是不同的。

l  paramValues:paramValues是Map<String, String[]>型別,當一個引數名,對應多個引數值時可以使用它。

3.3 請求頭相關內建物件

header和headerValues是與請求頭相關的內建物件:

l  header:Map<String,String>型別,用來獲取請求頭。

l  headerValues:headerValues是Map<String,String[]>型別。當一個請求頭名稱,對應多個值時,使用該物件,這裡就不在贅述。

3.4 應用初始化引數相關內建物件

l  initParam:initParam是Map<String,String>型別。它對應web.xml檔案中的<context-param>引數。

3.5 Cookie相關內建物件

l  cookie:cookie是Map<String,Cookie>型別,其中key是Cookie的名字,而值是Cookie物件本身。

3.6 pageContext物件

pageContext:pageContext是PageContext型別!可以使用pageContext物件呼叫getXXX()方法,例如pageContext.getRequest(),可以${pageContext.request}。也就是讀取JavaBean屬性!!!

EL表示式

說明

${pageContext.request.queryString}

pageContext.getRequest().getQueryString();

${pageContext.request.requestURL}

pageContext.getRequest().getRequestURL();

${pageContext.request.contextPath}

pageContext.getRequest().getContextPath();

${pageContext.request.method}

pageContext.getRequest().getMethod();

${pageContext.request.protocol}

pageContext.getRequest().getProtocol();

${pageContext.request.remoteUser}

pageContext.getRequest().getRemoteUser();

${pageContext.request.remoteAddr}

pageContext.getRequest().getRemoteAddr();

${pageContext.session.new}

pageContext.getSession().isNew();

${pageContext.session.id}

pageContext.getSession().getId();

${pageContext.servletContext.serverInfo}

pageContext.getServletContext().getServerInfo();

EL函式庫

1 什麼EL函式庫

  EL函式庫是由第三方對EL的擴充套件,我們現在學習的EL函式庫是由JSTL新增的。JSTL明天再學!

EL函式庫就是定義一些有返回值靜態方法。然後通過EL語言來呼叫它們!當然,不只是JSTL可以定義EL函式庫,我們也可以自定義EL函式庫。

  EL函式庫中包含了很多對字串的操作方法,以及對集合物件的操作。例如:${fn:length(“abc”)}會輸出3,即字串的長度。

2 匯入函式庫

  因為是第三方的東西,所以需要匯入。匯入需要使用taglib指令!

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

3 EL函式庫介紹

l  String toUpperCase(String input):

l  String toLowerCase(String input):

l  int indexOf(String input, String substring):

l  boolean contains(String input, String substring):

l  boolean containsIgnoreCase(String input, String substring):

l  boolean startsWith(String input, String substring):

l  boolean endsWith(String input, String substring):

l  String substring(String input, int beginIndex, int endIndex):

l  String substringAfter(String input, String substring):hello-world, “-“

l  substringBefore(String input, String substring):hello-world, “-“

l  String escapeXml(String input):把字串的“>”、“<”。。。轉義了!

l  String trim(String input):

l  String replace(String input, String substringBefore, StringsubstringAfter):

l  String[] split(String input, String delimiters):

l  int length(Object obj):可以獲取字串、陣列、各種集合的長度!

l  String join(String array[], String separator):

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

String[] strs = {"a", "b","c"};

List list = new ArrayList();

list.add("a");

pageContext.setAttribute("arr", strs);

pageContext.setAttribute("list", list);

%>

${fn:length(arr) }<br/><!--3-->

${fn:length(list) }<br/><!--1-->

${fn:toLowerCase("Hello") }<br/><!-- hello -->

${fn:toUpperCase("Hello") }<br/><!-- HELLO -->

${fn:contains("abc", "a")}<br/><!-- true -->

${fn:containsIgnoreCase("abc", "Ab")}<br/><!-- true -->

${fn:contains(arr, "a")}<br/><!-- true -->

${fn:containsIgnoreCase(list, "A")}<br/><!-- true -->

${fn:endsWith("Hello.java", ".java")}<br/><!-- true -->

${fn:startsWith("Hello.java", "Hell")}<br/><!-- true -->

${fn:indexOf("Hello-World", "-")}<br/><!-- 5 -->

${fn:join(arr, ";")}<br/><!-- a;b;c -->

${fn:replace("Hello-World", "-", "+")}<br/><!-- Hello+World -->

${fn:join(fn:split("a;b;c;", ";"), "-")}<br/><!-- a-b-c -->

${fn:substring("0123456789", 6, 9)}<br/><!-- 678 -->

${fn:substring("0123456789", 5, -1)}<br/><!-- 56789 -->

${fn:substringAfter("Hello-World", "-")}<br/><!-- World -->

${fn:substringBefore("Hello-World", "-")}<br/><!-- Hello -->

${fn:trim("     a b c     ")}<br/><!-- a b c -->

${fn:escapeXml("<html></html>")}<br/><!-- <html></html> -->

4 自定義EL函式庫

l  寫一個類,寫一個有返回值的靜態方法;

l  編寫itcast.tld檔案,可以引數fn.tld檔案來寫,把itcast.tld檔案放到/WEB-INF目錄下;

l  在頁面中新增taglib指令,匯入自定義標籤庫。

ItcastFuncations.java

package cn.itcast.el.funcations;

publicclass ItcastFuncations {

publicstatic String test() {

return"傳智播客自定義EL函式庫測試";

}

}

itcast.tld(放到classes下)

<?xml version="1.0" encoding="UTF-8" ?>

<taglib xmlns="http://java.sun.com/xml/ns/j2ee"

  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"

  xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee http://java.sun.com/xml/ns/j2ee/web-jsptaglibrary_2_0.xsd"

  version="2.0">

<tlib-version>1.0</tlib-version>

<short-name>itcast</short-name>

<uri>http://www.itcast.cn/jsp/functions</uri>

<function>

<name>test</name>

<function-class>cn.itcast.el.funcations.ItcastFuncations</function-class>

<function-signature>String test()</function-signature>

</function>

</taglib>

index.jsp

<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>

<%@ taglib prefix="itcast" uri="/WEB-INF/itcast.tld" %>

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">

<html>

<body>

  <h1>${itcast:test() }</h1>

</body>

</html>

JSTL標籤庫

1 什麼是JSTL

JSTL是apache對EL表示式的擴充套件(也就是說JSTL依賴EL),JSTL是標籤語言!JSTL標籤使用以來非常方便,它與JSP動作標籤一定,只不過它不是JSP內建的標籤,需要我們自己導包,以及指定標籤庫而已!

如果你使用MyEclipse開發JavaWeb,那麼在把專案釋出到Tomcat時,你會發現,MyEclipse會在lib目錄下存放jstl的Jar包!如果你沒有使用MyEclipse開發那麼需要自己來匯入這個JSTL的Jar包:jstl-1.2.jar。

2 JSTL標籤庫

JSTL一共包含四大標籤庫:

l  core:核心標籤庫,我們學習的重點;

l  fmt:格式化標籤庫,只需要學習兩個標籤即可;

l  sql:資料庫標籤庫,不需要學習了,它過時了;

l  xml:xml標籤庫,不需要學習了,它過時了。

3 使用taglib指令匯入標籤庫

除了JSP動作標籤外,使用其他第三方的標籤庫都需要:

l  導包;

l  在使用標籤的JSP頁面中使用taglib指令匯入標籤庫;

下面是匯入JSTL的core標籤庫:

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

l  prefix="c":指定標籤庫的字首,這個字首可以隨便給值,但大家都會在使用core標籤庫時指定字首為c;

l  uri="http://java.sun.com/jstl/core":指定標籤庫的uri,它不一定是真實存在的網址,但它可以讓JSP找到標籤庫的描述檔案;

4 core標籤庫常用標籤

4.1 out和set

 out

<c:out value=”aaa”/>

輸出aaa字串常量

<c:out value=”${aaa}”/>

與${aaa}相同

<c:out value=”${aaa}” default=”xxx”/>

當${aaa}不存在時,輸出xxx字串

<%

request.setAttribute("a","<script>alert('hello');</script>");

%>

<c:out value="${a }" default="xxx" escapeXml="false" />

當escapeXml為false,不會轉換“<”、“>”。這可能會受到JavaScript攻擊。

set

<c:set var=”a” value=”hello”/>

在pageContext中新增name為a,value為hello的資料。

<c:set var=”a” value=”hello” scope=”session”/>

在session中新增name為a,value為hello的資料。

4.2 remove

         <%

                   pageContext.setAttribute("a", "pageContext");

                   request.setAttribute("a", "session");

                   session.setAttribute("a", "session");

                   application.setAttribute("a", "application");

         %>

         <c:out value="${a }" default="none"/>

刪除所有域中name為a的資料!

<c:remove var="a" scope=”page”/>

刪除pageContext中name為a的資料!

4.3 url

  url標籤會在需要URL重寫時新增sessionId。

<c:url value="/"/>

輸出上下文路徑:/day08_01/

<c:url value="/" var="a" scope="request"/>

把本該輸出的結果賦給變數a。範圍為request

<c:url value="/AServlet"/>

輸出:/day08_01/AServlet

<c:url value="/AServlet">

<c:param name="username" value="abc"/>

<c:param name="password" value="123"/>

</c:url>

輸出:/day08_01/AServlet?username=abc&password=123

如果引數中包含中文,那麼會自動使用URL編碼!

4.4 if

  if標籤的test屬性必須是一個boolean型別的值,如果test的值為true,那麼執行if標籤的內容,否則不執行。

<c:set var="a" value="hello"/>[c1] 

<c:if test="${not empty a[c2]  }">

<c:out value="${a }"/>

</c:if>

4.5 choose

choose標籤對應Java中的if/else if/else結構。when標籤的test為true時,會執行這個when的內容。當所有when標籤的test都為false時,才會執行otherwise標籤的內容。

<c:set var="score" value="${param.score }"/>

<c:choose>

<c:when test="${score > 100 || score < 0}">錯誤的分數:${score }</c:when>[c3] 

<c:when test="${score >= 90 }">A</c:when>[c4] 

<c:when test="${score >= 80 }">B</c:when>

<c:when test="${score >= 70 }">C</c:when>

<c:when test="${score >= 60 }">D</c:when>

<c:otherwise>E</c:otherwise>[c5] 

</c:choose>

4.6 forEach

forEach當前就是迴圈標籤了,forEach標籤有多種兩種使用方式:

l  使用迴圈變數,指定開始和結束值,類似for(int i = 1; i <= 10; i++) {};

l  迴圈遍歷集合,類似for(Object o : 集合);

迴圈變數方式:

<c:set var="sum" value="0" />[崔6] 

<c:forEach var="i" begin="1" end="10">[崔7] 

<c:set var="sum" value="${sum + i}" />[崔8] 

</c:forEach>

<c:outvalue="sum = ${sum }"/>

<c:set var="sum" value="0" />

<c:forEach var="i" begin="1" end="10" step[崔9] ="2">

<c:set var="sum" value="${sum + i}" />

</c:forEach>

<c:out value="sum = ${sum }"/>

遍歷集合或陣列方式:

<%

String[] names = {"zhangSan", "liSi", "wangWu", "zhaoLiu"};

pageContext.setAttribute("ns", names);

%>

<c:forEach var="item[崔10] " items="${ns }[崔11] ">

<c:out value="name: ${item }[崔12] "/><br/>

</c:forEach>

遍歷List

<%

List<String> names = new ArrayList<String>();

names.add("zhangSan");

names.add("liSi");

names.add("wangWu");

names.add("zhaoLiu");

pageContext.setAttribute("ns", names);

%>

<c:forEach var="item" items="${ns }">[崔13] 

<c:out value="name: ${item }"/><br/>

</c:forEach>

遍歷Map

<%

Map<String,String> stu = new LinkedHashMap<String,String>();

stu.put("number", "N_1001");

stu.put("name", "zhangSan");

stu.put("age", "23");

stu.put("sex", "male");

pageContext.setAttribute("stu", stu);

%>

<c:forEach var="item[崔14] " items="${stu }">

</c:forEach>

forEach標籤還有一個屬性:varStatus,這個屬性用來指定接收“迴圈狀態”的變數名,例如:<forEach varStatus=”vs” …/>,這時就可以使用vs這個變數來獲取迴圈的狀態了。

l  count:int型別,當前以遍歷元素的個數;

l  index:int型別,當前元素的下標;

l  first:boolean型別,是否為第一個元素;

l  last:boolean型別,是否為最後一個元素;

l  current:Object型別,表示當前專案。

<c:forEach var="item" items="${ns }" varStatus="vs"[崔16] >

<c:if test="${vs.first }[崔17] ">第一行:</c:if>

<c:if test="${vs.last }[崔18] ">最後一行:</c:if>

<c:out value="${vs.count }[崔19] : "/>

<c:out value="[${vs.index }[崔20] ]: "/>

<c:out value="name: ${vs.current }[崔21] "/><br/>

</c:forEach>

5 fmt標籤庫常用標籤

fmt標籤庫是用來格式化輸出的,通常需要格式化的有時間和數字。

格式化時間:

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

......

<%

Date date = new Date();

pageContext.setAttribute("d", date);

%>

<fmt:formatDate value="${d }" pattern=[崔22] "/>

格式化數字:

<%

double d1 = 3.5;

double d2 = 4.4;

pageContext.setAttribute("d1", d1);

pageContext.setAttribute("d2", d2);

%>

<fmt:formatNumber value="${d1 }" pattern="0.00[崔23] "/><br/>

<fmt:formatNumber value="${d2 }" pattern="#.##[崔24] "/>

 [c1]在page域中建立名為a的變數

 [c2]判斷a變數不為null,沒有指定域,表示全域

 [c3]if

 [c4]else if

 [c5]else

 [崔6]建立page域屬性sum為0

 [崔7]設定迴圈變數i,初始值為1,遍歷到10。

 [崔8]設定sum的值為sum + i

 [崔9]步長為2,預設步長為1。相當於i+=2的意思!而預設為i++。

 [崔10]把ns是中每一項賦給item。

 [崔11]ns是被遍歷的陣列。

 [崔12]列印每一項

 [崔13]與遍歷陣列沒有區別!

for(String s : ns) {

  …

}

 [崔14]因為遍歷的是Map,所以每一項是Entry型別

 [崔15]獲取Entry的key和value

 [崔16]把迴圈狀態賦給vs

 [崔17]如果是第一行,那麼${vs.first}為true

 [崔18]如果是最後一行,那麼${vs.last}為true

 [崔19]返回行數,從1開始

 [崔20]返回行數,從0開始

 [崔21]當前項,與${item}相同

 [崔22]按指定格式輸出日期和時間。

 [崔23]必須且僅能保留兩位小數,如果大於兩位,那麼只保留兩位,並四捨五入,如果小於兩位,那麼使用0補足兩位。

 [崔24]最多顯示兩位,如果小於兩位,那麼有幾位保留幾位,不會用0補足。大於兩位,只保留兩位,並四捨五入!



自定義標籤

1 自定義標籤概述

1.1 自定義標籤的步驟

其實我們在JSP頁面中使用標籤就等於呼叫某個物件的某個方法一樣,例如:<c:if test=””>,這就是在呼叫物件的方法一樣。自定義標籤其實就是自定義類一樣!

l  定義標籤處理類:必須是Tag或SimpleTag的實現類;

l  編寫標籤庫描述符檔案(TLD);

SimpleTag介面是JSP2.0中新給出的介面,用來簡化自定義標籤,所以現在我們基本上都是使用SimpleTag。

Tag是老的,傳統的自定義標籤時使用的介面,現在不建議使用它了。

1.2 SimpleTag介面介紹

SimpleTag介面內容如下:

l  void doTag():標籤執行方法;

l  JspTag getParent():獲取父標籤;

l  void setParent(JspTag parent):設定父標籤

l  void setJspContext(JspContext context):設定PageContext

l  void setJspBody(JspFragment jspBody):設定標籤體物件;

請記住,萬物皆物件!在JSP頁面中的標籤也是物件!你可以通過檢視JSP的“真身”清楚的知道,所有標籤都會變成物件的方法呼叫。標籤對應的類我們稱之為“標籤處理類”!

標籤的生命週期:

1.      當容器(Tomcat)第一次執行到某個標籤時,會建立標籤處理類的例項;

2.      然後呼叫setJspContext(JspContext)方法,把當前JSP頁面的pageContext物件傳遞給這個方法;

3.      如果當前標籤有父標籤,那麼使用父標籤的標籤處理類物件呼叫setParent(JspTag)方法;

4.      如果標籤有標籤體,那麼把標籤體轉換成JspFragment物件,然後呼叫setJspBody()方法;

5.      每次執行標籤時,都呼叫doTag()方法,它是標籤處理方法。

HelloTag.java

publicclass HelloTag implements SimpleTag {

private JspTag parent;

private PageContext pageContext;

private JspFragment jspBody;

publicvoid doTag() throws JspException, IOException {

pageContext.getOut().print("Hello Tag!!!");[崔1] 

}

publicvoid setParent(JspTag parent) {

this.parent = parent;

}

public JspTag getParent() {

returnthis.parent;

}

publicvoid setJspContext(JspContext pc) {

this.pageContext = (PageContext) pc;

}

publicvoid setJspBody(JspFragment jspBody) {

this.jspBody = jspBody;

}

}

1.3 標籤庫描述檔案(TLD)

標籤庫描述檔案是用來描述當前標籤庫中的標籤的!標籤庫描述檔案的副檔名為tld,你可以把它放到WEB-INF下,這樣就不會被客戶端直接訪問到了。

hello.tld

<?xml version="1.0" encoding="UTF-8"?>

<taglib version="2.0" xmlns="http://java.sun.com/xml/ns/j2ee"

    xmlns:xml="http://www.w3.org/XML/1998/namespace"