有這樣一個業務需求:
當我們在編輯某個用戶時,需要設置該用戶的角色,在轉到編輯頁面時,就需要自動勾選上該用戶已經選擇的角色,如下圖:
當我們點擊編輯時,會查詢用戶詳細信息,以及角色集合傳到編輯頁面。
用<c:forEach> 標簽將所有角色顯示出來,那如何勾選該用戶已經選擇的角色呢,角色是一個集合,用戶選擇的角色也是一個角色,在遍歷角色集合時,還需要查詢用戶的角色集合中是否有該角色...
以前使用過js,也可以使用<%java code%>,但都不是很方便,而且<%%>這種形式與JSP頁面不統一,不方便維護。
所以,自定義標簽此時就很方便了,就類似於<c:forEach>,與頁面也整體統一了。
--------------------------------------------------------------自定義標簽--------------------------------------------------------------
自定義標簽步驟:
1.實現SimpleTag接口/SimpleTagSupport類,重寫doTag()方法。
2.編寫標簽庫描述符(tld)文件,在tld文件中對自定義標簽進行描述,並放置在WEB-INF/目錄下。(如果需要打包的話,在src/下建META-INF文件夾,將tld文件放在該文件夾下)
3.完成以上操作,即可在JSP頁面中導入和使用自定義標簽。
以上面的需求為例:
第一步:自定義標簽類[該標簽不僅可以適用於復選框,還可以適用於單選框,下拉列表框等]
1 package com.lizhou.mobilescm.tag; 2 3 import java.io.IOException; 4 import java.util.ArrayList; 5 import java.util.Collection; 6 import java.util.Iterator; 7 import java.util.List; 8 import java.util.Map; 9 10 import javax.servlet.jsp.JspException; 11 import javax.servlet.jsp.JspWriter; 12 import javax.servlet.jsp.tagext.SimpleTagSupport; 13 14 /** 15 * 自定義標簽:根據數據將checkbox標記 16 * <my:check items="" value="" /> 17 * @author bojiangzhou 18 * @date 2016年4月10日 19 */ 20 /** 21 * <my:checked items="" value="" /> 22 * 輸出checked 23 * @author bojiangzhou 24 * @date 2016年5月4日 25 */ 26 public class CheckedTag extends SimpleTagSupport { 27 28 /** 29 * 要遍歷的數據:Map,List,Object[],Object 30 */ 31 private Object items; 32 33 /** 34 * 當前值 35 */ 36 private Object value; 37 38 public void setItems(Object items) { 39 this.items = items; 40 } 41 42 public void setValue(Object value) { 43 this.value = value; 44 } 45 46 public void doTag() throws IOException { 47 //獲取輸出流 48 JspWriter out = this.getJspContext().getOut(); 49 try { 50 if(items instanceof Collection){ 51 //items為Map、List類型 52 Collection collection = (Collection) items; 53 Iterator it = collection.iterator(); 54 while(it.hasNext()){ 55 Object next = it.next(); 56 if(next.equals(value)){ 57 out.write("checked"); 58 break; 59 } 60 } 61 } else if(items instanceof Object[]){ 62 //items為Object[]數組類型 63 Object[] array = (Object[]) items; 64 for(Object o : array){ 65 if(o.equals(value)){ 66 out.write("checked"); 67 break; 68 } 69 } 70 } else{ 71 //items為一個簡單數據類型 72 if(value.equals(items)){ 73 out.write("checked"); 74 } 75 } 76 } catch (Exception e) { 77 //如果有異常輸出空 78 out.write(""); 79 } 80 81 } 82 83 }
第二步:編寫tld文件(tld文件可以從其它標簽包里復制一份即可),記得放在WEB-INF/下,
1 <?xml version="1.0" encoding="UTF-8" ?> 2 3 <taglib xmlns="http://java.sun.com/xml/ns/j2ee" 4 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 5 xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee http://java.sun.com/xml/ns/j2ee/web-jsptaglibrary_2_0.xsd" 6 version="2.0"> 7 8 <description>my jstl 1.0</description> 9 <display-name>my jstl</display-name> 10 <tlib-version>1.0</tlib-version> 11 <short-name>my</short-name> <!-- 標簽前綴 --> 12 <uri>http://java.sun.com/jsp/jstl/my</uri> <!-- 引用地址 --> 13 14 <tag> 15 <description> 16 out checked 17 </description> 18 <name>checked</name> <!-- 標簽名稱 --> 19 <tag-class>com.lizhou.mobilescm.tag.CheckedTag</tag-class> <!-- 標簽使用的類 --> 20 <body-content>empty</body-content> <!-- 標簽體是否為空 --> 21 <attribute> <!-- 屬性 --> 22 <description> 23 Collection of items to iterate over. 24 </description> 25 <name>items</name> 26 <required>true</required> <!-- 是否必須 --> 27 <rtexprvalue>true</rtexprvalue> <!-- 是否可以使用JSP表達式 --> 28 </attribute> 29 <attribute> 30 <description> 31 Current value 32 </description> 33 <name>value</name> 34 <required>true</required> 35 <rtexprvalue>true</rtexprvalue> 36 </attribute> 37 </tag> 38 39 </taglib>
第三步:在JSP頁面使用
引入標簽:
<%@ taglib uri="http://java.sun.com/jsp/jstl/my" prefix="my" %>
使用:
1 <tr> 2 <th>角色:</th> 3 <td> 4 <c:forEach items="${roleList}" var="role"> 5 <input type="checkbox" name="user.roleIdList" value="${role.id}" <my:checked items="${user.roleIdList}" value="${role.id}"/> />${role.name} 6 </c:forEach> 7 </td> 8 </tr>
--------------------------------------------------------------自定義標簽:函數形式--------------------------------------------------------------
上面是使用標簽的形式,在項目中還學到一中自定義標簽的方式:函數形式
例如格式化Date類型的日期為字符串:
第一步:定義一個工具類,類中有一個格式化日期的靜態方法。[好像只能是靜態方法]
1 package com.lizhou.mobilescm.tool; 2 3 import java.text.SimpleDateFormat; 4 import java.util.Date; 5 6 /** 7 * 時間工具 8 * @author bojiangzhou 9 * @date 2016年5月4日 10 */ 11 public class TimeTool { 12 13 /** 14 * 將日期格式化成字符串 15 * @param date 日期 16 * @param pattern 格式:yyyy-MM-dd 17 * @return 18 */ 19 public static String formatDate(Date date){ 20 SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd"); 21 return sdf.format(date); 22 } 23 24 }
第二步:配置tld文件如下:
1 <?xml version="1.0" encoding="UTF-8" ?> 2 3 <taglib xmlns="http://java.sun.com/xml/ns/j2ee" 4 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 5 xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee http://java.sun.com/xml/ns/j2ee/web-jsptaglibrary_2_0.xsd" 6 version="2.0"> 7 8 <description>my jstl 1.0</description> 9 <display-name>my jstl</display-name> 10 <tlib-version>1.0</tlib-version> 11 <short-name>my</short-name> 12 <uri>http://java.sun.com/jsp/jstl/my</uri> 13 14 <function> 15 <description> 16 format the date to string 17 </description> 18 <name>dateFormat</name> <!-- 標簽名稱 --> 19 <function-class>com.lizhou.mobilescm.tool.TimeTool</function-class> <!-- 方法所在類 --> 20 <function-signature>java.lang.String formatDate(java.util.Date)</function-signature><!-- 方法簽名:格式:返回類型 方法名稱( 參數類型 ) --> 21 </function> 22 23 </taglib>
第三步:使用,在EL表達式中使用beginDate是在request中的一個Date類型日期。
1 <input name="beginDate" class="date" value='${my:dateFormat(beginDate)}' readonly/>
--------------------------------------------------------------自定義標簽:打包--------------------------------------------------------------
我們可以將自定義的標簽打包成一個jar/war包,形成自己的標簽庫,以便於以后使用。
那么,打包方式如下:
1.在src/目錄下建META-INF文件夾,將my.tld文件移動到該文件夾下
2.點擊項目,右鍵 > Export > 選擇Java下的JAR file > next >
3.然后就可以導入這個標簽包使用了
OK!