利用
自定义标签,软件开发人员和页面设计人员可以独立地自由工作.页面设计人员可以把精力集中在使用标签(HTML,XML或者JSP)创建网站上,而软件开发人员则可以将精力集中在实现底层功能上面,若国际化等等,这样,页面设计人员可以使用自定义标签的形式来实现具体的功能.

1.JSP标签编程简介

下面我们来指定一个简单的标签,步骤如下

 
 标签编程在开发中并不常见,主要是为了更好的理解struts等框架的标签而打基础,完善相关知识体系。

  1. 扩张TagSupport
  2. 写自定义Tag的tld文件
  3. web.xml中指定你的tld文件
  4. 在JSP页面使用自定义标签

   标签编程分为:

  • 扩张TagSupport

 
 一个继承自TagSupport的标签类,一个在WEB-INFO文件夹下的标签库文件.tld(该库文件主要用来将标签名称与标签类对应起来),

        说明:
               
一般不会去实现Tag接口,而是通过TagSupport类是实现了Tag的接口继承过来的字段,这些字段用做public
int               doStartTag(),public int doEndTag()返回值
                Tag.EVAL_BODY_INCLUDE 包含主体内容
                Tag.SKIP_BODY     不包含主体内容
                Tag.EVAL_PAGE      包含后面的页面内容
                Tag.SKIP_PAGE     不包含主体的内容    
实现一个简单实现代码:

 
 需要在web.xml中编辑标签的URL主要与上面生成的标签库文件对应,在JSP中引用URL,并在文件体中
引用该标签名。

java 代码

 
 注意:如果提示相应的包找不到,可以在tomcat的lib文件夹下找相应的lib文件,并拷贝到jdk/jre/lib/ext文件夹中。

 

 

  1. package com.mercyblitz;  
  2. import java.io.IOException;  
  3. import javax.servlet.jsp.JspException;  
  4. import javax.servlet.jsp.JspWriter;  
  5. import javax.servlet.jsp.tagext.TagSupport;  
  6.   
  7. public class MyTags extends TagSupport {  
  8.     public int doStartTag()throws JspException  
  9.     {  
  10.         JspWriter out=pageContext.getOut();  
  11.         try  
  12.         {  
  13.             out.println(“Hello,World”); //页面中显示的内容  
  14.         }catch(IOException e)  
  15.         {  
  16.             throw new JspException(e);  
  17.         }  
  18.         return SKIP_BODY; //不包含主体内容  
  19.     }  
  20. }  

==========================================源代码

   a.继承自TagSuppor的的标签类

package cn.liys.taglib;
import javax.servlet.jsp.*;
import javax.servlet.jsp.tagext.*;
public class HelloTag extends TagSupport{
public int doStartTag() throws JspException{ //在标签开始时执行
JspWriter out =super.pageContext.getOut();
try {
out.println(“<h1>Hello World!</h1>”);
}catch (Exception e){

}
return TagSupport.SKIP_BODY;
}

}

 

  b.编写一个标签库文件 .tlb

 

<?xml version=”1.0″ encoding=”UTF-8″?>
<taglib xmlns=””
xmlns:xsi=””
xsi:schemaLocation=”

version=”2.1″>
<tlib-version>1.0</tlib-version>
<short-name>firsttag</short-name>
<tag>
<name>hello</name>                                      
//标签名
<tag-class>cn.liys.taglib.HelloTag</tag-class>
 //与标签类对应
<body-content>empty</body-content>//标签体为空
</tag>
</taglib>

 

  c.在web.xml中将标签库文件与标签URL对应

<jsp-config>
<taglib>
<taglib-uri>hello_tag</taglib-uri>                        
            //标签库名
<taglib-location>/WEB-INF/hellotag.tld</taglib-location>
//标签库的路径
</taglib>
</jsp-config>

 

  d.在jsp文件中将该标签拿来引用

<%@page contentType=”text/html” pageEncoding=”GBK”%>
<%@taglib prefix=”mytag” uri=”hello_tag”%>
//web.xml中的标签库名
<html>
<head>
</head>
<body>
<h1><mytag:hello/></h1> //标签库中的标签名
</body>

</html>

 

 *******************************************************************************************************************************

2.定义有属性的标签

 

在标签类中,设置属性,并编写getter,setter方法,在doStartTag中即可使用该属性。

ackage cn.liys.taglib;
import java.util.*;
import java.text.*;
import javax.servlet.jsp.*;
import javax.servlet.jsp.tagext.*;
public class DateTag extends TagSupport{
private String format;

public int doStartTag() throws JspException{
SimpleDateFormat sdf = new SimpleDateFormat(this.format);

JspWriter out =super.pageContext.getOut();
try {
澳门新葡亰8455下载app ,out.println(sdf.format(new Date()));
}catch (Exception e){

}
return TagSupport.SKIP_BODY;
}

public void setFormat(String fmt){
this.format = fmt;
}

public String getFormat(){
return this.format;
}

}

 

在WEB-INF文件夹中生成 标签库文件 datetag.tld

<?xml version=”1.0″ encoding=”UTF-8″?>
<taglib xmlns=””
xmlns:xsi=””
xsi:schemaLocation=”

version=”2.1″>
<tlib-version>1.0</tlib-version>
<short-name>firsttag</short-name>
<tag>
<name>date</name>
<tag-class>cn.liys.taglib.DateTag</tag-class>
<body-content>empty</body-content>
<attribute>             <!–注意需要在tag中设置属性–>
<name>format</name>
<required>true</required>  <!–必输项–>
<rtexprvalue>true</rtexprvalue><!–支持表达式输出–>
</attribute>
</tag>
</taglib>

 

在web.xml中进行url与标签库文件的对应配置

……

<jsp-config>
<taglib>
<taglib-uri>hello_tag</taglib-uri>
<taglib-location>/WEB-INF/hellotag.tld</taglib-location>
</taglib>
<taglib>
<taglib-uri>date_tag</taglib-uri>
<taglib-location>/WEB-INF/datetag.tld</taglib-location>
</taglib>
</jsp-config>

……

 

在jsp页面中使用

<%@page contentType=”text/html” pageEncoding=”GBK”%>
<%@taglib prefix=”mytag” uri=”date_tag”%>
<html>
<head>
</head>
<body>
<h1><mytag:date format=”yyyy-MM-dd
HH:mm:ss.SSS”/></h1>
</body>

</html>

 

 *******************************************************************************************************************************

3.标签体的执行

   a. 通过标签类的doStartTag函数返回值来决定是否执行标签体。

    return TagSupport.EVAL_BODY_INCLUDE;   //执行标签体

    return TagSupport.SKIP_BODY;                    //跳过标签体

 

   

  b.配置对应的标签库文件.tlb(标签,标签名,标签对应的类,标签内容 JSP,
属性….)

     …

  

<tag>
<name>present</name>
<tag-class>cn.liys.taglib.MldnTag</tag-class>
<body-content>JSP</body-content>
<attribute>
<name>name</name>
<required>true</required>
<rtexprvalue>true</rtexprvalue>
</attribute>
<attribute>
<name>scope</name>
<required>true</required>
<rtexprvalue>true</rtexprvalue>
</attribute>
</tag>

     …

 

c. web.xml(uri 与 库文件名对应)

  

<jsp-config>
<taglib>
<taglib-uri>hello_tag</taglib-uri>
<taglib-location>/WEB-INF/hellotag.tld</taglib-location>
</taglib>
</jsp-config>

 d. jsp中的代码片段

    <%@ taglib prefix=”mytag” uri=”mldn_tag”%> 

    …….

  <mytag:present name=”username” scope=”<%=scope%>”>
 <!–根据属性执行标签类,来判断是否执行标签体–>
  <h2><%=scope%>范围存在属性,内容是:“${sessionScope.username}”</h2>
  </mytag:present>

    …….

    

 

 *******************************************************************************************************************************

4.迭代标签

通过标签编程,实现list<?>对象的迭代。

判断标签类(判断是否要进行下一步迭代,同上),迭代标签类,标签库文件,web.xml,JSP

迭代标签类: //一下为关键代码段

……

private Iterator<?> iter = null ;

doStartTag( ){

Object value = null ;

….

 value =
super.pageContext.getAttribute(this.name,PageContext.PAGE_SCOPE) ;

….

if(value!=null && value instanceof List<?>){
this.iter = ((List<?>)value).iterator() ;
if(iter.hasNext()){
// 将属性保存在page属性范围之中
super.pageContext.setAttribute(this.id,iter.next()) ;
return TagSupport.EVAL_BODY_INCLUDE ;  //执行标签体
} else {
return TagSupport.SKIP_BODY ;
}
} else {
return TagSupport.SKIP_BODY ;
}

}

 

public int doAfterBody()  //实现迭代循环
throws JspException{
if(iter.hasNext()){
// 将属性保存在page属性范围之中
super.pageContext.setAttribute(this.id,iter.next()) ;
return TagSupport.EVAL_BODY_AGAIN ; // 反复执行doAfterBody()方法
} else {
return TagSupport.SKIP_BODY ;
}
}

….

 

标签库文件与web.xml的配置同上,此处省略

 

iteratetag.jsp

<%@ taglib prefix=”mytag” uri=”mldn”%>

。。。

<% // 此代码只是为了测试,实际中此部分应该由servlet传递
List<String> all = new ArrayList<String>() ;
all.add(“www.MLDN.cn”) ;
all.add(“www.MLDNJAVA.cn”) ;
all.add(“www.JIANGKER.com”) ;
request.setAttribute(“all”,all) ; // 将内容保存在标签执行
%>

<mytag:present name=”all” scope=”request”>
<mytag:iterate id=”url” name=”all” scope=”request”>
<h3>网站:${url}</h3>
</mytag:iterate>
</mytag:present>

 

  

 *******************************************************************************************************************************

4.简单标签库 SimpleTagSupport

  不再需要doStartTag() doAfterBody()等函数,直接一个doTag()函数即可。 

  public class SimpleDateTag extends SimpleTagSupport {

  private String format ; //
日期格式化属性

  … 

public void doTag() throws JspException,IOException{
SimpleDateFormat sdf = new SimpleDateFormat(this.format) ;
try{
super.getJspContext().getOut().write(sdf.format(new Date())) ;
}catch(Exception e){}
}

 …}

Iterator 标签类:

Object value = null ;

value =
super.getJspContext().getAttribute(this.name,PageContext.PAGE_SCOPE) ;

…..

if(value != null && value instanceof List<?>){
Iterator<?> iter = ((List<?>) value).iterator() ;
while(iter.hasNext()){
super.getJspContext().setAttribute(id,iter.next()) ;
super.getJspBody().invoke(null) ;
}
}

jsp页面使用该标签库

<% //此处只是测试用,属性应该是servlet返回的
List<String> all = new ArrayList<String>() ;
all.add(“www.MLDN.cn”) ;
all.add(“www.MLDNJAVA.cn”) ;
all.add(“www.JIANGKER.com”) ;
request.setAttribute(“all”,all) ;
%>
<h1>
<mytag:simpleiterate id=”url” name=”all” scope=”request”>
<h2>网站:${url}</h2>
</mytag:simpleiterate>
</h1>

 

 *******************************************************************************************************************************

4.标签的动态属性

   以一个动态属性相加为例子,tag标签中可以设置n个float
属性,页面将输出这些值相加的结果。

   动态属性标签类的片段:

   public class DynamicAddTag extends SimpleTagSupport implements
DynamicAttributes {  //继承简单标签支持类,实现动态属性接口类

  private Map<String,Float> num = new
HashMap<String,Float>() ;  //申明一个Map集合

 

public void doTag()  //根据 setDynamicAttribute
函数取出的动态属性,相加,将结果输出到页面上
throws JspException,
IOException{
Float sum = 0.0f ;
Iterator<Map.Entry<String,Float>> iter =
this.num.entrySet().iterator() ;
while(iter.hasNext()){
Map.Entry<String,Float> value = iter.next() ;
sum += value.getValue() ; // 取出每一个内容
}
super.getJspContext().getOut().write(sum + “”) ;
}

public void setDynamicAttribute(String uri,
String localName,
Object value)
throws JspException{
//循环 取出设置的每一个动态属性,都保存在Map集合里
num.put(localName,Float.parseFloat(value.toString())) ;
}

   }

 

标签库文件.tld中增加标签配置内容

<tag>
<name>add</name>
<tag-class>org.lxh.tagdemo.DynamicAddTag</tag-class>
<body-content>empty</body-content>
<dynamic-attributes>true</dynamic-attributes>
 <!–接收动态标签–>
</tag>

 

web.xml内容省略,uri与标签库文件对应

 

jsp内容

<%@ taglib prefix=”mytag” uri=”mldn”%>

<h2>计算结果:
<mytag:add num1=”11.2″ num2=”12.3″ num3=”13.5″/>
</h2>
</body>
</html>

 

 

    

  

  

  

 

  

  • 写自定义Tag的tld文件

xml 代码

网站地图xml地图