[轉][Java]自定義標簽簡介
作用:自定義標簽主要用於移除 jsp 頁面中的 java 代碼。
實現:需要完成以下兩個步驟:
- 編寫一個實現 Tag 接口的 Java 類,把頁面 java 代碼移到這個 java 類中。(標簽處理類)
- 編寫標簽庫描述符 (tld)文件,在 tld 文件中把標簽處理器類描述成一個標簽。
代碼:新建一個 day11 項目,在 src 目錄下新建 cn.itcast.web.tag 包,ViewIPTag Java文件
package cn.itcast.web.tag; import java.io.IOException; import javax.servlet.http.HttpServletRequest;import javax.servlet.jsp.JspException; import javax.servlet.jsp.JspWriter; import javax.servlet.jsp.tagext.TagSupport; public class ViewIPTag extends TagSupport { @Override public int doStartTag() throws JspException { HttpServletRequest request = (HttpServletRequest) this.pageContext.getRequest(); JspWriter out= this.pageContext.getOut(); String ip = request.getRemoteAddr(); try { out.print(ip); } catch (IOException e) { throw new RuntimeException(e); } return super.doStartTag(); } }
再在 WebRoot\WEB-INF 目錄下新建 itcast.tld
<?xml version="1.0" encoding="UTF-8"?> <!-- 本代碼部分內容來自: X:\apache-tomcat-7.0.77-src\webapps\examples\WEB-INF\jsp2\jsp2-example-taglib.tld Licensed to the Apache Software Foundation (ASF) under one or more contributor license agreements. See the NOTICE file distributed with this work for additional information regarding copyright ownership. The ASF licenses this file to You under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. --> <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"> <description>A tag library exercising SimpleTag handlers.</description> <tlib-version>1.0</tlib-version> <short-name>itcast</short-name> <uri>http://www.itcast.cn</uri> <tag> <description>輸出客戶端IP</description> <name>viewIP</name> <tag-class>cn.itcast.web.tag.ViewIPTag</tag-class> <body-content>empty</body-content> </tag> </taglib>
這時候就可以在任意 jsp 文件中使用此標簽
<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%> <%@ taglib uri="http://www.itcast.cn" prefix="itcast" %> <!doctype html> <html> <head> <title>starting page</title> </head> <body> This is my JSP page. <br> 來自客戶端的IP是:<itcast:viewIP/> </body> </html>
標簽調用流程:
1. 瀏覽器給 Web 服務器發送 jsp頁面請求
2. Web 服務器開始解釋 jsp 頁面
3. 遇到自定義標簽,首先實例化標簽對應的標簽處理器類
4. 調用 setPageContext 方法,把頁面的 pageContext 對象傳遞給標簽處理器類
5. 看標簽是否有父標簽,如果有父標簽,把父標簽作為一個對象,調用 setParent 方法傳遞給標簽處理器類,如果沒有,傳遞一個 null
6. 完成以上標簽的初始化工作後,服務器就開始執行標簽。這時遇到 標簽的開始標簽,就調用 doStartTag 方法
7. 如果標簽有標簽體,這時服務器一般會執行標簽體
8. 服務器遇到 jsp頁面結束標簽,則調用標簽處理器類的 doEndTag 方法
9. 整個標簽執行完後,服務器一般情況下會調用 release 方法釋放標簽工作時所占用的資源
Method Summary => setPageContext(PageContext pc) getParent() setParent() doStartTag() doEndTag() release()
在 ViewIPTag.java 類中,doStartTag 方法默認是 return super.doStartTag();
如果改寫為 return Tag.EVAL_BODY_INCLUDE 則輸出標簽體
如果改寫為 return Tag.SKIP_BODY 則不輸出標簽體
doEndTag 方法默認是 return super.doEndTag();
如果改寫為 return Tag.EVAL_PAGE 則輸出
如果改寫為 return Tag.SKIP_PAGE 則停止輸出
假如需要標簽體執行 5 次,在 doAfterBody 方法裏寫:
@Override public int doStartTag() throws JspException { return Tag.EVAL_BODY_INCLUDE; } @Override public int doAfterBody() throws JspException { int x=5; x--; if(x>0){ return IterationTag.EVAL_BODY_AGAIN; }else{ return IterationTag.SKIP_BODY; } }
// 修改標簽體 public class TagDemo4 extends BodyTagSupport { @Override public int doStartTag() throws JspException { return BodyTag.EVAL_BODY_BUFFERED; } @Override public int doEndTag() throws JspException { BodyContent bc = this.getBodyContent(); String content = bc.getString(); content = content.toUpperCase(); try { this.pageContext.getOut().write(content); } catch (IOException e) { throw new RuntimeException(e); } return Tag.EVAL_PAGE; } }
[轉][Java]自定義標簽簡介