自定义标签

 
一、概述
我们在进行javaweb开发时,jsp页面上经常会用到jstl标签和structs标签,但是有时候这些标签并不能满足我们的要求,这个时候就需要或者可以通过自定义标签的方式来满足我们要实现的功能。

二、自定义标签的组成
自定义标签一般由三部分组成,准确的说是两部分,第三部分是我们在jsp页面中引用我们自定义的标签,然后使用。
  1. 标签的处理程序(Java类)
  2. tld文件:标签的描述符文件(.tld文件要放在和web.xml同一级目录下)
  3. 引用标签,使用taglib引入到jsp中

三、自定义标签的作用
  1. 使我们的Java代码和JSP页面彻底分离
  2. 还可以使我们的代码更安全(页面中没有算法、商业业务逻辑等)
  3. 提供了可重用的功能组件

四、标签处理程序的编写


标签处理程序必须实现接口或者继承类,实现Tag和BodyTag接口可以自定义带有标签体和属性的标签,实现SimpleTag接口只能自定义最简单的标签(没有标签体,也没有属性)。而TagSupport、BodyTagSupport、SimpleTagSupport类正好是Tag、BodyTag、SimpleTag接口的实现类。


五、几个简单的例子
示例1:没有标签体,也没有属性
//标签处理程序
package com.wangyi.tag;
import java.io.IOException;
import javax.servlet.jsp.JspContext;
import javax.servlet.jsp.JspException;
import javax.servlet.jsp.JspWriter;
import javax.servlet.jsp.PageContext;
import javax.servlet.jsp.tagext.SimpleTagSupport;
/**
 * 自定义标签1:没有标签体,也没有属性
 */
public class WelcomeTag extends SimpleTagSupport {
       /*
       * 当 jsp 页面执行该标签处理程序所指定的标签的时候,执行该方法
       */
       @Override
    public void doTag() throws JspException, IOException {
              //获得当前 jsp 页面的上下文对象
            JspContext jc = this . getJspContext ();
             //获得该 jsp 页面上下文对象的输出流
            JspWriter out = jc .getOut();
             //获得session中的user属性
            Object obj = jc . getAttribute ( "user" ,PageContext. SESSION_SCOPE );
             if ( obj != null ){ //如果session中存在user属性
                   out .println( "成功!" );
            } else { //如果不存在
                   out .println( "<a href=''>登录</a>" );
            }     
    }
      
}

//标签的描述符文件文件(.tld文件)
<? xml version = "1.0" encoding = "UTF-8" ?>
< taglib xmlns = " http://java.sun.com/xml/ns/j2ee" ;
  version = "2.0" >
   
  < description > welcomeTag </ description >
  < display-name > welcomeTag </ display-name >
  < tlib-version > 1.0 </ tlib-version >
  <!-- 指定标签库默认的前缀名(prefix) -->
  < short-name > wt </ short-name >
  <!-- 在 jsp 页面中引入该标签的 url -->
  < uri > http://www.wangyi.com/welcome </ uri >
   <!-- 一个.tld中可以定义多个tag,一个tag代表一个标签 -->
  < tag >
       <!-- 标签的名称 -->
       < name > welcomeTag </ name >
       <!-- 标签处理程序类 -->
       < tag-class > com.wangyi.tag.WelcomeTag </ tag-class >
       <!-- 设定标签间的主体(body)内容形式
            只有三种值:
                jsp :表示标签间可有主体内容
                empty:表示标签间不能有主体内容
                Tagdependent :表示标签间主体内容由标签自行处理
       -->
       < body-content > empty </ body-content >
  </ tag >
</ taglib >

示例2:有标签体,但是没有属性
//标签处理程序
package com.wangyi.tag;
import java.io.IOException;
import javax.servlet.jsp.JspException;
import javax.servlet.jsp.JspWriter;
import javax.servlet.jsp.tagext.BodyContent;
import javax.servlet.jsp.tagext.BodyTagSupport;
/**
 * 自定义标签2:有标签体,但没有属性
 */
public class TestTag extends BodyTagSupport {
       /**
       * 当 jsp 页面执行到某个标签结束的时候,执行该方法处理标签体的内容
       */
       @Override
       public int doAfterBody() throws JspException {
             //获得该标签的标签体
            BodyContent bc = this .getBodyContent();
             //获得该标签的标签体的输出流
            JspWriter out = bc .getEnclosingWriter();
             //获得标签体的内容
            String content = bc .getString();
             try {
                   out .println( content .toUpperCase());
            } catch (IOException e ) {
                   e .printStackTrace();
            }
             return this . EVAL_PAGE ; //该返回值告诉 jsp 页面,这个标签执行完毕,可以去执行页面中的其他标签了
      }
      
      
}

//标签的描述符文件文件(.tld文件)
  < tag >
       < name > testTag </ name >
       < tag-class > com.wangyi.tag.TestTag </ tag-class >
       < body-content > JSP </ body-content >
  </ tag >

//页面:
<%@ page language = "java" contentType = "text/html; charset=UTF-8" pageEncoding = "UTF-8" %>
<!-- 引入自定义标签 -->
<%@ taglib uri = " http://www.wangyi.com/welcome" ; prefix = "wt" %>
<! DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" " http://www.w3.org/TR/html4/loose.dtd" ; >
< html >
< head >
< meta http-equiv = "Content-Type" content = "text/html; charset=UTF-8" >
< title > 自定义标签1 </ title >
</ head >
< body >
      自定义标签1: < wt:welcomeTag />
       < br >
      自定义标签2: < wt:testTag > this is second custom tag. </ wt:testTag >
</ body >
</ html >

示例3:通用的分页标签

//标签处理程序
package com.wangyi.tag;
import java.io.IOException;
import java.text.MessageFormat;
import javax.servlet.jsp.JspException;
import javax.servlet.jsp.JspWriter;
import javax.servlet.jsp.tagext.TagSupport;
/**
 * 自定义分页标签
 */
public class PageTag extends TagSupport {
      
       private int nowPage = 1; //当前页
       private int pageSize = 4; //分页大小
       private int count = 0;   //总记录数
       private String url ;      //访问 url
      
       public int getNowPage() {
             return nowPage ;
      }
       public void setNowPage( int nowPage ) {
             this . nowPage = nowPage ;
      }
       public int getPageSize() {
             return pageSize ;
      }
       public void setPageSize( int pageSize ) {
             this . pageSize = pageSize ;
      }
       public int getCount() {
             return count ;
      }
       public void setCount( int count ) {
             this . count = count ;
      }
       public String getUrl() {
             return url ;
      }
       public void setUrl(String url ) {
             this . url = url ;
      }
      
       /**
       * 当 jsp 页面遇到了分页标签的时候执行该方法。
       * 这个标签一定是有属性的,这些属性就是给我们这个类的属性赋值(通过反射调用setter方法)
       */
       @Override
       public int doStartTag() throws JspException {
             //总页数的计算
             int allPage = count % pageSize == 0 ? count / pageSize : count / pageSize + 1;
            
             //特殊当前页处理
             if ( nowPage <= 1){
                   nowPage = 1;
            }
            
             if ( nowPage >= allPage ){
                   nowPage = allPage ;
            }
            
             //超链接的模板,第一个占位{0}:访问 url ,第二个占位{1}:当前页,第三个占位{2}:该链接的显示文字
            String link = "<a href=''{0}?page={1}''>{2}</a>" ;
            
             //MessageFormat.format()方法:第一个参数是字符串模板,其他参数均为字符串模板中需要填充的占位
             //首页
            String first = MessageFormat. format ( link , url , "1" , "首页" );
             //上一页
            String up = "上一页" ;
             if ( nowPage >  1){
                   up = MessageFormat. format ( link , url , nowPage -1+ "" , "上一页" );
            }
            
             //下一页
            String next = "下一页" ;
             if ( nowPage < allPage ){
                   next = MessageFormat. format ( link , url , nowPage +1+ "" , "下一页" );
            }
            
             //尾页
            String last = MessageFormat. format ( link , url , allPage + "" , "尾页" );
            
             //htmlString:在 jsp 页面上显示的分页块元素
            String htmlString = "{0} {1} {2} {3}&nbsp;&nbsp;&nbsp;&nbsp;共{4}页,第{5}页,分页单位:{6},共{7}条" ;
             htmlString = MessageFormat. format ( htmlString , first , up , next , last , allPage + "" , nowPage + "" , pageSize + "" , count );
            
             //将htmlString输出到页面中
            JspWriter out = this . pageContext .getOut();
             try {
                   out .println( htmlString );
            } catch (IOException e ) {
                   e .printStackTrace();
            }
            
             return this . EVAL_PAGE ; 该返回值告诉 jsp 页面,这个标签执行完毕,可以去执行页面中的其他标签了
      }
}

//标签的描述符文件文件(.tld文件)
<? xml version = "1.0" encoding = "UTF-8" ?>
< taglib xmlns = " http://java.sun.com/xml/ns/j2ee" ;
  version = "2.0" >
   
  < description > welcomeTag </ description >
  < display-name > welcomeTag </ display-name >
  < tlib-version > 1.0 </ tlib-version >
  <!-- 指定标签库默认的前缀名(prefix) -->
  < short-name > wt </ short-name >
  <!-- 在 jsp 页面中引入该标签的 url ,也可以不写该元素,然后通过引入该 tld 文件的方式来引入该 tld 里面的标签 -->
  <!-- <uri> http://www.wangyi.com/page</uri> ; -->
  < tag >
       < name > page </ name >
       < tag-class > com.wangyi.tag.PageTag </ tag-class >
       < body-content > empty </ body-content >
      
       <!-- 定义标签体的属性 -->
       < attribute >
             < name > nowPage </ name >
             < required > true </ required >
             < rtexprvalue > true </ rtexprvalue >
       </ attribute >
       < attribute >
             < name > pageSize </ name >
             < required > true </ required >
             < rtexprvalue > true </ rtexprvalue >
       </ attribute >
       < attribute >
             < name > count </ name >
             < required > true </ required >
             < rtexprvalue > true </ rtexprvalue >
       </ attribute >
       < attribute >
             < name > url </ name >
             < required > true </ required >
             < rtexprvalue > true </ rtexprvalue >
       </ attribute >
  </ tag >
</ taglib >

//页面:
<%@ page language = "java" contentType = "text/html; charset=UTF-8" pageEncoding = "UTF-8" %>
<%@ taglib uri = " http://java.sun.com/jstl/core_rt" ; prefix = "c" %>
<!-- 引入自定义标签,采用 tld 文件中 url 的方式 -->
<%@ taglib uri = " http://www.wangyi.com/welcome" ; prefix = "wt" %>
<!-- 引入自定义标签,采用直接引入标签描述符文件(. tld 文件)的方式 -->
<%@ taglib uri = "/WEB-INF/pageTag.tld"   prefix = "p" %>
<! DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" " http://www.w3.org/TR/html4/loose.dtd" ; >
< html >
< head >
< meta http-equiv = "Content-Type" content = "text/html; charset=UTF-8" >
< title > 自定义标签1 </ title >
</ head >
< body >
      自定义标签1: < wt:welcomeTag />
       < br >
      自定义标签2: < wt:testTag > this is second custom tag. </ wt:testTag >
       < br >
      自定义标签3: < p:page pageSize = "5" url = "UserServlet" count = "16" nowPage = "1" />
</ body >
</ html >

示例1、示例2、示例3结果:










  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值