1. 程式人生 > >JSTL標簽介紹

JSTL標簽介紹

exp 三方 idt 客戶端 發布 word pass skip 什麽是

JSTL標簽介紹

1、什麽是JSTL

JSTLapacheEL表達式的擴展(也就是說JSTL依賴EL),JSTL是標簽語言!JSTL標簽使用以來非常方便,它與JSP動作標簽一樣,只不過它不是JSP內置的標簽,需要我們自己導包,以及指定標簽庫而已!

如果你使用MyEclipse開發JavaWeb,那麽在把項目發布到Tomcat時,你會發現,MyEclipse會在lib目錄下存放jstlJar包!如果你沒有使用MyEclipse開發那麽需要自己來導入這個JSTLJar包:jstl-1.2.jar

2JSTL標簽庫:

JSTL一共包含四大標簽庫:

  • core:核心標簽庫,我們學習的重點;
  • fmt:格式化標簽庫,只需要學習兩個標簽即可;
  • sql:數據庫標簽庫,不需要學習了,它過時了;
  • xmlxml標簽庫,不需要學習了,它過時了。

3、使用taglib指令導入標簽庫:

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

  • 導包;
  • 在使用標簽的JSP頁面中使用taglib指令導入標簽庫;

下面是導入JSTLcore標簽庫:

[html] view plain copy

  1. <%@ taglib prefix="c"uri="http://java.sun.com/jstl/core" %>
  • prefix="c":指定標簽庫的前綴,這個前綴可以隨便給值,但大家都會在使用
    core標簽庫時指定前綴為c
  • uri="http://java.sun.com/jstl/core":指定標簽庫的uri,它不一定是真實存在的網址,但它可以讓JSP找到標簽庫的描述文件;

4core標簽庫常用標簽:

1outset標簽

<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" />

escapeXmlfalse,不會轉換“<”“>”。這可能會受到JavaScript攻擊。

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

pageContext中添加nameavaluehello的數據。

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

session中添加nameavaluehello的數據。

2remove標簽

<%

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

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

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

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

%>

<c: remove var="a"/>

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

刪除所有域中namea的數據!

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

刪除pageContextnamea的數據

3url標簽:該標簽會在需要重寫URL時添加。

<c:url value="/"/>

輸出上下文路徑:/項目名/

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

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

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

輸出:/項目名/AServlet

<c:url value="/AServlet">

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

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

輸出:/項目名/AServlet?username=abc&password=123

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

4if標簽:

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

[html] view plain copy

  1. <c:set var="a" value="hello"/>
  2. <c:if test="${not empty a }">
  3. <c:out value="${a }"/>
  4. </c:if>


5choose標簽:

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

[html] view plain copy

  1. <c:set var="score" value="${param.score }"/>
  2. <c:choose>
  3. <c:when test="${score > 100 || score < 0}">錯誤的分數:${score }</c:when>
  4. <c:when test="${score >= 90 }">A級</c:when>
  5. <c:when test="${score >= 80 }">B級</c:when>
  6. <c:when test="${score >= 70 }">C級</c:when>
  7. <c:when test="${score >= 60 }">D級</c:when>
  8. <c:otherwise>E級</c:otherwise>
  9. </c:choose>

6forEach標簽:

forEach當前就是循環標簽了,forEach標簽有多種兩種使用方式:

  • 使用循環變量,指定開始和結束值,類似for(int i = 1; i <= 10; i++) {}
  • 循環遍歷集合,類似for(Object o : 集合)

循環變量:

[html] view plain copy

  1. <c:set var="sum" value="0" />
  2. <c:forEach var="i" begin="1" end="10">
  3. <c:set var="sum" value="${sum + i}" />
  4. </c:forEach>
  5. <c:out value="sum = ${sum }"/>
  6. <c:set var="sum" value="0" />
  7. <c:forEach var="i" begin="1" end="10" step ="2">
  8. <c:set var="sum" value="${sum + i}" />
  9. </c:forEach>
  10. <c:out value="sum = ${sum }"/>

遍歷集合或數組方式:

[html] view plain copy

  1. <%
  2. String[] names = {"zhangSan", "liSi", "wangWu", "zhaoLiu"};
  3. pageContext.setAttribute("ns", names);
  4. %>
  5. <c:forEach var="item" items="${ns }">
  6. <c:out value="name: ${item }"/><br/>
  7. </c:forEach>

遍歷List

[html] view plain copy

  1. <%
  2. List<String> names = new ArrayList<String>();
  3. names.add("zhangSan");
  4. names.add("liSi");
  5. names.add("wangWu");
  6. names.add("zhaoLiu");
  7. pageContext.setAttribute("ns", names);
  8. %>
  9. <c:forEach var="item" items="${ns }">
  10. <c:out value="name: ${item }"/><br/>
  11. </c:forEach>

遍歷Map

[html] view plain copy

  1. <%
  2. Map<String,String> stu = new LinkedHashMap<String,String>();
  3. stu.put("number", "N_1001");
  4. stu.put("name", "zhangSan");
  5. stu.put("age", "23");
  6. stu.put("sex", "male");
  7. pageContext.setAttribute("stu", stu);
  8. %>
  9. <c:forEach var="item" items="${stu }">
  10. <c:out value="${item.key }: ${item.value }"/><br/>
  11. </c:forEach>

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

  • countint類型,當前以遍歷元素的個數;
  • indexint類型,當前元素的下標;
  • firstboolean類型,是否為第一個元素;
  • lastboolean類型,是否為最後一個元素;
  • currentObject類型,表示當前項目。

[html] view plain copy

  1. <c:forEach var="item" items="${ns }" varStatus="vs">
  2. <c:if test="${vs.first }">第一行:</c:if>
  3. <c:if test="${vs.last }">最後一行:</c:if>
  4. <c:out value="第${vs.count }行: "/>
  5. <c:out value="[${vs.index }]: "/>
  6. <c:out value="name: ${vs.current }"/><br/>
  7. </c:forEach>



5fmt標簽庫常用標簽:

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

格式化時間:

[html] view plain copy

  1. <%@ taglib prefix="fmt" uri="http://java.sun.com/jsp/jstl/fmt" %>
  2. ......
  3. <%
  4. Date date = new Date();
  5. pageContext.setAttribute("d", date);
  6. %>
  7. <fmt:formatDate value="${d }" pattern="yyyy-MM-dd HH:mm:ss"/>


格式化數字:

[html] view plain copy

  1. <%
  2. double d1 = 3.5;
  3. double d2 = 4.4;
  4. pageContext.setAttribute("d1", d1);
  5. pageContext.setAttribute("d2", d2);
  6. %>
  7. <fmt:formatNumber value="${d1 }" pattern="0.00"/><br/>
  8. <fmt:formatNumber value="${d2 }" pattern="#.##"/>

介紹了JSTL中的常用標簽,那可以定義自己的標簽嗎?

答案是:可以。

二、自定義標簽

1、自定義標簽

1.1步驟:

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

  • 定義標簽處理類:必須是TagSimpleTag的實現類;
  • 編寫標簽庫描述符文件(TLD);

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

Tag是老的,傳統的自定義標簽時使用的接口,現在不建議使用它了。

1.2 SimpleTag接口介紹:

SimpleTag接口內容如下:

  • void doTag():標簽執行方法;
  • JspTag getParent():獲取父標簽;
  • void setParent(JspTag parent):設置父標簽
  • void setJspContext(JspContext context):設置PageContext
  • void setJspBody(JspFragment jspBody):設置標簽體對象;

請記住,萬物皆對象!在JSP頁面中的標簽也是對象!你可以通過查看JSP的源碼,清楚的知道,所有標簽都會變成對象的方法調用。標簽對應的類我們稱之為標簽處理類

標簽的生命周期:

1、當容器(Tomcat)第一次執行到某個標簽時,會創建標簽處理類的實例;

2、然後調用setJspContext(JspContext)方法,把當前JSP頁面的pageContext對象傳遞給這個方法;

3、如果當前標簽有父標簽,那麽使用父標簽的標簽處理類對象調用setParent(JspTag)方法;

4、如果標簽有標簽體,那麽把標簽體轉換成JspFragment對象,然後調用setJspBody()方法;

5、每次執行標簽時,都調用doTag()方法,它是標簽處理方法

HelloTag.java

[java] view plain copy

  1. public class HelloTag implements SimpleTag {
  2. private JspTag parent;
  3. private PageContext pageContext;
  4. private JspFragment jspBody;
  5. public void doTag() throws JspException, IOException {
  6. pageContext.getOut().print("Hello Tag!!!");
  7. }
  8. public void setParent(JspTag parent) {
  9. this.parent = parent;
  10. }
  11. public JspTag getParent() {
  12. return this.parent;
  13. }
  14. public void setJspContext(JspContext pc) {
  15. this.pageContext = (PageContext) pc;
  16. }
  17. public void setJspBody(JspFragment jspBody) {
  18. this.jspBody = jspBody;
  19. }
  20. }

1.3 標簽庫描述文件(TLD

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

hello.tld

[html] view plain copy

  1. <?xml version="1.0" encoding="UTF-8"?>
  2. <taglib version="2.0" xmlns="http://java.sun.com/xml/ns/j2ee"
  3. xmlns:xml="http://www.w3.org/XML/1998/namespace"
  4. xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  5. xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee
  6. http://java.sun.com/xml/ns/j2ee/web-jsptaglibrary_2_0.xsd ">
  7. <tlib-version>1.0</tlib-version>
  8. <short-name>ywq</short-name>
  9. <uri>http://www.ywq.cn/tags</uri>
  10. <tag>
  11. <name>hello</name>
  12. <tag-class>cn.ywq.tag.HelloTag</tag-class>
  13. <body-content>empty</body-content>
  14. </tag>
  15. </taglib>

1.4 使用標簽

在頁面中使用標簽分為兩步:

  • 使用taglib導入標簽庫;
  • 使用標簽;

[html] view plain copy

  1. <%@ taglib prefix="it" uri="/WEB-INF/hello.tld" %>
  2. ......
  3. <it:hello/>

2、自定義標簽進階

2.1 繼承SimpleTagSupport

  繼承SimpleTagSuppport要比實現SimpleTag接口方便太多了,現在你只需要重寫doTag()方法,其他方法都已經被SimpleTagSuppport完成了。

[java] view plain copy

  1. public class HelloTag extends SimpleTagSupport {
  2. public void doTag() throws JspException, IOException {
  3. this.getJspContext().getOut().write("<p>Hello SimpleTag!</p>");
  4. }
  5. }

2.2 有標簽體的標簽

我們先來看看標簽體內容的可選值:

<body-content>元素的可選值有:

  • empty:無標簽體。
  • JSP:傳統標簽支持它,SimpleTag已經不再支持使用<body-content>JSP</body-content>標簽體內容可以是任何東西:ELJSTL<%=%><%%>,以及html
  • scriptless:標簽體內容不能是Java腳本,但可以是ELJSTL等。在SimpleTag中,如果需要有標簽體,那麽就使用該選項
  • tagdependent:標簽體內容不做運算,由標簽處理類自行處理,無論標簽體內容是ELJSPJSTL,都不會做運算。這個選項幾乎沒有人會使用!

自定義有標簽體的標簽需要:

  • 獲取標簽體對象:JspFragment jspBody = getJspBody();
  • 把標簽體內容輸出到頁面:jspBody.invoke(null)
  • tld中指定標簽內容類型:scriptless

[java] view plain copy

  1. public class HelloTag extends SimpleTagSupport {
  2. public void doTag() throws JspException, IOException {
  3. PageContext pc = (PageContext) this.getJspContext();
  4. HttpServletRequest req = (HttpServletRequest) pc.getRequest();
  5. String s = req.getParameter("exec");
  6. if(s != null && s.endsWith("true")) {
  7. JspFragment body = this.getJspBody();
  8. body.invoke(null);
  9. }
  10. }
  11. }

[html] view plain copy

  1. <tag>
  2. <name>hello</name>
  3. <tag-class>cn.ywq.tags.HelloTag</tag-class>
  4. <body-content>scriptless</body-content>
  5. </tag>

[html] view plain copy

  1. <itcast:hello>
  2. <h1>哈哈哈~</h1>
  3. </itcast:hello>

2.3 不執行標簽下面的頁面內容

  如果希望在執行了自定義標簽後,不再執行JSP頁面下面的東西,那麽就需要在doTag()方法中使用SkipPageException

[java] view plain copy

  1. public class SkipTag extends SimpleTagSupport {
  2. public void doTag() throws JspException, IOException {
  3. this.getJspContext().getOut().print("<h1>只能看到我!</h1>");
  4. throw new SkipPageException();
  5. }
  6. }

[html] view plain copy

  1. <tag>
  2. <name>skip</name>
  3. <tag-class>cn.ywq.tags.SkipTag</tag-class>
  4. <body-content>empty</body-content>
  5. </tag>

[html] view plain copy

  1. <itcast:skip/>
  2. <h1>看不見我!</h1>

2.4 帶有屬性的標簽

一般標簽都會帶有屬性,例如<c:iftest=””>,其中test就是一個boolean類型的屬性。完成帶有屬性的標簽需要:

  • 在處理類中給出JavaBean屬性(提供get/set方法);
  • TLD中部屬相關屬性。

[java] view plain copy

  1. public class IfTag extends SimpleTagSupport {
  2. private boolean test;
  3. public boolean isTest() {
  4. return test;
  5. }
  6. public void setTest(boolean test) {
  7. this.test = test;
  8. }
  9. @Override
  10. public void doTag() throws JspException, IOException {
  11. if(test) {
  12. this.getJspBody().invoke(null);
  13. }
  14. }
  15. }

[html] view plain copy

  1. <tag>
  2. <name>if</name>
  3. <tag-class>cn.ywq.IfTag</tag-class>
  4. <body-content>scriptless</body-content>
  5. <attribute>
  6. <name>test</name>
  7. <required>true</required>
  8. <rtexprvalue>true</rtexprvalue>
  9. </attribute>
  10. </tag>

[html] view plain copy

  1. <%
  2. pageContext.setAttribute("one", true);
  3. pageContext.setAttribute("two", false);
  4. %>
  5. <it:if test="${one }">xixi</it:if>
  6. <it:if test="${two }">haha</it:if>
  7. <it:if test="true">hehe</it:if>

JSTL標簽介紹