比如我们需要在页面上定义一个下拉框控件(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文件。