自定义标签

百度百科:

 

自定义标签

 编辑
一般我们说自定义标签是指JSP自定义标签。自定义标签在功能上逻辑上与javaBean 类似,都封装Java 代码。自定义标签是可重用的组件代码,并且允许开发人员为复杂的操作提供逻辑名称。
JSP开发人员使用标签库创建标签.标签库是按照功能或实现进行分组的自定义标签的集合。
网络上常见的CMS内容管理系统都是采用模板的形式来实现,基本上所有的CMS系统都有一套自己的模板标签书写方法,简称自定义标签。

基本概念

编辑
1.标签(Tag):
标签是一种XML元素,通过标签可以使JSP网页变得简洁并且易于维护,还可以方便地实现同一个JSP文件支持多种语言版本。由于标签是XML元素,所以它的名称和属性都是大小写敏感的
2.标签库(Tag library):
由一系列功能相似、逻辑上互相联系的标签构成的集合称为标签库。
3.标签库描述文件(Tag Library Descriptor):
标签库描述文件是一个XML文件,这个文件提供了标签库中类和JSP中对标签引用的映射关系。它是一个配置文件,和web.xml是类似的。
4.标签处理类(Tag Handle Class):
标签处理类是一个Java类,这个类继承了TagSupport或者扩展了SimpleTag接口,通过这个类可以实现自定义JSP标签的具体功能
 

简单自定义标签实现:
 
1.写自己要实现的标签功能,如打印一句话到jsp,添加一个标签类,extends javax.servlet.jsp.tagext.TagSupport类
public class HelloWorldTag extends TagSupport{

    /**
     * 
     */
    private static final long serialVersionUID = 1L;

    @Override
    public int doEndTag() throws JspException {
        // TODO Auto-generated method stub
        return super.doEndTag();
    }

    @Override
    public int doStartTag() throws JspException {
        JspWriter out = super.pageContext.getOut();
        try {
            out.println("hello,我是自定义标签的内容");
        } catch (IOException e) {
            e.printStackTrace();
        }
        return TagSupport.SKIP_BODY;//0:直接结束标签
    }
    
    
}

2.在WebRoot(eclipse中是WebContent)目录下,新建helloworld.tld标签文件

<?xml version="1.0" encoding="UTF-8" ?>

<taglib xmlns="http://java.sun.com/xml/ns/javaee"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-jsptaglibrary_2_1.xsd"
    version="2.1">
    <tlib-version>1.0</tlib-version>
    <short-name>helloWorldTag</short-name>
    
  <!-- 自定义标签 -->
  <tag>
      <name>helloworld</name>
      <tag-class>com.mlxs.tag.HelloWorldTag</tag-class>
      <body-content>empty</body-content>
  </tag>
</taglib>

3.在jsp中使用自定义标签

<%@ taglib prefix="mytag" uri="/mytag/helloworld.tld" %>

<body>
    <!-- 使用自定义标签 -->
    <mytag:helloworld/>
  </body>

4.访问页面验证

hello,我是自定义标签的内容

 
 
模仿一下集合遍历的标签:
 
1.IteratorTag类
/**
 * 模拟循环集合的标签类
 * @author Administrator
 *
 */
public class IteratorTag extends TagSupport{

    //单个元素的名称
    private String var;
    //集合名称
    private String items;
    //迭代器
    private Iterator iter=null;

    //getter和setter,从前台获取数据
    public String getVar() {
        return var;
    }
    public void setVar(String var) {
        this.var = var;
    }
    public String getItems() {
        return items;
    }
    public void setItems(String items) {
        this.items = items;
    }

    /**
     * 标签头
     */
    @Override
    public int doStartTag() throws JspException {
        //获取集合的value
        Object value = super.pageContext.getAttribute(items);
        //判断
        if(value!=null && value instanceof List){
            this.iter = ((List)value) .iterator();
            if(iter.hasNext()){
                this.pageContext.setAttribute(var, iter.next());//注意:此处的var不能加引号
                return TagSupport.EVAL_BODY_INCLUDE; //执行标签体
            }
        }else{
            //其他如map省略
            return TagSupport.SKIP_BODY;//0:直接结束标签
        }
        
        return TagSupport.SKIP_BODY;//0:直接结束标签
    }
    
    /**
     * 标签体结束后执行
     */
    @Override
    public int doAfterBody() throws JspException {
        if(iter.hasNext()){
            this.pageContext.setAttribute(var, iter.next());
            return TagSupport.EVAL_BODY_AGAIN; //再执行一次标签体
        }else{
            return TagSupport.SKIP_BODY;//0:直接结束标签
        }
    }
}

2.tld文件中:

<!-- 自定义标签 实现集合遍历 -->
  <tag>
      <name>iter</name>
      <tag-class>com.mlxs.tag.IteratorTag</tag-class>
      <body-content>JSP</body-content>
      <!-- 定义属性(参数) -->
      <attribute>
          <name>var</name>
          <required>true</required><!-- 是否必须传 -->
          <rtexprvalue>true</rtexprvalue><!-- 是否支持EL表达式 -->
      </attribute>
      <attribute>
          <name>items</name>
          <required>true</required><!-- 是否必须传 -->
          <rtexprvalue>true</rtexprvalue><!-- 是否支持EL表达式 -->
      </attribute>
  </tag>

3.jsp访问

<%@ page language="java" import="java.util.*" pageEncoding="utf-8"%>
<%@ taglib prefix="mytag" uri="/mytag/helloworld.tld" %>

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
  <head>
    
    <title>My JSP 'index.jsp' starting page</title>
    <meta http-equiv="pragma" content="no-cache">
    <meta http-equiv="cache-control" content="no-cache">
    <meta http-equiv="expires" content="0">    
    <meta http-equiv="keywords" content="keyword1,keyword2,keyword3">
    <meta http-equiv="description" content="This is my page">
  </head>
  
  <body>
      <%
        List list = new ArrayList();
        list.add("0");
        list.add("2");
        list.add("44");
        list.add("10哈哈");
        //存储在application
        pageContext.setAttribute("list", list);
     %>
    <!-- 使用自定义标签 -->
    <mytag:iter items="list" var="result">
        <h2>${result }</h2>
    </mytag:iter>
  </body>
</html>

4.访问

0

2

44

10哈哈


 

还有一种更简洁的方式,extends SimpleTagSupport,只需要重写doTag方法,然后再tld的标签中这样配置:<body-content>scriptless</body-content>

/**
 * 模拟循环集合的标签类
 * @author Administrator
 *
 */
public class IteratorSimpleTag extends SimpleTagSupport{

    //单个元素的名称
    private String var;
    //集合名称
    private String items;
    //迭代器
    private Iterator iter=null;

    //getter和setter,从前台获取数据
    public String getVar() {
        return var;
    }
    public void setVar(String var) {
        this.var = var;
    }
    public String getItems() {
        return items;
    }
    public void setItems(String items) {
        this.items = items;
    }

    /**
     * 标签
     */
    @Override
    public void doTag() throws JspException {
        //获取集合的value
        Object value = super.getJspContext().getAttribute(items);
        //判断
        if(value!=null && value instanceof List){
            this.iter = ((List)value) .iterator();
            while(iter.hasNext()){
                this.getJspContext().setAttribute(var, iter.next());//注意:此处的var不能加引号
                try {
                    this.getJspBody().invoke(null);//响应页面
                } catch (IOException e) {
                    e.printStackTrace();
                } 
            }
        }
    }
    
}

 

posted @ 2016-03-17 23:25  艺言弈行  阅读(396)  评论(0编辑  收藏  举报