一、認識標簽 1,說明:傳統標簽編程在開發中基本用不到,學習標簽編程主要還是為了完善知識體系。 2,標簽的主要作用:移除或減少jsp中的java代碼 3,標簽的主要組成部分及運行原理 4,簡單標簽示例:繼承javax.servlet.jsp.tagext.TagSupport 標簽開發步驟 4.1編 ...
一、認識標簽
1,說明:傳統標簽編程在開發中基本用不到,學習標簽編程主要還是為了完善知識體系。
2,標簽的主要作用:移除或減少jsp中的java代碼
3,標簽的主要組成部分及運行原理
4,簡單標簽示例:繼承javax.servlet.jsp.tagext.TagSupport
標簽開發步驟
4.1編寫一個繼承TagSupport(或實現Tag介面)的類
package com.chen.ying; 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 FirstTag extends TagSupport { public int doStartTag()throws JspException{ System.out.println("調用doStartTag方法"); HttpServletRequest req=(HttpServletRequest)pageContext.getRequest(); JspWriter out=pageContext.getOut(); String ip=req.getRemoteAddr();//通過request對象取得ip地址 try { out.write(ip);//輸出時有可能會拋出異常 } catch (IOException e) { e.printStackTrace(); } return TagSupport.SKIP_BODY;//表示跳過標簽體 } }
4.2在WEB-INF目錄下新建*.tld文件,用於表示標簽庫,在*.tld文件中對標簽處理類進行描述
<?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"> <!-- description用來添加對taglib(標簽庫)的描述 --> <description>陳程編程開發的自定義標簽庫</description> <!--taglib(標簽庫)的版本號 --> <tlib-version>1.0</tlib-version> <short-name>GaclTagLibrary</short-name> <!-- 為自定義標簽庫設置一個uri用於表示標簽庫,uri以/開頭,/後面的內容隨便寫,如這裡的/chen , 在Jsp頁面中引用標簽庫時,需要通過uri找到標簽庫 在Jsp頁面中就要這樣引入標簽庫:<%@taglib uri="/chen" prefix="anyword"%> --> <uri>/chen</uri> <!--一個taglib(標簽庫)中包含多個自定義標簽,每一個自定義標簽使用一個tag標記來描述 --> <!-- 一個tag標記對應一個自定義標簽 --> <tag> <description>這個標簽的作用是用來輸出客戶端的IP地址</description> <!-- 為標簽處理器類配一個標簽名,在Jsp頁面中使用標簽時是通過標簽名來找到要調用的標簽處理器類 通過IP就能找到對應的com.chen.ying.FirstTag類 --> <name>IP</name> <!-- 標簽對應的處理器類--> <tag-class>com.chen.ying.FirstTag</tag-class> <body-content>empty</body-content> </tag> </taglib>
4.3在jsp頁面中使用自定義標簽
使用<%@taglib uri=”標簽庫的uri” prefix=”標簽的使用首碼”%>來引入要使用的標簽庫,首碼可任意設置
顯示結果
每次調用<haha:IP>標簽時,都會觸發doStartTag()方法
從上面代碼可以看到,使用標簽可以移除jsp中的java代碼
二、定義有屬性的標簽
1, 要求
2, 完成一個日期格式化顯示的操作,即根據用戶輸入的日期格式化模板顯示日期。
2.1編寫標簽類
package com.chen.ying; import java.io.IOException; import java.text.SimpleDateFormat; import java.util.Date; import javax.servlet.jsp.JspException; import javax.servlet.jsp.tagext.TagSupport; public class DataTag extends TagSupport { private String format; public int doStartTag()throws JspException{ SimpleDateFormat sdf=new SimpleDateFormat(this.format);//設置日期格式 try { pageContext.getOut().write(sdf.format(new Date()));//用指定格式顯示日期 } catch (IOException e) { e.printStackTrace(); } return TagSupport.SKIP_BODY; } public String getFormat() { return format; } public void setFormat(String format) {//在標簽中通過反射機制設置 this.format = format; } }
2.2在標簽庫中配置標簽
2.3在jsp使用標簽
3, 小結
三、TagSupport類
1, 要求
2, TagSupport主要屬性及方法
Int doStartTag()
int doAfterBody()
int doEndTag()
3,Tag介面執行流程
4,含標簽體的標簽:判斷某個屬性範圍內是否存在指定的屬性名稱的屬性
4.1編寫標簽處理器類
package com.chen.ying; import javax.servlet.jsp.JspException; import javax.servlet.jsp.tagext.TagSupport; public class AttributeTag extends TagSupport { private String name;//接收屬性的名稱 private String scope;//接收屬性的範圍 public int doStartTag()throws JspException{ Object value=null; if("page".equals(this.scope)){//是否是page屬性範圍 value=pageContext.getAttribute(this.name,pageContext.PAGE_SCOPE); } if("request".equals(this.scope)){//是否是request屬性範圍 value=pageContext.getAttribute(this.name,pageContext.REQUEST_SCOPE); } if("session".equals(this.scope)){//是否是session屬性範圍 value=pageContext.getAttribute(this.name,pageContext.SESSION_SCOPE); } if("application".equals(this.scope)){//是否是屬性範圍 value=pageContext.getAttribute(this.name,pageContext.APPLICATION_SCOPE); } if(value==null){//表示沒有此屬性,不執行標簽體 return TagSupport.SKIP_BODY; } else{//執行標簽體 return TagSupport.EVAL_BODY_INCLUDE; } } public void setName(String name) { this.name = name; } public void setScope(String scope) { this.scope = scope; } }
4.2在標簽庫中配置標簽
4.3在jsp中使用標簽‘
是否執行標簽體,由返回值決定
5,小結
四、迭代標簽
1, 要求
在MVC模式中強調,在一個JSP文件中最好不要出現script代碼,因為這樣會破壞程式的結構,維護起來非常麻煩,JSP文件就只是用來接收、判斷與輸出的。現在要在JSP中完成集合的輸出,為了不出現script代碼,可以用迭代標簽
2, 迭代標簽開發步驟
2.1編寫標簽處理類
public class IteratorTag extends TagSupport { private String name; private String scope; private String id;//指定保存集合中的每個元素的屬性名稱 private Iterator<?> iter=null; public int doStartTag()throws JspException{ Object value=null; if("page".equals(this.scope)){//是否是page屬性範圍 value=pageContext.getAttribute(this.name,pageContext.PAGE_SCOPE); } if("request".equals(this.scope)){//是否是request屬性範圍 value=pageContext.getAttribute(this.name,pageContext.REQUEST_SCOPE); } if("session".equals(this.scope)){//是否是session屬性範圍 value=pageContext.getAttribute(this.name,pageContext.SESSION_SCOPE); } if("application".equals(this. Scope)){//是否是屬性範圍 value=pageContext.getAttribute(this.name,pageContext.APPLICATION_SCOPE); } if(value!=null&&value instanceof List<?>){//有此屬性且為List類型 this.iter=((List<?>)value).iterator(); if(iter.hasNext()){ pageContext.setAttribute(this.id,iter.next()); //將集合元素保存在指定屬性名的屬性範圍中 return TagSupport.EVAL_BODY_INCLUDE;//執行標簽體,通過id屬性名輸出集合元素 } else{ return TagSupport.SKIP_BODY; } } else{ return TagSupport.SKIP_BODY; } } public int doAfterBody()throws JspException{ if(iter.hasNext()){ pageContext.setAttribute(this.id,iter.next()); //將集合元素保存在屬性範圍中,屬性名在jsp中指定 return TagSupport.EVAL_BODY_AGAIN;//如果還有元素,交給doAfterBody()處理 } else{ return TagSupport.SKIP_BODY; } } public void setName(String name) { this.name = name; } public void setScope(String scope) { this.scope = scope; } public void setId(String id) { this.id = id; } }
註意,如果是要執行一次標簽體則在doStartTag()中返回EVAL_BODY_INCLUDE,如果是要多次執行標簽體,則在doAfterBody()中返回EVAL_BODY_AGAIN;
2.2在標簽庫中配置標簽處理類
有時候tomcat會出現如下錯誤
Unable to find setter method for ***
只要在對應屬性配置處添加<type>屬性類型</type>即可解決
2.3在jsp中使用標簽
id用於指定list中每個元素保存在屬性範圍中的屬性名,以方便用表達式語言輸出
2.4結果
3, 小結
通過標簽操作對象,可分為以下步驟:首先在servlet中將對象保存在屬性範圍內,然後:1,確定標簽的屬性有哪些,如要操作對象屬性的名稱,範圍等2,通過對象屬性得到對象,然後處理對象,可將處理後的結果保存在指定屬性名的屬性範圍內,然後在標簽體中顯示處理結果,如上述id=”person”.
五、 BodyTagSupport類
1, 要求
2, 定義
3, 主要擴充方法
4, BodyContent類
5, BodyTag介面的執行流程
6,TagExtraInfo類和VariableInfo類
TagExtraInfo類的主要方法
VariableInfo類的主要方法
7,小結
以上都是傳統標簽開發,在實際開發中並不常用,下麵的簡單標簽才是重點