一、EL函數(shù)(調(diào)用普通類的靜態(tài)方法)
編寫步驟(自定義EL函數(shù)的編寫步驟即自定義標(biāo)簽的編寫步驟):
①編寫一個普通的java類,提供一個靜態(tài)方法,功能自定,例如下:
1 package cn.wzbrilliant.el;2 3 public class ElFunction {4 public static String toUpperCase(String str){5 return str.toUpperCase();6 }7 }
②在JavaWeb應(yīng)用的WEB-INF目錄下建立一個擴展名是tld(taglib definition)的xml文件。內(nèi)容如下:
1 <?xml version="1.0" encoding="UTF-8"?> 2 <taglib xmlns="http://java.sun.com/xml/ns/j2ee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 3 xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee http://java.sun.com/xml/ns/j2ee/web-jsptaglibrary_2_0.xsd" 4 version="2.0"> 5 <tlib-version>1.0</tlib-version> 6 <short-name>myfn</short-name> 7 <uri>/WEB-INF/myfn.tld</uri> 8 9 <function><!-- 定義函數(shù) -->10 <name>toUpper</name> <!-- 調(diào)用名稱 -->11 <function-class>cn.wzbrilliant.el.ElFunction</function-class> <!-- 類全名 -->12 <function-signature>java.lang.String toUpperCase( java.lang.String )</function-signature>13 </function>14 15 </taglib>
<tlib-version>值隨意
<short-name>一般與文件名、前綴名稱相同,方便查找,不相同也可。
<uri>值隨意,只要與web.xml中的uri想對應(yīng)即可
③(可選步驟)前提是把tld文件放到了WEB-INF目錄下。告知應(yīng)用,tld文件和tld中的uri的對應(yīng)。修改web.xml,增加以下內(nèi)容:
1 <jsp-config>2 <taglib>3 <taglib-uri>/WEB-INF/myfn.tld</taglib-uri>4 <taglib-location>/WEB-INF/myfn.tld</taglib-location>5 </taglib>6 </jsp-config>
<taglib> 代表一個標(biāo)簽庫,可以多個
<taglib-location> tld文件的位置
④ 在JSP中使用
用taglib指令,引入自定義的EL函數(shù)庫:<%@ taglib uri="/WEB-INF/myfn.tld" 使用方式如下: 代碼第五行和第六行都可輸出"ABCDEF"。 二、EL自定義標(biāo)簽開發(fā) 自定義標(biāo)簽屬于JSP技術(shù) 1、標(biāo)簽的作用 移除掉JSP中的Java腳本(<%%>) 2、編寫自定義標(biāo)簽的步驟(自定義EL函數(shù),步驟相同) 自定義標(biāo)簽分為兩種,傳統(tǒng)標(biāo)簽和簡單標(biāo)簽: 這里只介紹簡單標(biāo)簽的開發(fā): ①編寫一個類,直接或間接實現(xiàn)javax.servlet.jsp.tagext.Tag接口 這里繼承SimpleTagSupport類,例子如下: JspFragment對象的invoke方法將標(biāo)簽內(nèi)容輸入到給定的流中,如果為null,例如上面代碼,則其作用與注釋部分代碼相同。 下面以一個獲取遠程ip地址的代碼為例: ②在WEB-INF目錄下建立一個擴展名為tld(Tag Libary Definition)的xml文件。 標(biāo)簽內(nèi)容與EL函數(shù)中tld文件中相似。可以添加多個標(biāo)簽。具體如下: taglib:根元素 tlib-version:版本號 short-name:引用標(biāo)簽時的短名稱。一般與tld文件的文件名一致,好找。 uri:標(biāo)簽綁定的名稱空間。只是一個名字,沒有實際的意義。 tag:定義標(biāo)簽元素 name:標(biāo)簽的名稱。 tag-class:標(biāo)簽的實現(xiàn)類的全名稱。 body-content:指示標(biāo)簽的主體內(nèi)容的類型。 可選值:empty:沒有主體內(nèi)容。適用于傳統(tǒng)和簡單標(biāo)簽。 JSP:說明JSP文件中能出現(xiàn)什么,標(biāo)簽主體內(nèi)容中就能出現(xiàn)什么。適用于傳統(tǒng)標(biāo)簽。 scriptless:說明標(biāo)簽的主體內(nèi)容不能是java腳本。適用于簡單標(biāo)簽。 tagdependent:說明標(biāo)簽的主體內(nèi)容是原封不動的傳遞給標(biāo)簽處理類的,而不是傳遞的運算結(jié)果 attribute:定義標(biāo)簽的屬性 name:屬性名。對應(yīng)標(biāo)簽處理類中的setter方法 required:是否是必須的屬性 rtexprvalue:是否支持表達式(EL或java表達式)。默認是false。 ③(可選的)在web.xml中對tld文件和名稱空間進行映射對應(yīng)。 此處配置與EL函數(shù)相同 ⑤ 在JSP中使用 首先引入:<%@ taglib uri="/WEB-INF/mytag.tld" prefix="mytag"%> 使用方法:在jsp頁面中使用:<mytag:remoteIp /> 即可輸出訪問服務(wù)器的遠程的ip地址 3.簡單標(biāo)簽的原理: 三、自定義標(biāo)簽實例: ①實現(xiàn)JSTL中forEach標(biāo)簽的功能 類代碼如下: mytag.tld文件中添加如下內(nèi)容: 使用方法: 與JSTL中forEach標(biāo)簽使用無異,如此便可遍歷數(shù)組、集合的元素。 ②實現(xiàn)JSTL中when otherwise功能(與if-else結(jié)構(gòu)相似) 實現(xiàn)用到了父標(biāo)簽。父標(biāo)簽的作用:用于子標(biāo)簽之間數(shù)據(jù)的傳遞。 該例使用了三個標(biāo)簽,分別為choose(父標(biāo)簽),when,otherwise,用三個類實現(xiàn)。 父標(biāo)簽choose實現(xiàn)類: 子標(biāo)簽when實現(xiàn)類: 子標(biāo)簽otherwise實現(xiàn)類: mytag.tld中添加如下內(nèi)容: 使用方法,在jsp中: ③html顯示文本中html代碼的過濾 例如留言板中,有時候需要將html代碼原樣輸出,而不解析。 實現(xiàn)類代碼如下: mytag.tld中添加如下內(nèi)容: 使用方式:在jsp頁面中輸出文本數(shù)據(jù)時添加此標(biāo)簽便可將文本中html代碼原樣輸出,而不解析。 ④防盜鏈標(biāo)簽 防止別的網(wǎng)站、應(yīng)用盜鏈,可以利用EL自定義標(biāo)簽,將請求轉(zhuǎn)向其他URI(自定義的廣告等等) 實現(xiàn)代碼如下: mytag.tld中添加如下內(nèi)容: 使用方法:在防盜鏈的頁面頭部添加:<mytag:referer site="http://localhost:8080/JavaWeb" redirectPath="error.jsp"/>,其中site值為本應(yīng)用的URI,redirectPath是將外部應(yīng)用的請求轉(zhuǎn)發(fā)的目標(biāo)地址,可以是相對路徑,也可以是絕對路徑。 四、JSTL中的核心標(biāo)簽庫(替換掉JSP中的Java腳本) ① c:if 作用:判斷是否為true,如果為true,那么標(biāo)簽的主體內(nèi)容就會顯示。屬性:test:必須的。要求必須是boolean的。支持表達式(EL或Java表達式) var:保存test運算結(jié)果的變量 scope: 保存的域范圍。默認是page②c:forEach 遍歷:數(shù)組、List、Set、Map屬性:items:要遍歷的目標(biāo)對象。支持表達式 var:變量名。指向當(dāng)前遍歷的集合中的一個元素 begin:開始的索引(含) end:結(jié)束的索引(含) step:步長。默認是1 varStatus:取一個名字,引用了一個對象。該對象有以下方法: int getIndex():當(dāng)前記錄的索引號。從0開始 int getCount():當(dāng)前記錄的順序。從1開始 boolean isFirst():是否是第一條記錄 boolean isLast():是否是最后一條記錄1 <%2 pageContext.setAttribute("p", "abcdef");3 %>4 5 ${myfn:toUpper(h) } <br/>6 ${myfn:toUpper("abcdef") }
1 package cn.wzbrilliant.el; 2 3 import java.io.IOException; 4 5 import javax.servlet.jsp.JspException; 6 import javax.servlet.jsp.tagext.SimpleTagSupport; 7 8 public class SimpleTag extends SimpleTagSupport { 9 10 @Override11 public void doTag() throws JspException, IOException {12 // JspFragment jf=getJspBody();13 // jf.invoke(getJspContext().getOut());14 15 getJspBody().invoke(null);16 17 }18 19 }
1 package cn.wzbrilliant.el; 2 3 import java.io.IOException; 4 5 import javax.servlet.jsp.JspException; 6 import javax.servlet.jsp.PageContext; 7 import javax.servlet.jsp.tagext.SimpleTagSupport; 8 9 public class SimpleTag extends SimpleTagSupport {10 11 @Override12 public void doTag() throws JspException, IOException {13 PageContext pageContext=(PageContext)getJspContext();14 String ip=pageContext.getRequest().getRemoteAddr();15 pageContext.getOut().write(ip);16 }17 18 }
1 <?xml version="1.0" encoding="UTF-8"?> 2 <taglib xmlns="http://java.sun.com/xml/ns/j2ee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 3 xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee http://java.sun.com/xml/ns/j2ee/web-jsptaglibrary_2_0.xsd" 4 version="2.0"> 5 6 <tlib-version>1.0</tlib-version> 7 <short-name>mytag</short-name> 8 <uri>/WEB-INF/mytag.tld</uri> 9 10 <tag><!-- 描述標(biāo)簽 -->11 <description>Show Remote Address</description>12 <name>remoteIp</name><!-- 標(biāo)簽名稱 -->13 <tag-class>cn.wzbrilliant.el.SimpleTag</tag-class>14 <body-content>empty</body-content><!-- 指示標(biāo)簽的主體內(nèi)容:沒有就寫empty -->15 </tag>16 17 </taglib>
1 <jsp-config>2 <taglib>3 <taglib-uri>/WEB-INF/mytag.tld</taglib-uri>4 <taglib-location>/WEB-INF/mytag.tld</taglib-location>5 </taglib>6 </jsp-config>
1 package cn.wzbrilliant.el; 2 3 import java.io.IOException; 4 import java.lang.reflect.Array; 5 import java.util.ArrayList; 6 import java.util.Collection; 7 import java.util.List; 8 import java.util.Map; 9 import java.util.Set;10 11 import javax.servlet.jsp.JspException;12 import javax.servlet.jsp.PageContext;13 import javax.servlet.jsp.tagext.SimpleTagSupport;14 15 public class ForEachTag extends SimpleTagSupport {16 private String var;17 private Collection items;18 19 public void setItems(Object items) {20 if(items instanceof List){21 this.items=(List)items;22 }else if(items instanceof Set){23 this.items=(Set)items;24 }else if(items instanceof Map){25 this.items=((Map)items).entrySet();26 }else if(items.getClass().isArray()){27 this.items=new ArrayList();28 int length=Array.getLength(items);29 for(int i=0;i<length;i++){30 this.items.add(Array.get(items, i));31 }32 }else{33 throw new RuntimeException("對不起,不支持的類型");34 }35 }36 public void setVar(String var) {37 this.var = var;38 }39 @Override40 public void doTag() throws JspException, IOException {41 PageContext pageContext=(PageContext) getJspContext();42 for(Object obj:items){43 pageContext.setAttribute(var, obj);44 getJspBody().invoke(null);45 }46 }47 48 }
1 <tag><!-- forEach標(biāo)簽 --> 2 <description>for each</description> 3 <name>forEach</name> 4 <tag-class>cn.wzbrilliant.el.ForEachTag</tag-class> 5 <body-content>scriptless</body-content> 6 <attribute> 7 <name>items</name> 8 <required>true</required> 9 <rtexprvalue>true</rtexprvalue>10 </attribute>11 <attribute>12 <name>var</name>13 <required>true</required>14 <rtexprvalue>true</rtexprvalue>15 </attribute>16 </tag>
1 <%2 int[] arr = new int[] {1,2,3,4};3 4 pageContext.setAttribute("p", arr);5 %>6 7 <mytag:forEach items="${p}" var="v">8 ${v}<br>9 </mytag:forEach>
1 package cn.wzbrilliant.el; 2 3 import java.io.IOException; 4 5 import javax.servlet.jsp.JspException; 6 import javax.servlet.jsp.tagext.SimpleTagSupport; 7 8 public class ChooseTag extends SimpleTagSupport { 9 private boolean flag=false;10 11 protected boolean isFlag(){12 return flag;13 }14 15 protected void setFlag(boolean flag){16 this.flag=flag;17 }18 19 @Override20 public void doTag() throws JspException, IOException {21 22 getJspBody().invoke(null);23 }24 25 26 }
1 package cn.wzbrilliant.el; 2 3 import java.io.IOException; 4 5 import javax.servlet.jsp.JspException; 6 import javax.servlet.jsp.tagext.SimpleTagSupport; 7 8 public class WhenTag extends SimpleTagSupport { 9 private boolean test;10 11 public void setTest(boolean test){12 this.test=test;13 }14 15 @Override16 public void doTag() throws JspException, IOException {17 if(test){18 ChooseTag parent=(ChooseTag)getParent();19 parent.setFlag(true);20 getJspBody().invoke(null);21 }22 }23 24 25 }
1 package cn.wzbrilliant.el; 2 3 import java.io.IOException; 4 5 import javax.servlet.jsp.JspException; 6 import javax.servlet.jsp.tagext.SimpleTagSupport; 7 8 public class OtherwiseTag extends SimpleTagSupport { 9 10 @Override11 public void doTag() throws JspException, IOException {12 ChooseTag parent=(ChooseTag)getParent();13 if(!parent.isFlag()){14 getJspBody().invoke(null);15 }16 }17 18 }
1 <tag><!-- choose標(biāo)簽 --> 2 <description>when otherwise</description> 3 <name>choose</name> 4 <tag-class>cn.wzbrilliant.el.ChooseTag</tag-class> 5 <body-content>scriptless</body-content> 6 </tag> 7 8 <tag><!-- when標(biāo)簽 --> 9 <description>when otherwise</description>10 <name>when</name>11 <tag-class>cn.wzbrilliant.el.WhenTag</tag-class>12 <body-content>scriptless</body-content>13 <attribute>14 <name>test</name>15 <required>true</required>16 <rtexprvalue>true</rtexprvalue>17 </attribute>18 </tag>19 20 <tag><!-- otherwise標(biāo)簽 -->21 <description>when otherwise</description>22 <name>otherwise</name>23 <tag-class>cn.wzbrilliant.el.OtherwiseTag</tag-class>24 <body-content>scriptless</body-content>25 </tag>
1 <% 2 pageContext.setAttribute("p", arr); 3 %> 4 5 6 <mytag:choose> 7 <mytag:when test="${empty p }"> 8 there is empty 9 </mytag:when>10 <mytag:otherwise>11 <mytag:forEach items="${p }" var="v">12 <br>${v}13 </mytag:forEach>14 </mytag:otherwise>15 </mytag:choose>
1 package cn.wzbrilliant.el; 2 3 import java.io.IOException; 4 import java.io.StringWriter; 5 6 import javax.servlet.jsp.JspException; 7 import javax.servlet.jsp.tagext.SimpleTagSupport; 8 9 public class HtmlTextFilterTag extends SimpleTagSupport {10 11 @Override12 public void doTag() throws JspException, IOException {13 StringWriter sw=new StringWriter();14 getJspBody().invoke(sw);15 String content=sw.toString();16 content = filter(content);17 getJspContext().getOut().write(content);18 }19 20 private String filter(String message) {21 if (message == null)22 return (null);23 24 char content[] = new char[message.length()];25 message.getChars(0, message.length(), content, 0);26 StringBuffer result = new StringBuffer(content.length + 50);27 for (int i = 0; i < content.length; i++) {28 switch (content[i]) {29 case '<':30 result.append("<");31 break;32 case '>':33 result.append(">");34 break;35 case '&':36 result.append("&");37 break;38 case '"':39 result.append(""");40 break;41 default:42 result.append(content[i]);43 }44 }45 return (result.toString());46 }47 }
1 <tag><!-- 文本中Html代碼過濾標(biāo)簽 -->2 <description>htmlfilter</description>3 <name>htmlfilter</name>4 <tag-class>cn.wzbrilliant.el.HtmlTextFilterTag</tag-class>5 <body-content>scriptless</body-content>6 </tag>
1 package cn.wzbrilliant.el; 2 3 import java.io.IOException; 4 5 import javax.servlet.http.HttpServletRequest; 6 import javax.servlet.http.HttpServletResponse; 7 import javax.servlet.jsp.JspException; 8 import javax.servlet.jsp.PageContext; 9 import javax.servlet.jsp.tagext.SimpleTagSupport;10 11 public class RefererTag extends SimpleTagSupport {12 private String site;13 private String redirectPath;14 15 public void setSite(String site) {16 this.site = site;17 }18 19 public void setRedirectPath(String redirectPath) {20 this.redirectPath = redirectPath;21 }22 23 @Override24 public void doTag() throws JspException, IOException {25 PageContext pageContext = (PageContext) getJspContext();26 HttpServletRequest request = (HttpServletRequest) pageContext.getRequest();27 HttpServletResponse response = (HttpServletResponse) pageContext.getResponse();28 String referer = request.getHeader("referer");29 if (referer != null && !referer.startsWith(site)) {30 String path;31 if (redirectPath.startsWith("/")) {32 path = request.getContextPath() + redirectPath;33 } else {34 String uri=request.getRequestURI();35 path=uri.substring(0, uri.lastIndexOf("/")+1)+redirectPath;36 }37 response.sendRedirect(path);38 }39 }40 41 }
1 <tag><!-- 防盜鏈 --> 2 <description>referer</description> 3 <name>referer</name> 4 <tag-class>cn.wzbrilliant.el.RefererTag</tag-class> 5 <body-content>empty</body-content> 6 <attribute> 7 <name>site</name> 8 <required>true</required> 9 <rtexprvalue>true</rtexprvalue>10 </attribute>11 <attribute>12 <name>redirectPath</name>13 <required>true</required>14 <rtexprvalue>true</rtexprvalue>15 </attribute>16 </tag>
新聞熱點
疑難解答