今天是學習自定義標簽的第二天,主要是寫一個自定義的循環標簽。
先看效果圖:
?
前臺頁面Jsp代碼
<%@ page language="java" contentType="text/html; charset=UTF-8"pageEncoding="UTF-8"%> <%@taglib prefix="myout" uri="/demo" %> <html> <head> </head><%String[] array = new String[]{"one","two","three","four","five"};pageContext.setAttribute("arr", array);%> <body><h1>我的測試頁面</h1><myout:Foreach items="arr" var="item">array數組里對應的英文數字:${item}<br></myout:Foreach> </body> </html>
跟第一篇一樣,還是分四部分講解:
?
第一部分:自定義標簽文件(*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"><tlib-version>1.0</tlib-version><short-name>myout</short-name><uri>/demo</uri><!-- 循環 --><tag><name>Foreach</name><tag-class>com.tag.support.TagDemo</tag-class><!-- 標簽體可以用EL表達式 --><body-content>scriptless</body-content><attribute><name>items</name><required>true</required><rtexprvalue>true</rtexprvalue></attribute><attribute><name>var</name><required>true</required><rtexprvalue>true</rtexprvalue></attribute></tag> </taglib>
?
這個地方要注意一點:關于<%@taglib prefix="myout" uri="/demo" %> 是如何找到demo.tld文件的?
兩種方式:
?? 第一種方式:就如同上面這樣配置,在demo.tld文件中加上<uri>/demo</uri> ,指定uri,
?????????????????? 但是這種方式demo.tld必須放在WEB-INF下,不然容器找不到
?? 第二種方式:在web.xml中配置,這種方式是通過顯示的指定demo.tld的位置,可以不放在WEB-INF只要指向正確就好
<jsp-config><taglib><taglib-uri>/demo</taglib-uri><taglib-location>/WEB-INF/lirui.tld</taglib-location></taglib></jsp-config>
?
新增一種方式:其實在jsp頁面引用自定義標簽還可以另一種方式(指定*.tld文件所在路徑),只是這種方式不靈活。
%@taglib prefix="myout" uri="/WEB-INF/demo.tld" %
?
第二部分:標簽具體業務實現類。
自定義的類要繼承(extends)SimpleTagSupport
import java.io.IOException;import javax.servlet.jsp.JspContext; import javax.servlet.jsp.JspException; import javax.servlet.jsp.tagext.SimpleTagSupport;public class TagDemo extends SimpleTagSupport {//注意:這個屬性要與tld文件中定義的屬性一致,并提供get和set方法private String items;private String var;public String getItems() {return items;}public void setItems(String items) {this.items = items;}public String getVar() {return var;}public void setVar(String var) {this.var = var;}//具體業務實現類 @Overridepublic void doTag() throws JspException, IOException {//this.getJspContext()獲得JspContext對象也就是前臺頁面的PageContext//可以看出頁面輸出Hello World注意是這里的write方法實現的JspContext jspContext = this.getJspContext();String[] arr = (String[])jspContext.getAttribute(items);for(String s: arr){jspContext.setAttribute(var, s);this.getJspBody().invoke(null);}} }
注意一點:this.getJspBody().invoke(null); 這行代碼表示把標簽體的內容的內容輸入到瀏覽器,如果沒有調用該方法,則忽略標簽體
我一開始做的時候沒有加這一行代碼,
直接導致前臺頁面<myout:Foreach items="arr" var="item">array數組里對應的英文數字:${item}<br> </myout:Foreach> 標簽體內同顯示不出來,當時查了下資料才知道這里沒有加this.getJspBody().invoke(null); 這一行代碼。
?
擴充一下知識點:JspFragment是個抽象類,這個類代碼很簡單,具體如下:
import java.io.IOException; import java.io.Writer; import javax.servlet.jsp.JspContext; import javax.servlet.jsp.JspException;public abstract class JspFragment {public abstract void invoke(Writer paramWriter)throws JspException, IOException;public abstract JspContext getJspContext(); }
這個類的實例通過SimpleTagSupport類中的getJspBody()方法獲得的。
該類實例封裝了標簽體的內容,主要方法就是invoke方法,該方法具體有兩種用法:
第一種:this.getJspBody().invoke(null);表示輸出到瀏覽器,這是原樣輸出的
第二種:當需要對標簽體進行修改時,需要用到第二種,this.getJspBody().invoke(Writer out);
假設:我希望上面顯示的頁面效果使所有字母大寫,效果如圖
代碼如下:
//具體業務實現類 @Overridepublic void doTag() throws JspException, IOException {JspContext jspContext = this.getJspContext();String[] arr = (String[])jspContext.getAttribute(items);for(String s: arr){jspContext.setAttribute(var, s);//定義一個緩沖區,把內容先輸入到緩存區中,然后在打印到瀏覽器StringWriter sw = new StringWriter();this.getJspBody().invoke(sw);String str = sw.toString().toUpperCase();//打印的具體操作this.getJspContext().getOut().write(str);}}
這就是這兩種方式的區別。
第三部分:Jsp頁面引用自定義標簽。
<%@taglib prefix="myout" uri="/demo" %>
關于引用自定義標簽,上面第二部分已說的很清楚,這里就不多說了。
第四部分:關于定義uri的幾種方式。
兩種方式:(第一部分好像也說了,這里再重復一遍)
?? 第一種方式:就如同上面這樣配置,在demo.tld文件中加上<uri>/demo</uri> ,指定uri,
?????????????????? 但是這種方式demo.tld必須放在WEB-INF下,不然容器找不到
?? 第二種方式:在web.xml中配置,這種方式是通過顯示的指定demo.tld的位置,可以不放在WEB-INF只要指向正確就好
<jsp-config><taglib><taglib-uri>/demo</taglib-uri><taglib-location>/WEB-INF/lirui.tld</taglib-location></taglib></jsp-config>
?
今天是學習Jsp自定義標簽的第二天,剛開始寫博客,如果有什么問題歡迎各位網友及時提出,謝謝。
技術的提高在于分享,而不是閉門造車。