01-标签简介和开发第一个标签
自定义标签简介
⑴编写一个实现Tag接口的Java类,把页面java代码移到这个java类中(标签处理类。)
⑵编写标签库描述符(tld)文件,在tld文件中对标签处理器类描述成一个标签。(放在WEB-INF下)
例题:使用标签输出客户机IP、
1.jsp        在jsp页面中导入和使用自定义标签
 
 
  
  1. 您的ip是:<itcast:viewIP/> 
 
1.编写一个实现tag接口的java类
 
  
  1. public class ViewIPTag extends TagSupport {  
  2.    
  3.     @Override  
  4.     public int doStartTag() throws JspException {  
  5.          
  6.     HttpServletRequest request =(HttpServletRequest)this.pageContext.getRequest();//返回的是ServletRequest,所以要强转  
  7.     JspWriter out = this.pageContext.getOut();      
  8.       
  9.     String ip = request.getRemoteAddr();  
  10.     try {  
  11.        out.print(ip);  
  12.     } catch (IOException e) {  
  13.        throw new RuntimeException(e);  
  14.     }  
  15.        return super.doStartTag();  
  16.     }  
  17.    
  18. }  
 
2.在tld文件中对标签处理类进行描述(tld文件的位置:WEB-INF下)
tld模版
 
  
  1. <?xml version="1.0" encoding="UTF-8" ?>   
  2.    
  3. <taglib xmlns="http://java.sun.com/xml/ns/j2ee"   
  4.     xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"   
  5.     xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee http://java.sun.com/xml/ns/j2ee/web-jsptaglibrary_2_0.xsd" 
  6.     version="2.0">   
  7.       
  8.     <description>JSTL 1.1 core library</description>   
  9.   <display-name>JSTL core</display-name>   
  10.   <tlib-version>1.1</tlib-version>   
  11.   <short-name>itcast</short-name>   
  12.   <uri>http://www.itcast.cn</uri><!--此行填写你自己标签库的uri-->   
  13.    
  14.     <tag>   
  15.         <name>viewIP</name>   
  16.        <tag-class>cn.itcast.web.tag.ViewIPTag</tag-class> 
  17.        <body-content>empty</body-content> <!-- 有无标签体 --> 
  18.     </tag>   
  19.    
  20. </taglib>   
 
02-自定义标签运行原理
(暂空)
 
03-自定义标签功能概述
 
Tag接口的执行流程
● jsp引擎将遇到自定义标签时,首先创建标签处理类的实例对象,然后按照 JSP规范定义的通信规则依次调用它的方法。
1、 public void setPageContext(PageContext pageContext),JSP引擎实例化标签处理器后,将调用setPageContext方法将JSP页面的pageContext对象传递给标签处理器,标签处理器以后可以通过这个pageContext对象与JSP页面进行通信。
 
2、 public void setParent(Tag t),setPageContext方法执行完后,WEB容器接着调用setParent方法将当前标签的父标签传递给当前标签处理器,如果当前标签没有父标签,则传递给setParent方法的参数值为null。
3、 public int doStartTag(),调用了setPageContext方法和setParent方法之后,WEB容器执行到自定义标签的开始标记时,就会调用标签处理器的doStartTag方法。
4、 public int doEndTag()WEB容器执行完自定义标签的标签体后,就会接着去执行自定义标签的结束标记,此时,WEB容器会去调用标签处理器的 doEndTag方法。
5、 public void release(),通常WEB容器执行完自定义标签后,标签处理器会驻留在内存中,为其它请求服务,直至停止WEB应用时,WEB容器才会调用release方法。
 
 
 
自定义标签功能扩展

 

 
 
四.传统标签库功能详解
 
2.jsp    控制 jsp页面某一部分内容是否执行(继承Tag接口)
使用 Tag的默认实现类TagSupport的doEndTag方法dedoStartTag方法
 
 
  
  1. public int doStartTag() throws JspException {  
  2.              
  3.        return this.EVAL_BODY_INCLUDE; //显示标签体内容  
  4.        return this.SKIP_BODY; //不显示标签体内容  
  5.     }  
3.jsp用标签体控制整个 jsp是否输出(继承Tag接口,使用Tagd的默认实现类TagSupport)
 
使用 Tag的默认实现类TagSupport的doEndTag方法
 
  
  1. public int doEndTag() throws JspException {  
  2.        // TODO Auto-generated method stub  
  3.        return Tag.SKIP_PAGE; //不显示标签结束之后的内容  
  4.        return Tag.EVAL_PAGE;//显示标签结束后的内容  
  5.     }  
  6.    
4.jsp 使用标签控制页面内容重复执行(此时Tag接口不够用,用继承了Tag接口的IterationTag接口,)
 

 
使用 Tag的默认实现类TagSupport的2个方法doStartTag()与doAfterBody()
 
  
  1. public int doStartTag() throws JspException {  
  2.        return Tag.EVAL_BODY_INCLUDE;// 先使用doStartTag显示标签体内容  
  3.     }  
  4.    
  5.     // 执行完标签体调用次方法  
  6.     public int doAfterBody() throws JspException {  
  7.        x--;  
  8.        if(x>0){  
  9.            return IterationTag.EVAL_BODY_AGAIN; //再次执行次方法  
  10.        }else{  
  11.            return IterationTag.SKIP_BODY; //停止执行次方法  
  12.        }  
  13.     }  
 
 
5.jsp       用标签修改jsp页面内容(使用BodyTag接口)
使用BodyTag的默认实现类 BodyTagSupport的doStartTag()方法
①当返回 EVAL_BODY_BUFFERED 时 服务器把标签体作为对象通过setBodyContent ()传递给标签处理器类。
②在 doEndTag()中拿到标签体,修改标签体
 
 
  
  1. public int doStartTag() throws JspException {  
  2.        // TODO Auto-generated method stub  
  3.        return BodyTag.EVAL_BODY_BUFFERED;// 服务器把封装到一个类中,传递进来  
  4.     }  
  5.    
  6.     @Override 
  7.     public int doEndTag() throws JspException {  
  8.        BodyContent bc = this.getBodyContent();// 得到标签体  
  9.        String content = bc.getString();  
  10.        content = content.toUpperCase();  
  11.    
  12.        try {  
  13.            this.pageContext.getOut().write(content);  
  14.        } catch (IOException e) {  
  15.            throw new RuntimeException(e);  
  16.        }  
  17.    
  18.        return Tag.EVAL_PAGE;// 继续显示标签体后的HTML  
  19.     }  
 
 
05-简单标签库功能详解
①setJspBody(JspFragment jspBody);//服务器在调用标签时,调用setJspBody方法,把标签体作为JspFragment对象传入。
②doTag(); //在标签执行时调用doTag方法。执行标签体、如果抛出SkipPageException异常,余下JSP就不会执行。
 
1.jsp               用简单标签控制是否执行标签提(使用SimpleTag接口的实现类,SimpleTagSupport)
 
 
  
  1. public void doTag() throws JspException, IOException {  
  2.    
  3.        JspFragment jf = this.getJspBody();  
  4.        //如果不标签体,doTag方法为空就行  
  5.        jf.invoke(this.getJspContext().getOut());// 输出给浏览器。  
  6.          
  7. }  
 
2.jsp               迭代标签体(使用SimpleTag接口的实现类,SimpleTagSupport)
 
    
 
  
  1. public void doTag() throws JspException, IOException {  
  2.    
  3.        JspFragment jf = this.getJspBody();  
  4.          
  5.        for(int i=0;i<5;i++){  
  6. jf.invoke(null);//同jf.invoke(this.getJspContext().getOut());输出给浏览器。  
  7.            }  
  8.          
  9. }  
 
3.jsp               修改标签体(使用SimpleTag接口的实现类,SimpleTagSupport)
 
 
  
  1. public void doTag() throws JspException, IOException {  
  2.    
  3.        JspFragment jf = this.getJspBody();  
  4.        StringWriter sw = new StringWriter();  
  5.        jf.invoke(sw);  
  6.    
  7.        String content = sw.toString().toUpperCase();  
  8.    
  9.        this.getJspContext().getOut().write(content);  
  10.    
  11. }  
 
4.jsp       控制标签余下的jsp不执行(使用SimpleTag接口的实现类,SimpleTagSupport)
 
  
  1. public void doTag() throws JspException, IOException {  
  2.    
  3.        throw new SkipPageException();  
  4. }  
 
简单标签执行流程图
(暂空)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
06-开发带属性的标签
 
①在标签处理器中添加属性对应的变量与set方法
    
 
  
  1. private int count;  
  2.    
  3.     public void setCount(int count) {  
  4.        this.count = count;  
  5.     }  
  6.    
  7.     @Override 
  8.     public void doTag() throws JspException, IOException {  
  9.        JspFragment jf = this.getJspBody();  
  10.    
  11.        for (int i = 0; i < count; i++) {  
  12.            jf.invoke(null);  
  13.        }  
  14.     }  
 
②在 TLD文件中描述标签的属性
 
 
  
  1. <tag>  
  2.      <name>demo5</name>  
  3.      <tag-class>cn.itcast.web.simpletag.SimpleTagDemo5</tag-class>  
  4.      <body-content>scriptless</body-content><!-- 简单的标签为空。-->  
  5.        
  6.      <attribute>  
  7.          <name>count</name>  
  8.          <required>turn</required><!-- 属性是否必须 -->  
  9.          <rtexprvalue>true</rtexprvalue><!-- 属性复制时是否可以使用EL表达式 -->  
  10.      </attribute>  
  11.   </tag>  
 
 

(待续)