<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>

<!-- 引入标签库: prefix是必须含有的不可缺少 -->    
<%@ taglib uri="/ssgao" prefix="ssgao" %>

<!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>Insert title here</title>
</head>
<body>
输出标签信息
<!-- 在JSp页面中使用自定义标签gs,gs标签是带有标签体的,其标签体的内容是:我的宝贝是笑笑 -->
<ssgao:aouo>
我的宝贝是笑笑
</ssgao:aouo>
</body>
</html>

JspTag接口*

     该接口是所有自定义标签的父接口,是jsp2.0中新定义的标记接口,没有任何属性和方法。JspTag的接口有Tag和SimpleTag两个直接子接口,jsp2.0之前的版本只有Tag接口,所以实现Tag接口的自定义标签页叫做传统标签把实现SimpleTag接口的自定义标签叫做简单标签

Tag接口

     Tag接口是所有传统标签的父接口,其中定义了两个重要的方法(doStartTag,doEndTag)方法和四个常量(EVAL_BODY_INCLUDE,SKIP_BODY,EVAL_PAGE.SKIP_PAGE)这两个方法和四个常量的作用如下:
     从WEB容器在解释执行JSP页面的过程中,遇到自定义的标签的开始标记就会去调用标签处理器的doStartTag方法,doStartTag方法执行完后可以向WEB容器返回常量EVAL_BODY_INCLUDE或SKIP_BODY。如果doStartTag方法返回EVAL_BODY_INCLUDE,WEB容器就会接着执行自定义标签的标签体。如果doStartTag方法返回SKIP_BODY,WEB容器就会忽略自定义标签的标签体,直接解释执行自定义标签的结束标记。
     WEB容器解释执行到自定义标签的结束标记时,就会调用标签处理器的doEndTag方法,doEndTag方法执行完后可以向WEB容器返回常量EVAL_PAGE或KIP_PAGE。如果doEndTag方法返回常量EVAL_PAGE,WEB容器就会接着执行JSP页面中位于结束标记后面的JSP代码;如果doEndTag方法返回SKIP_TAG,WEB容器就会忽略JSP页面中位于标记后面的所有内容。
     从doStartTag和doEndTag方法的作用和返回值的作用可以看出,开发自定义的标签时,可以在doStartTag方法和doEndTag方法体内编写适合Java程序代码来实现具体的功能。通过控制doStartTag方法和doEndTag方法的返回值,还可以告诉WEB容器是否执行自定义标签中的标签体内容和JSP页面中位于自定义标签结束标记后面的内容。

Iteration Tag接口

   IterationTag接口继承了Tag接口,并在Tag接口的基础上增加一个doAfterBody的方法和一个EVAL_BODY_AGAIN常量。实现IterationTag接口的标签除了可以完成Tag接口所能完成功能外,还能够通知WEB容器是否重复执行标签体内容。对于实现了ITerationTag接口的自定义标签,WEB容器在执行完自定义标签的标签体后,将调用标签处理器的doAfterBody方法,doAfterBody方法可以向WEB容器返回常量EVAL_BODY_AGAIN或SKIP_BODY。如果doAfterBody方法返回EVAL_BODY_AGAIN,WEB容器就会把标签体内容重复执行一次,执行完后接着在调用doAfterBody方法,如此往复,直到doAfterBody方法返回常量SKIP_BODY.WEB容器才会开始处理标签的结束标记和调用doEndTag方法。
     可见,开发自定义标签时,可以通过控制doAfterBody方法的返回值来告诉WEB容器是否重复执行标签体内容,从而达到循环处理标签体内容的效果。例如,可以通过一个实现IterationTag接口的标签来迭代输出一个集合中所有元素,在标签体部分指定元素的输出格式。

BodyTag接口

BodyTag接口继承了IterationTag接口,并在IterationTag接口的基础上增加了两个方法(setBodyContent、doInitBody)和一个EVAL_BODY_BUFFERED常量。实现BodyTag接口的标签除了可以完成IterationTag接口所能完成的功能,还可以对标签体内容进行修改。对于实现了BodyTag接口的自定义标签,标签处理器的doStartTag方法不仅可以返回前面讲解的常量EVAL_BODY_INCLUDE或SKIP_BODY,还可以返回常量EVAL_BODY_BUFFERED。如果doStartTag方法返回EVAL_BODY_BUFFERED,WEB容器就会创建一个专用于捕获标签体运行结果的BodyContent对象,然后调用标签处理器的setBodyContent方法将BodyContent对象的引用传递给标签处理器,WEB容器接着将标签体的执行结果写入到BodyContent对象中。在标签处理器的后续事件方法中,可以通过先前保存的BodyContent对象的引用来获取标签体的执行结果,然后调用BodyContent对象特有的方法对BodyContent对象中的内容(即标签体的执行结果)进行修改和控制其输出。
在JSP API中也提供了BodyTag接口的实现类BodyTagSupport,我们在编写能够修改标签体内容的自定义标签的标签处理器类时,可以继承和扩展BodyTagSupport类,这相比实现BodyTag接口将简化开发工作

SimpleTag 接口

  SimpleTag接口是JSP2.0中新增的一个标签接口。由于传统标签使用三个标签接口来完成不同的功能,显得过于繁琐,不利于标签技术的推广,因此,SUN公司为降低标签技术的学习难度,在JSP 2.0中定义了一个更为简单、便于编写和调用的SimpleTag接口。SimpleTag接口与传统标签接口最大的区别在于,SimpleTag接口只定义了一个用于处理标签逻辑的doTag方法,该方法在WEB容器执行自定义标签时调用,并且只被调用一次。那些使用传统标签接口所完成的功能,例如是否执行标签体、迭代标签体、对标签体内容进行修改等功能都可以在doTag方法中完成。
   在JSP API中也提供了SimpleTag接口的实现类SimpleTagSupport,我们在编写简单标签时,可以继承和扩展SimpleTagSupport类,这相比实现SimpleTag接口将简化开发工作

传统标签接口中的各个方法可以返回返回值得说明

返回值和方法名 EVAL_BODY_INCLUDE SKIP_BODY EVAL_BODY_BUFFEREDY EVAL_BODY_AGAIN EVAL_PAGE SKIP_PAGE
doStartTag 将标签体的执行结果插入到输出流中 忽略标签体部分 将标签提的执行接口放入到一个BodyContent对象中 X X X
doAfterBody X 不在重复执行标签体内容 X 重复执行标签内容 X X
doEndTag X X X X 继续处理结果标签后面的所有JSP代码 忽略结束标签后面的所有JSP代码

传统标签实现页面逻辑

控制jsp页面某一部分内容是否执行
控制整个jsp页面是否执行
控制jsp页面内容重复执行
修改jsp页面内容输出

控制jsp页面的自定义标签体是否执行

    编写一个类实现tag接口,控制doStartTag()方法的返回值,如果整个方法返回EVAL_BODY_INCLUDE,则执行标签体,如果返回SKIP_BODY则不执行
    SUN公司针对tag接口提供了一个默认的实现类TagSupport,TagSupport类中实现了tag接口的所有方法,因此我们可以编写一个类集成TagSupport,然后在重写doStartTag方法
    
package demo.tag;
import java.io.IOException;
import javax.servlet.jsp.JspException;
import javax.servlet.jsp.JspWriter;
import javax.servlet.jsp.tagext.Tag;
import javax.servlet.jsp.tagext.TagSupport;

/**
* TagSupport类实现了Tag接口,TagtwoDemo继承了TagSupport
* @author ssgao
*
*/
public class TagtwoDemo extends TagSupport{

/** */
private static final long serialVersionUID = 7332955146947736164L;
/**
* 重写doStartTag方法,来控制标签提是否执行
*/
@Override
public int doStartTag() throws JspException {
JspWriter jw =pageContext.getOut();
try {
jw.write("自定义标签->");
} catch (IOException e) {
e.printStackTrace();
}
/**
* 如果返回EVAL_BODY_INCLDE,则执行标签体
* 如果返回SKIP_BODY 则不执行标签体
*/
return Tag.EVAL_BODY_INCLUDE;
} } 在WEB-INF目录下tld文件中添加对该标签处理的描述 <?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE taglib PUBLIC "-//Sun Microsystems, Inc.//DTD JSP Tag Library 1.2//EN" "http://java.sun.com/dtd/web-jsptaglibrary_1_2.dtd" >
<taglib>
 <tlib-version>tlib-version</tlib-version>
 <jsp-version>jsp-version</jsp-version>
 <short-name>short-name</short-name>
 
 <uri>/ssgao</uri>
 
 <tag>
   <name>aouo</name>
   <tag-class>demo.tag.TagtwoDemo</tag-class>
   <body-content>JSP</body-content>
 </tag>
</taglib> 在JSP页面中引入标签库
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>

<!-- 引入标签库: prefix是必须含有的不可缺少 -->    
<%@ taglib uri="/ssgao" prefix="ssgao" %>


<!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>Insert title here</title>
</head>
<body>
输出标签信息
<!-- 在JSp页面中使用自定义标签gs,gs标签是带有标签体的,其标签体的内容是:我的宝贝是笑笑 -->
<ssgao:aouo>
我的宝贝是笑笑
</ssgao:aouo>
</body>
</html>

控制整个JSP页面是否执行

编写一个类实现Tag接口,控制doEndTag方法的返回值,如果这个方法返回EVAL_PAGE,则执行标签下的JSP页面,如果返回SKIP_PAGE则不执行余下的JSP

package demo.tag;

import javax.servlet.jsp.JspException;
import javax.servlet.jsp.tagext.Tag;
import javax.servlet.jsp.tagext.TagSupport;

/**
* TagSupport类实现了Tag接口,TagtwoDemo继承了TagSupport
* @author ssgao
*
*/
public class EndTagDemo extends TagSupport{

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

/**
* 重写doEndTag方法控制JSP页面是否执行
*/
public int doEndTag() throws JspException { /**
* 如果返回EVAL_PAGE,则执行标签余下的JSP页面
* 如果返回SKIP_PAGE,则不执行余下的JSP页面
*/
return Tag.SKIP_PAGE;
}
} 在WEB-INF目录下tld文件中添加对该标签处理的描述
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE taglib PUBLIC "-//Sun Microsystems, Inc.//DTD JSP Tag Library 1.2//EN" "http://java.sun.com/dtd/web-jsptaglibrary_1_2.dtd" >
<taglib>
 <tlib-version>tlib-version</tlib-version>
 <jsp-version>jsp-version</jsp-version>
 <short-name>short-name</short-name>  
 <uri>/end</uri>
 
 <tag>
   <name>end</name>
   <tag-class>demo.tag.EndTagDemo</tag-class>
   <body-content>empty</body-content>
 </tag>
</taglib> 在JSP页面中引入标签库
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>

<!-- 引入标签库: prefix是必须含有的不可缺少 -->    
<%@ taglib uri="/end" prefix="gs" %>
<!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>Insert title here</title>
</head>
<body>
<!-- 在JSp页面中使用自定义标签gs,gs标签是带有标签体的,其标签体的内容是:我的宝贝是笑笑 -->
<gs:end/>
输出标签信息
</body>
</html>

JSP页面内容重复执行

编写一个类实现Iterationtag接口控制doAfterBody()方法的返回值,如果这个方法返回EVAL_BODY_AGAIN,则web服务器重复执行一次标签体,一次类推,知道doAfterBody方法返回SKIP_BODY
则标签体才不会重复执行
package demo.tag;

import java.io.IOException;

import javax.servlet.jsp.JspException;
import javax.servlet.jsp.JspWriter;
import javax.servlet.jsp.tagext.IterationTag;
import javax.servlet.jsp.tagext.Tag;
import javax.servlet.jsp.tagext.TagSupport;

/**
* TagSupport类实现了Tag接口,TagtwoDemo继承了TagSupport
* @author ssgao
*
*/
public class AfterTagDemo extends TagSupport{

/** */
private static final long serialVersionUID = 7332955146947736164L;
static int no;
static{
no=5;
} /**
* 重写doStartTag方法,来控制标签提是否执行
*/
@Override
public int doStartTag() throws JspException {
/**
* 如果返回EVAL_BODY_INCLDE,则执行标签体
* 如果返回SKIP_BODY 则不执行标签体
*/
return Tag.EVAL_BODY_INCLUDE;
}
@Override
public int doAfterBody() throws JspException {
no--;
while(no>0){
return IterationTag.EVAL_BODY_AGAIN;
}
return IterationTag.SKIP_BODY;
}
} 在WEB-INF目录下tld文件中添加对该标签处理的描述
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE taglib PUBLIC "-//Sun Microsystems, Inc.//DTD JSP Tag Library 1.2//EN" "http://java.sun.com/dtd/web-jsptaglibrary_1_2.dtd" >
<taglib>
 <tlib-version>tlib-version</tlib-version>
 <jsp-version>jsp-version</jsp-version>
 <short-name>short-name</short-name>
 <uri>/after</uri>
 <tag>
   <name>after</name>
   <tag-class>demo.tag.AfterTagDemo</tag-class>
   <body-content>JSP</body-content>
 </tag>
</taglib>

在JSP页面中引入标签库

<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>

<!-- 引入标签库: prefix是必须含有的不可缺少 -->    
<%@ taglib uri="/after" prefix="ssgao" %>

<!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>Insert title here</title>
</head>
<body>
输出标签信息
<!-- 在JSp页面中使用自定义标签gs,gs标签是带有标签体的,其标签体的内容是:我的宝贝是笑笑 -->
<ssgao:after>
我的宝贝是笑笑
</ssgao:after>
</body>
</html>

修改JSP页面内容输出

编写一个类实现BodyTag接口,控制doStartTag方法返回EVAL_BODY_BUFFERED,则WEB服务器会创建BodyContent对象捕获标签体,然后在doEndTag()方法体内,得到代表标签体的bodyContent对象
从而就可以对标签体进行修改操作
sun公司针对BodyTag接口提供一个默认的实现类BodyTagSupport,BodyTagSupport类中实现了BodyTag接口的所有方法,因此我们可以编写一个类继承BodyTagSupport类,然后在根据需要重写doStartTag方法和doEndTag方法。
package demo.tag;

import javax.servlet.jsp.JspException;
import javax.servlet.jsp.tagext.BodyContent;
import javax.servlet.jsp.tagext.BodyTag;
import javax.servlet.jsp.tagext.BodyTagSupport;
import javax.servlet.jsp.tagext.Tag;
/**
* BodyTagSupport类实现了BodyTag接口接口,EditTagDemo继承 BodyTagSupport类
* @author ssgao
*
*/
public class EditTagDemo extends BodyTagSupport{

/** */
private static final long serialVersionUID = -3814095430415404149L;

/**
* 控制doStartTag()方法返回EVAL_BODY_BUFFERED
*/
@Override
public int doStartTag() throws JspException {
return BodyTag.EVAL_BODY_BUFFERED;
}

@Override
public int doEndTag() throws JspException {
/**this.getBodyContent()得到代表标签体的bodyContent对象 */
BodyContent bodyContent=this.getBodyContent();
//拿到标签体
String content = bodyContent.getString();
//修改标签体里面的内容,将小写转换为大写
String result = content.toUpperCase();
try {
/** 输出修改后的内容*/
this.pageContext.getOut().write(result);
} catch (Exception e) {
e.printStackTrace();
}
return Tag.EVAL_PAGE;
}
} 在WEB-INF目录下tld文件中添加对该标签处理的描述
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE taglib PUBLIC "-//Sun Microsystems, Inc.//DTD JSP Tag Library 1.2//EN" "http://java.sun.com/dtd/web-jsptaglibrary_1_2.dtd" >
<taglib>
 <tlib-version>tlib-version</tlib-version>
 <jsp-version>jsp-version</jsp-version>
 <short-name>short-name</short-name>
 <uri>/edit</uri>  
 <tag>
   <name>edit</name>
   <tag-class>demo.tag.EditTagDemo</tag-class>
   <body-content>JSP</body-content>
 </tag>
</taglib>

在JSP页面中引入标签库

<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>

<!-- 引入标签库: prefix是必须含有的不可缺少 -->    
<%@ taglib uri="/edit" prefix="ssgao" %>

<!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>Insert title here</title>
</head>
<body>
输出标签信息
<ssgao:edit>
sadasd
</ssgao:edit>
</body>
</html>

jsp jsp传统标签开发的更多相关文章

  1. javaweb学习总结(二十四)——jsp传统标签开发

    一.标签技术的API 1.1.标签技术的API类继承关系 二.标签API简单介绍 2.1.JspTag接口 JspTag接口是所有自定义标签的父接口,它是JSP2.0中新定义的一个标记接口,没有任何属 ...

  2. javaweb(二十四)——jsp传统标签开发

    一.标签技术的API 1.1.标签技术的API类继承关系 二.标签API简单介绍 2.1.JspTag接口 JspTag接口是所有自定义标签的父接口,它是JSP2.0中新定义的一个标记接口,没有任何属 ...

  3. 深入分析JavaWeb Item23 -- jsp自己定义标签开发入门

    一.自己定义标签的作用 自己定义标签主要用于移除Jsp页面中的java代码. 二.自己定义标签开发和使用 2.1.自己定义标签开发步骤 1.编写一个实现Tag接口的Java类(标签处理器类) 要编写一 ...

  4. JSP传统标签开发

    1.标签技术的API类继承关系 1).JspTag接口是所有自定义标签的父接口 该接口中没有任何属性和方法,只有两个直接子接口,Tag接口和SimpleTag接口,把实现Tag接口的自定义标签叫做传统 ...

  5. 【JSP】自定义标签开发入门

    JSP 自定义标签 自定义标签是用户定义的JSP语言元素.当JSP页面包含一个自定义标签时将被转化为servlet,标签转化为对被 称为tag handler的对象的操作,即当servlet执行时We ...

  6. javaweb基础(24)_jsp一般的标签开发

    一.标签技术的API 1.1.标签技术的API类继承关系 二.标签API简单介绍 2.1.JspTag接口 JspTag接口是所有自定义标签的父接口,它是JSP2.0中新定义的一个标记接口,没有任何属 ...

  7. 08.十分钟学会JSP传统标签编程

    一.认识标签 1,说明:传统标签编程在开发中基本用不到,学习标签编程主要还是为了完善知识体系. 2,标签的主要作用:移除或减少jsp中的java代码 3,标签的主要组成部分及运行原理 4,简单标签示例 ...

  8. 【jsp】JSTL标签大全详解

    一.JSTL标签介绍 1.什么是JSTL? JSTL是apache对EL表达式的扩展(也就是说JSTL依赖EL),JSTL是标签语言!JSTL标签使用以来非常方便,它与JSP动作标签一样,只不过它不是 ...

  9. JSP简单标签开发

    一.继承自SimpleTag接口的自定义标签实现类称为简单标签,接口中5个方法 1.setJspContext方法 用于把JSP页面的PageContext对象传递给标签处理器对象 2.setPare ...

随机推荐

  1. Program Size

    在Keil中编译工程成功后,在下面的Bulid Ouput窗口中会输出下面这样一段信息: Program Size: Code=6320  RO-data=4864  RW-data=44  ZI-d ...

  2. Java继承相关知识总结

    Java继承的理解 一.概念: 一个新类从已有的类那里获得其已有的属性和方法,这种现象叫类的继承 这个新类称为子类,或派生类,已有的那个类叫做父类,或基类 继承的好处:代码得到极大的重用.形成一种类的 ...

  3. 0xc0000005:读取位置时发生访问冲突

    这是空指针,比如: A* a=NULL; a->fun();//会提示标题错误,因为a没有分配空间

  4. cogs 2221. [SDOI2016 Round1] 数字配对

    ★★ 输入文件:pair.in 输出文件:pair.out 简单对比 时间限制:1 s 内存限制:128 MB [题目描述] 有 n 种数字,第 i 种数字是 ai.有 bi 个,权值是 ci. 若两 ...

  5. POJ 2348 Euclid's Game(博弈)题解

    题意:有a,b两个数字,两人轮流操作,每次可以选择两个之中较小的数字,然后另一个数字减去选择数字的任意倍数(不能减到负数),直到其中一个为0,不能操作为败 思路:这题用博弈NP思想,必败点和必胜点之间 ...

  6. POJ 2352 Stars(树状数组)题解

    Language:Default Stars Time Limit: 1000MS Memory Limit: 65536K Total Submissions: 52268 Accepted: 22 ...

  7. AcceptAsync和BeginAccept的区别

    Difference between […]Async and Begin[…] .net asynchronous APIs Note that most *Async methods (with ...

  8. 51NOD 1133 不重叠的线段

    1133 不重叠的线段   X轴上有N条线段,每条线段有1个起点S和终点E.最多能够选出多少条互不重叠的线段.(注:起点或终点重叠,不算重叠).   例如:[1 5][2 3][3 6],可以选[2 ...

  9. [BZOJ1122][POI2008]账本BBB 单调队列+后缀和

    Description 一个长度为n的记账单,+表示存¥1,-表示取¥1.现在发现记账单有问题.一开始本来已经存了¥p,并且知道最后账户上还有¥q.你要把记账单修改正确,使得 1:账户永远不会出现负数 ...

  10. 列举一些有所帮助的blog和文章

    w3school hdoj imooc CSDN Github myGithub CmdMarkdown 一直在路上--记我从初中到本科近十年的学习成长历程 作者:周见智 C++中队列的建立与操作详细 ...