比如我們需要在頁面上定義一個下拉框控件(Select),我們需要加載從數據庫中查出來的數據。我們就可以通過定義select標籤的方式,將SQL查詢,組織數據,如循環遍歷等事情全部在jsp標籤類中實現。 這樣有什麼好處呢?
主要目的是爲了取代醜陋的jsp腳本,在Html頁面中插入JSP有幾個壞處:
- JSP腳本非常醜陋,難以閱讀。
- JSP腳本和HTML代碼混雜,維護成本高。
- HTML頁面中嵌入JSP腳本,導致美工人員難以參與開發。
所以出於以上的考慮,就有了自定義標籤,自定義標籤一方面具有和HTML類似的語法,一方面又可以完成JSP腳本的功能。同時,使用自定義標籤可以複用,例入在系統中很多頁面都需要用到下拉框循環遍歷從數據庫中查詢的數據,如果是平時,每個人用一次就得循環一次,但是有了自定義標籤,只需要引用標籤就可以了,遍歷的功能都封裝到了標籤內部。 不多說了,下面我就具體來介紹一下自定義標籤吧。
一、基本概念:
標籤是一種XML元素,通過標籤可以使JSP網頁變得簡潔並且易於維護。標籤庫是由一系列功能相似、邏輯上互相聯繫的標籤構成的集合稱爲標籤庫。 標籤庫描述文件是一個XML文件,這個文件提供了標籤庫中類和JSP中對標籤引用的映射關係。 標籤處理類是一個Java類,這個類繼承了TagSupport或者擴展了SimpleTag接口,通過這個類可以實現自定義jsp標籤的具體功能。
二、 創建基本步驟
- 開發自定義標籤的處理類,下面是一個處理地域字典的標籤類
- 提供屬性的get和set方法
- 處理doStartTag 或doEndTag方法
這兩個方法是TagSupport提供的。例如<zw:areaInfo… />,當jsp解析這個標籤的時候,在"<" 出觸發doStartTag事件,在">"時觸發doEndTag事件。一般doStartTag裏進行邏輯操作,在doEndTag進行控制輸出。代碼如下:
<pre name="code" class="java">public class AreaInfoTag extends TagSupport{
private static final long serialVersionUID = 6306592846049270874L;
//標籤數據的使用類型:new:新增;edit:修改;query:查詢]
private String useType;
// 選中父的標籤 對應 AreaInfo 中的 SGuid
private String parentCode;
// 選中的子標籤 對應 AreaInfo 中的 SGuid
private String childrenCode;
// 選中父標籤回填屬性]</p>
private String parentName;
// 選中子標籤回填屬性]
private String childrenName;
// select 的父類名]
private String parentClassName;
// select 的子類名]
private String childrenClassName;
// 父標籤的id名稱]
private String parentId;
//子標籤的id名稱]
private String childrenId;
// 標籤數據的生效時間]
private String beginDate;
// 標籤數據的失效時間]
private String endDate;
private IAreaInfoService areaService;
@Override
public int doEndTag() throws JspException {
JspWriter writer = pageContext.getOut();
StringBuffer buf = new StringBuffer();
try{
if(areaService==null){
areaService = (IAreaInfoService)SpringUtils.getBean("areaInfoService");
}
if(parentClassName==null||parentClassName.equals("")){
buf.append("<select id=\""+parentId+"\" οnchange=\"changeParent(this,'"+childrenId+"')\"; name=\""+parentName+"\">");
}else{
buf.append("<select id=\""+parentId+"\" οnchange=\"changeParent(this,'"+childrenId+"')\"; name=\""+parentName+"\" class=\""+parentClassName+"\">");
}
buf.append("<option value=\"\">--請選擇--</option>");
List<AreaInfo> areaList = areaService.getAreaList(Constants.AREA_SUPER_SGUID, useType, beginDate, endDate);
for (AreaInfo area : areaList) {
if(area.getSGuid().trim().equals(parentCode.trim())){
buf.append("<option selected=\"selected\" value=\""+StringUtil.getTrim(area.getSGuid())+"\">"+area.getSDictName()+"</option>");
}else{
buf.append("<option value=\""+StringUtil.getTrim(area.getSGuid())+"\">"+area.getSDictName()+"</option>");
}
}
buf.append("</select>");
if(childrenClassName==null||childrenClassName.equals("")){
buf.append("<select id=\""+childrenId+"\" name=\""+childrenName+"\">");
}else{
buf.append("<select id=\""+childrenId+"\" name=\""+childrenName+"\" class=\""+childrenClassName+"\">");
}
buf.append("<option value=\"\">--請選擇--</option>");
if(childrenCode!=null&&!childrenCode.equals("")){
List<AreaInfo> subAreas = areaService.getAreaList(parentCode);
for (AreaInfo area : subAreas) {
if(area.getSGuid().trim().equals(childrenCode.trim())){
buf.append("<option selected=\"selected\" value=\""+StringUtil.getTrim(area.getSGuid())+"\">"+area.getSDictName()+"</option>");
}else{
buf.append("<option value=\""+StringUtil.getTrim(area.getSGuid())+"\">"+area.getSDictName()+"</option>");
}
}
}
buf.append("</select>");
System.out.println("buf:"+buf);
writer.write(buf.toString());
writer.flush();
}catch(Exception e){
e.printStackTrace();
}
return super.doEndTag();
}
public String getParentCode() {
return parentCode;
}
public void setParentCode(String parentCode) {
this.parentCode = parentCode;
}
public String getChildrenCode() {
return childrenCode;
}
public void setChildrenCode(String childrenCode) {
this.childrenCode = childrenCode;
}
public String getParentName() {
return parentName;
}
public void setParentName(String parentName) {
this.parentName = parentName;
}
public String getChildrenName() {
return childrenName;
}
public void setChildrenName(String childrenName) {
this.childrenName = childrenName;
}
public String getParentId() {
return parentId;
}
public void setParentId(String parentId) {
this.parentId = parentId;
}
public String getChildrenId() {
return childrenId;
}
public void setChildrenId(String childrenId) {
this.childrenId = childrenId;
}
public String getParentClassName() {
return parentClassName;
}
public void setParentClassName(String parentClassName) {
this.parentClassName = parentClassName;
}
public String getChildrenClassName() {
return childrenClassName;
}
public void setChildrenClassName(String childrenClassName) {
this.childrenClassName = childrenClassName;
}
public String getUseType() {
return useType;
}
public void setUseType(String useType) {
this.useType = useType;
}
public String getBeginDate() {
return beginDate;
}
public void setBeginDate(String beginDate) {
this.beginDate = beginDate;
}
public String getEndDate() {
return endDate;
}
public void setEndDate(String endDate) {
this.endDate = endDate;
}
}
2. 編寫tld 文件 每個自定義標籤都必須在tld文件中聲明,tld文件只不過一個xml文件。根元素是<taglib>,它包含一個或者多個<tag>標籤,該元素用來聲明定製標籤。
<?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>A tag library exercising SimpleTag handlers.</description>
<tlib-version>1.0</tlib-version>
<short-name>zw</short-name>
<uri>http://com.zlwy.frameTemplate/common/functions</uri>
<tag>
<description> AreaInfoTag </description>
<name>areaInfo</name>
<tag-class>com.zlwy.organ.tag.AreaInfoTag</tag-class>
<attribute>
<name>parentCode</name>
<required>false</required>
<rtexprvalue>true</rtexprvalue>
</attribute>
<attribute>
<name>childrenCode</name>
<required>false</required>
<rtexprvalue>true</rtexprvalue>
</attribute>
<attribute>
<name>parentClassName</name>
<required>false</required>
<rtexprvalue>true</rtexprvalue>
</attribute>
<attribute>
<name>childrenClassName</name>
<required>false</required>
<rtexprvalue>true</rtexprvalue>
</attribute>
<attribute>
<name>parentName</name>
<required>true</required>
<rtexprvalue>true</rtexprvalue>
</attribute>
<attribute>
<name>childrenName</name>
<required>true</required>
<rtexprvalue>true</rtexprvalue>
</attribute>
<attribute>
<name>parentId</name>
<required>true</required>
<rtexprvalue>true</rtexprvalue>
</attribute>
<attribute>
<name>childrenId</name>
<required>true</required>
<rtexprvalue>true</rtexprvalue>
</attribute>
<attribute>
<name>useType</name>
<required>true</required>
<rtexprvalue>false</rtexprvalue>
</attribute>
<attribute>
<name>beginDate</name>
<required>false</required>
<rtexprvalue>true</rtexprvalue>
</attribute>
</tag>
<taglib> : tld文件的根元素 (必須)
<taglib-version> : 此標籤庫的版本 (必須)
<short-name> : 當在JSP中使用標籤時,此標籤庫首選或者建議的前綴。
<description> :描述信息
<uri> : 指定使用該標籤庫中標籤的 URI
3. 在jsp中使用自定義標籤
<pre name="code" class="html"><zw:areaInfo parentCode="${listPersonInsuranceTypeInfo.SWholeProvinceGuid}" parentClassName="content_content_select" childrenClassName="content_content_select"
childrenName="listPersonInsuranceTypeInfo[${st.count - 1}].SWholeCityGuid" parentName="listPersonInsuranceTypeInfo[${st.count - 1}].SWholeProvinceGuid" parentId="pt${st.count-1}"
useType="new" childrenId="cn${st.count - 1}" childrenCode="${listPersonInsuranceTypeInfo.SWholeCityGuid}">
</zw:areaInfo>
總結:在平時的開發中jsp自定義標籤經常被使用,從上面的例子中可以看出,自定義標籤實現了特定的java類,封裝了java代碼編寫的預定義行爲,在運行時,標籤被替換成相應的java代碼。 簡化了我們的jsp文件。