- 浏览: 453112 次
- 性别:
- 来自: 北京
文章分类
- 全部博客 (211)
- java (37)
- spring相关 (3)
- struts (10)
- 面试 (1)
- jsp/servlet (18)
- 持久化框架 (1)
- IT相关新闻 (3)
- 服务器 (11)
- 插件 (4)
- pushlet (3)
- js (24)
- oracle (29)
- mysql (9)
- hibernate (5)
- 开发工具 (6)
- jquery (6)
- 页面标签jstl,el (1)
- linux (25)
- 英语 (1)
- log4j (1)
- html/css (6)
- sqlserver (2)
- dwr (1)
- 设计模式 (4)
- vmware (2)
- office (1)
- eclipse (5)
- svn (1)
- webservice (1)
最新评论
-
18335864773:
建议使用 pageoffice 组件套红
js操作word套红 -
lopez:
数据库系统的客户程序只要向数据库系统声明了一个事务,数据库系统 ...
Hibernate事物控制与管理 -
liujq4512:
删了还是没用
An internal error occurred during: "Initializing Java Tooling". -
elaine0111:
非常感谢这篇文章,嘿嘿,解决了我的问题。我把这段代码保存在我的 ...
Js设置文本框中焦点位置在最后 -
weishuguangeye:
不错!
单例模式(Singleton)
【实例109】 开发带属性的标签:helloTagHaveProp
本实例中开发的标签在实例108的helloTag标签上作出改进,开发目标是在helloTag标签上增加两个属性fontSize和fontColor,fontSize用于设置字体大小,fontColor用于设置文字的颜色。
(1)第一步:开发标签实现类。
helloTagHaveProp.java
package hello;
import javax.servlet.jsp.JspWriter;
import javax.servlet.jsp.tagext.TagSupport;
public class helloTagHaveProp extends TagSupport {
private String fontSize="3";//字体大小,默认3号
private String fontColor="#000000";//字体颜色,默认黑色
//----标签开始时调用此方法-------
public int doStartTag(){
try{
JspWriter out=pageContext.getOut();
out.print("标签开始了。<font color=\""+fontColor +
"\" size=\""+fontSize+"\">hello!</font>");
}catch(Exception e){
System.out.println(e);
}
return EVAL_BODY_INCLUDE;
}
//----标签结束时调用此方法-------
public int doEndTag(){
try{
JspWriter out=pageContext.getOut();
out.print("标签结束了。");
}catch(Exception e){
System.out.println(e);
}
return EVAL_PAGE;
}
public String getFontColor() {
return fontColor;
}
public void setFontColor(String fontColor) {
this.fontColor = fontColor;
}
public String getFontSize() {
return fontSize;
}
public void setFontSize(String fontSize) {
this.fontSize = fontSize;
}
}
(2)第二步:编写标签描述tld文件。这里在myTag.tld文件中增加内容,在<taglib>与</taglib>之间增加的内容如下:
<!-- helloTagHaveProp-->
<tag>
<!-- 标签名称-->
<name>helloTagHaveProp</name>
<!-- 标签对应的处理类-->
<tag-class>hello.helloTagHaveProp</tag-class>
<!-- 标签体内容,没有标签体则设为empty-->
<body-content>empty</body-content>
<!-- 标签的属性声明-->
<attribute>
<name>fontSize</name>
<required>false</required>
</attribute>
<attribute>
<name>fontColor</name>
<required>false</required>
</attribute>
</tag>
其中,name为属性的名称,required设置此属性是否必须设置,如果为true则在JSP页面中使用此标签时,必须给标签的这个属性赋值。
(3)第三步:在Web应用的web.xml文件中声明标签库引用。本例与实例108使用同一个tld文件,故不必再修改。
(4)第四步:在JSP页面中声明并调用标签。
useHelloTagHaveProp.jsp
<%@ taglib uri="/myTag" prefix="myTag" %>
<%@ page contentType="text/html;charset=GB2312" %>
<html>
<head>
<title>一个简单的自定义标签</title>
</head>
<body>
下面是应用这个简单的自定义标签的结果:<br>
<myTag:helloTagHaveProp fontSize="5"/><br>
<myTag:helloTagHaveProp fontSize="4" fontColor="red"/>
</body>
</html>
程序的运行结果如图13-3所示。
三、 开发带标签体的标签
要开发带标签体的标签,可实现BodyTag接口,也可从BodyTag接口的实现类BodyTagSupport继承,为简化开发,推荐从BodyTagSupport类继承开发。
编写标签对应的实现类时,需要重载BodyTagSupport类几个方法:doStartTag(), setBodyContent(), doInitBody(), doAfterBody(), doEndTag(),他们执行顺序如下:doStartTag()→doInitBody()→setBodyContent()→doAfterBody()→doEndTag()doStartTag()方法可返回EVAL_BODY_INCLUDE或SKIP_BODY,如果返回EVAL_BODY_ INCLUDE则继续执行;如果返回SKIP_BODY则接下来的doInitBody(),setBodyContent(), doAfterBody()三个方法不会被执行,而直接执行doEndTag()方法。
setBodyContent()方法用于设置标签体内容,如果在此之前要作一些初始化工作,则在doInitBody()方法中完成。标签体内容执行完后,会调用doAfterBody()方法,此方法可返回EVAL_BODY_TAG, SKIP_BODY,
EVAL_PAGE或SKIP_PAGE。如果返回EVAL_BODY_TAG则会再次设置标签体内容,直到返回SKIP_BODY;如果返回EVAL_PAGE则标签体执行完后会继续执行JSP页面中接下来的部分;如果返回SKIP_PAGE,则JSP页面的后续内容将不再执行。
【实例110】 开发带标签体的标签:bodyTag1
本实例将要开发一个带标签体的标签bodyTag1,这个标签有一个属性countNum,用于设置输出标签体内容的次数,输出内容为当前的系统时间。
(1)第一步:开发标签实现类。
BodyTag1.java
package body;
import javax.servlet.jsp.JspWriter;
import javax.servlet.jsp.tagext.BodyTagSupport;
public class bodyTag1 extends BodyTagSupport{
private int countNum=0;//循环显示时间的次数
private int currentNum=1;//当前执行次数
//----标签开始时调用此方法-------
public int doStartTag(){
try{
JspWriter out=pageContext.getOut();
out.print("标签开始了:<br>");
if(countNum>0)
return EVAL_BODY_TAG;
else
return SKIP_BODY;
}catch(Exception e){
System.out.println(e);
return SKIP_BODY;
}
}
//----标签体执行完后调用此方法----
public int doAfterBody(){
try{
JspWriter out=pageContext.getOut();
out.print("第"+currentNum+"次执行标签体。标签体执行完毕。<br>");
if(countNum>1){//如果还需要执行标签体
countNum--;
currentNum++;
return EVAL_BODY_TAG;
}else return SKIP_BODY;
}catch(Exception e){
System.out.println(e);
return SKIP_BODY;
}
}
//----标签结束时调用此方法-------
public int doEndTag(){
try{
JspWriter out=pageContext.getOut();
//----输出标签体的内容----
bodyContent.writeOut(bodyContent.getEnclosingWriter());
out.print("标签结束了。");
}catch(Exception e){
System.out.println(e);
}
return EVAL_PAGE;
}
public int getCountNum() {
return countNum;
}
public void setCountNum(int countNum) {
this.countNum = countNum;
this.currentNum=1;
}
}
执行标签体并不会直接输出标签体中的内容,因此本实例在doEndTag()方法中一次性把执行的结果输出。
(2)第二步:编写标签描述tld文件。
因为本章所有实例共用一个Web应用,故本例在myTag.tld文件中增加内容。在<taglib>与</taglib>之间增加的内容如下:
<!-- bodyTag1-->
<tag>
<!-- 标签名称-->
<name>bodyTag1</name>
<!-- 标签对应的处理类-->
<tag-class>body.bodyTag1</tag-class>
<!-- 标签体内容,有标签体则设为jsp-->
<body-content>jsp</body-content>
<!-- 标签的属性声明-->
<attribute>
<name>countNum</name>
<required>true</required>
<rtexprvalue>true</rtexprvalue>
</attribute>
</tag>
对于属性countNum的声明中,<required>设置为true,表示此属性为必输项;<rtexprvalue>设置为true,表示标签体支持运行时的表达式取值,如果为false则表示标签体为一个静态文本,默认情况下设置为true。
(3)第三步:在Web应用的web.xml文件中声明标签库引用。
同样,本例与实例108使用同一个tld文件,不必再修改。
(4)第四步:在JSP页面中声明并调用标签。
UseBodyTag1.jsp
<%@ taglib uri="/myTag" prefix="myTag" %>
<%@ page contentType="text/html;charset=GB2312" %>
<%@ page import="java.util.Date" %>
<html>
<head>
<title>开发带有标签体的标签</title>
</head>
<body>
下面是应用这个带有属性的自定义标签的结果:<br>
<myTag:bodyTag1 countNum="6">
现在的时间是:<%=new Date()%><br>
</myTag:bodyTag1>
</body>
</html>
该程序的运行结果如图13-4所示。
【实例111】 开发嵌套的标签:haveChildTag
实际工程中往往需要多个标签来配合完成一定的功能,嵌套的标签存在父子关系,其中,父为外层标签,子为内层标签。本实例将用两个简单的标签来演示,父标签则作出逻辑判断,如果isOutput属性为true,则输出实例108中的标签helloTag;如果为false,则不输出。
(1)第一步:开发标签实现类。
内层的标签helloTag在实例108中已有,此处不再列出。
haveChildTag.java
package hello;
import javax.servlet.jsp.tagext.BodyTagSupport;
public class haveChildTag extends BodyTagSupport {
private boolean isOutput;//是否输出子标签内容
//----标签开始时调用此方法-------
public int doStartTag(){
if(isOutput)
return EVAL_BODY_INCLUDE;
else return SKIP_BODY;
}
//----标签结束时调用此方法-------
public int doEndTag(){
try{
if(bodyContent!=null)
bodyContent.writeOut(bodyContent.getEnclosingWriter());
}catch(Exception e){
System.out.println(e);
}
return EVAL_PAGE;
}
public boolean getIsOutput() {
return isOutput;
}
public void setIsOutput(boolean isOutput) {
this.isOutput = isOutput;
}
}
(2)第二步:编写标签描述tld文件。
本例在myTag.tld文件中增加内容。在<taglib>与</taglib>之间增加的如下内容:
<!-- haveChildTag-->
<tag>
<!-- 标签名称-->
<name>haveChildTag</name>
<!-- 标签对应的处理类-->
<tag-class>hello.haveChildTag</tag-class>
<!-- 标签体内容,有标签体则设为jsp-->
<body-content>jsp</body-content>
<!-- 标签的属性声明-->
<attribute>
<name>isOutput</name>
<required>true</required>
<rtexprvalue>true</rtexprvalue>
</attribute>
</tag>
(3)第三步:在Web应用的web.xml文件中声明标签库引用。
同样,本例与本章前面的实例使用同一个tld文件,此处不必再修改。
(4)第四步:在JSP页面中声明并调用标签。
useHaveChildTag.jsp
<%@ taglib uri="/myTag" prefix="myTag" %>
<%@ page contentType="text/html;charset=GB2312" %>
<%@ page import="java.util.Date" %>
<html>
<head>
<title>开发嵌套的标签</title>
</head>
<body>
输出子标签时的结果:<br>
<myTag:haveChildTag isOutput="true">
<myTag:helloTag/>
</myTag:haveChildTag><br>
不输出子标签时的结果:<br>
<myTag:haveChildTag isOutput="false">
<myTag:helloTag/>
</myTag:haveChildTag><br>
</body>
</html>
该程序的运行结果如图13-5所示。
《JSP网络编程从实践到实践》原码下载地址:http://shop.csai.cn/itbook/itbookinfo.asp?lbbh=10051575
五、 开发迭代的标签
【实例112】 开发迭代的标签:iterateTag
对于集合对象的Iterator类对象,在JSP的Java代码中需要用while循环或for循环来输出,难于维护,且可复用性不好,程序员总是在大量地做这样的工作,这时可以考虑用迭代的标签来开发,需要输出数据时只须在JSP页面中声明标签即可。
开发迭代的标签,需要设计两个Java类:标签实现类和表示标签信息的类。本实例中标签实现类为iterateTag.java,表示标签信息的类为IterateTEI.java。开发迭代的标签可实现IterationTag接口,也可从TagSupport类或BodyTagSupport类继承,由于BodyTagSupport类继承自TagSupport类,而TagSupport类又实现了IterationTag接口,为简化开发,直接从BodyTagSupport类继承即可。
(1)第一步:开发标签实现类和表示标签信息的类。
iterateTag.java
package body;
import java.util.Collection;
import java.util.Iterator;
import javax.servlet.jsp.tagext.BodyTagSupport;
public class iterateTag extends BodyTagSupport{
private String name;//在pageContext中标识的一个属性名
private Iterator it;//要迭代的对象
private String type;//it中对象的类型
public void setCollection(Collection collection){
if(collection.size()>0)
it=collection.iterator();
}
//----标签开始时调用此方法-------
public int doStartTag(){
if(it==null) return SKIP_BODY;
else return continueNext(it);
}
//----标签体执行完后调用此方法----
public int doAfterBody(){
return continueNext(it);
}
//----标签结束时调用此方法-------
public int doEndTag(){
try{
if(bodyContent!=null)
bodyContent.writeOut(bodyContent.getEnclosingWriter());
}catch(Exception e){
System.out.println(e);
}
return EVAL_PAGE;
}
//----迭代----
protected int continueNext(Iterator it){
if(it.hasNext()){
pageContext.setAttribute(name,it.next(),pageContext.PAGE_SCOPE);
return EVAL_BODY_TAG;
}else return SKIP_BODY;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getType() {
return type;
}
public void setType(String type) {
this.type = type;
}
}
在标签实现类中,有3个属性:name、type和it。其中,name代表在pageContext中标识一个属性的名字;type代表待迭代内容的数据类型;it为要迭代的内容。在doStartTag()方法中,如果it不为null,就开始迭代,迭代时调用continueNext()方法。
IterateTEI.java
package body;
import javax.servlet.jsp.tagext.TagData;
import javax.servlet.jsp.tagext.TagExtraInfo;
import javax.servlet.jsp.tagext.VariableInfo;
//----提供标签翻译时的一些相关信息----
public class IterateTEI extends TagExtraInfo {
public IterateTEI() {
super();
}
public VariableInfo[] getVariableInfo(TagData data){
return new VariableInfo[]{
new VariableInfo(data.getAttributeString("name"),
data.getAttributeString("type"),
true,VariableInfo.NESTED)
};
}
}
VariableInfo类中有几个常量,具体的含义为:
NESTED:标签中的参数在标签开始到标签结束之间是有效的。
AT_BEGIN:标签中的参数在标签开始到使用它的JSP页面结束是有效的。
AT_END:标签中的参数在标签的结束到使用它的JSP页面结束是有效的。
(2)第二步:编写标签描述tld文件。本例在myTag.tld文件中增加内容。在<taglib>与</taglib>之间增加如下内容:
<!-- iterateTag-->
<tag>
<!-- 标签名称-->
<name>iterateTag</name>
<!-- 标签对应的处理类-->
<tag-class>body.iterateTag</tag-class>
<tei-class>body.IterateTEI</tei-class>
<!-- 标签体内容,有标签体则设为jsp-->
<body-content>jsp</body-content>
<!-- 标签的属性声明-->
<attribute>
<name>collection</name>
<required>true</required>
<rtexprvalue>true</rtexprvalue>
</attribute>
<attribute>
<name>name</name>
<required>true</required>
</attribute>
<attribute>
<name>type</name>
<required>true</required>
</attribute>
</tag>
</taglib>
(3)第三步:在Web应用的web.xml文件中声明标签库引用。同样,本例与本章前面的实例使用同一个tld文件,因此不必再修改。
(4)第四步:在JSP页面中声明并调用标签。
<%@ taglib uri="/myTag" prefix="myTag" %>
<%@ page contentType="text/html;charset=GB2312" %>
<%@ page import="java.util.ArrayList"%>
<head>
<title>开发迭代的标签</title>
</head>
<body>
开发一个迭代的标签,输出结果:<br>
<%//----------设置一个ArrayList对象的初始值----------
ArrayList testCol=new ArrayList();
testCol.add("邓佳容");
testCol.add("黄婧");
testCol.add("邓子云");
request.setAttribute("testCol",testCol);
%>
<myTag:iterateTag name="testColOne" collection="<%=testCol%>" type="String">
输出一个值:<%=testColOne.toString()%><br>
</myTag:iterateTag>
</body>
</html>
该程序的运行结果如图13-6所示。
本实例中开发的标签在实例108的helloTag标签上作出改进,开发目标是在helloTag标签上增加两个属性fontSize和fontColor,fontSize用于设置字体大小,fontColor用于设置文字的颜色。
(1)第一步:开发标签实现类。
helloTagHaveProp.java
package hello;
import javax.servlet.jsp.JspWriter;
import javax.servlet.jsp.tagext.TagSupport;
public class helloTagHaveProp extends TagSupport {
private String fontSize="3";//字体大小,默认3号
private String fontColor="#000000";//字体颜色,默认黑色
//----标签开始时调用此方法-------
public int doStartTag(){
try{
JspWriter out=pageContext.getOut();
out.print("标签开始了。<font color=\""+fontColor +
"\" size=\""+fontSize+"\">hello!</font>");
}catch(Exception e){
System.out.println(e);
}
return EVAL_BODY_INCLUDE;
}
//----标签结束时调用此方法-------
public int doEndTag(){
try{
JspWriter out=pageContext.getOut();
out.print("标签结束了。");
}catch(Exception e){
System.out.println(e);
}
return EVAL_PAGE;
}
public String getFontColor() {
return fontColor;
}
public void setFontColor(String fontColor) {
this.fontColor = fontColor;
}
public String getFontSize() {
return fontSize;
}
public void setFontSize(String fontSize) {
this.fontSize = fontSize;
}
}
(2)第二步:编写标签描述tld文件。这里在myTag.tld文件中增加内容,在<taglib>与</taglib>之间增加的内容如下:
<!-- helloTagHaveProp-->
<tag>
<!-- 标签名称-->
<name>helloTagHaveProp</name>
<!-- 标签对应的处理类-->
<tag-class>hello.helloTagHaveProp</tag-class>
<!-- 标签体内容,没有标签体则设为empty-->
<body-content>empty</body-content>
<!-- 标签的属性声明-->
<attribute>
<name>fontSize</name>
<required>false</required>
</attribute>
<attribute>
<name>fontColor</name>
<required>false</required>
</attribute>
</tag>
其中,name为属性的名称,required设置此属性是否必须设置,如果为true则在JSP页面中使用此标签时,必须给标签的这个属性赋值。
(3)第三步:在Web应用的web.xml文件中声明标签库引用。本例与实例108使用同一个tld文件,故不必再修改。
(4)第四步:在JSP页面中声明并调用标签。
useHelloTagHaveProp.jsp
<%@ taglib uri="/myTag" prefix="myTag" %>
<%@ page contentType="text/html;charset=GB2312" %>
<html>
<head>
<title>一个简单的自定义标签</title>
</head>
<body>
下面是应用这个简单的自定义标签的结果:<br>
<myTag:helloTagHaveProp fontSize="5"/><br>
<myTag:helloTagHaveProp fontSize="4" fontColor="red"/>
</body>
</html>
程序的运行结果如图13-3所示。
三、 开发带标签体的标签
要开发带标签体的标签,可实现BodyTag接口,也可从BodyTag接口的实现类BodyTagSupport继承,为简化开发,推荐从BodyTagSupport类继承开发。
编写标签对应的实现类时,需要重载BodyTagSupport类几个方法:doStartTag(), setBodyContent(), doInitBody(), doAfterBody(), doEndTag(),他们执行顺序如下:doStartTag()→doInitBody()→setBodyContent()→doAfterBody()→doEndTag()doStartTag()方法可返回EVAL_BODY_INCLUDE或SKIP_BODY,如果返回EVAL_BODY_ INCLUDE则继续执行;如果返回SKIP_BODY则接下来的doInitBody(),setBodyContent(), doAfterBody()三个方法不会被执行,而直接执行doEndTag()方法。
setBodyContent()方法用于设置标签体内容,如果在此之前要作一些初始化工作,则在doInitBody()方法中完成。标签体内容执行完后,会调用doAfterBody()方法,此方法可返回EVAL_BODY_TAG, SKIP_BODY,
EVAL_PAGE或SKIP_PAGE。如果返回EVAL_BODY_TAG则会再次设置标签体内容,直到返回SKIP_BODY;如果返回EVAL_PAGE则标签体执行完后会继续执行JSP页面中接下来的部分;如果返回SKIP_PAGE,则JSP页面的后续内容将不再执行。
【实例110】 开发带标签体的标签:bodyTag1
本实例将要开发一个带标签体的标签bodyTag1,这个标签有一个属性countNum,用于设置输出标签体内容的次数,输出内容为当前的系统时间。
(1)第一步:开发标签实现类。
BodyTag1.java
package body;
import javax.servlet.jsp.JspWriter;
import javax.servlet.jsp.tagext.BodyTagSupport;
public class bodyTag1 extends BodyTagSupport{
private int countNum=0;//循环显示时间的次数
private int currentNum=1;//当前执行次数
//----标签开始时调用此方法-------
public int doStartTag(){
try{
JspWriter out=pageContext.getOut();
out.print("标签开始了:<br>");
if(countNum>0)
return EVAL_BODY_TAG;
else
return SKIP_BODY;
}catch(Exception e){
System.out.println(e);
return SKIP_BODY;
}
}
//----标签体执行完后调用此方法----
public int doAfterBody(){
try{
JspWriter out=pageContext.getOut();
out.print("第"+currentNum+"次执行标签体。标签体执行完毕。<br>");
if(countNum>1){//如果还需要执行标签体
countNum--;
currentNum++;
return EVAL_BODY_TAG;
}else return SKIP_BODY;
}catch(Exception e){
System.out.println(e);
return SKIP_BODY;
}
}
//----标签结束时调用此方法-------
public int doEndTag(){
try{
JspWriter out=pageContext.getOut();
//----输出标签体的内容----
bodyContent.writeOut(bodyContent.getEnclosingWriter());
out.print("标签结束了。");
}catch(Exception e){
System.out.println(e);
}
return EVAL_PAGE;
}
public int getCountNum() {
return countNum;
}
public void setCountNum(int countNum) {
this.countNum = countNum;
this.currentNum=1;
}
}
执行标签体并不会直接输出标签体中的内容,因此本实例在doEndTag()方法中一次性把执行的结果输出。
(2)第二步:编写标签描述tld文件。
因为本章所有实例共用一个Web应用,故本例在myTag.tld文件中增加内容。在<taglib>与</taglib>之间增加的内容如下:
<!-- bodyTag1-->
<tag>
<!-- 标签名称-->
<name>bodyTag1</name>
<!-- 标签对应的处理类-->
<tag-class>body.bodyTag1</tag-class>
<!-- 标签体内容,有标签体则设为jsp-->
<body-content>jsp</body-content>
<!-- 标签的属性声明-->
<attribute>
<name>countNum</name>
<required>true</required>
<rtexprvalue>true</rtexprvalue>
</attribute>
</tag>
对于属性countNum的声明中,<required>设置为true,表示此属性为必输项;<rtexprvalue>设置为true,表示标签体支持运行时的表达式取值,如果为false则表示标签体为一个静态文本,默认情况下设置为true。
(3)第三步:在Web应用的web.xml文件中声明标签库引用。
同样,本例与实例108使用同一个tld文件,不必再修改。
(4)第四步:在JSP页面中声明并调用标签。
UseBodyTag1.jsp
<%@ taglib uri="/myTag" prefix="myTag" %>
<%@ page contentType="text/html;charset=GB2312" %>
<%@ page import="java.util.Date" %>
<html>
<head>
<title>开发带有标签体的标签</title>
</head>
<body>
下面是应用这个带有属性的自定义标签的结果:<br>
<myTag:bodyTag1 countNum="6">
现在的时间是:<%=new Date()%><br>
</myTag:bodyTag1>
</body>
</html>
该程序的运行结果如图13-4所示。
【实例111】 开发嵌套的标签:haveChildTag
实际工程中往往需要多个标签来配合完成一定的功能,嵌套的标签存在父子关系,其中,父为外层标签,子为内层标签。本实例将用两个简单的标签来演示,父标签则作出逻辑判断,如果isOutput属性为true,则输出实例108中的标签helloTag;如果为false,则不输出。
(1)第一步:开发标签实现类。
内层的标签helloTag在实例108中已有,此处不再列出。
haveChildTag.java
package hello;
import javax.servlet.jsp.tagext.BodyTagSupport;
public class haveChildTag extends BodyTagSupport {
private boolean isOutput;//是否输出子标签内容
//----标签开始时调用此方法-------
public int doStartTag(){
if(isOutput)
return EVAL_BODY_INCLUDE;
else return SKIP_BODY;
}
//----标签结束时调用此方法-------
public int doEndTag(){
try{
if(bodyContent!=null)
bodyContent.writeOut(bodyContent.getEnclosingWriter());
}catch(Exception e){
System.out.println(e);
}
return EVAL_PAGE;
}
public boolean getIsOutput() {
return isOutput;
}
public void setIsOutput(boolean isOutput) {
this.isOutput = isOutput;
}
}
(2)第二步:编写标签描述tld文件。
本例在myTag.tld文件中增加内容。在<taglib>与</taglib>之间增加的如下内容:
<!-- haveChildTag-->
<tag>
<!-- 标签名称-->
<name>haveChildTag</name>
<!-- 标签对应的处理类-->
<tag-class>hello.haveChildTag</tag-class>
<!-- 标签体内容,有标签体则设为jsp-->
<body-content>jsp</body-content>
<!-- 标签的属性声明-->
<attribute>
<name>isOutput</name>
<required>true</required>
<rtexprvalue>true</rtexprvalue>
</attribute>
</tag>
(3)第三步:在Web应用的web.xml文件中声明标签库引用。
同样,本例与本章前面的实例使用同一个tld文件,此处不必再修改。
(4)第四步:在JSP页面中声明并调用标签。
useHaveChildTag.jsp
<%@ taglib uri="/myTag" prefix="myTag" %>
<%@ page contentType="text/html;charset=GB2312" %>
<%@ page import="java.util.Date" %>
<html>
<head>
<title>开发嵌套的标签</title>
</head>
<body>
输出子标签时的结果:<br>
<myTag:haveChildTag isOutput="true">
<myTag:helloTag/>
</myTag:haveChildTag><br>
不输出子标签时的结果:<br>
<myTag:haveChildTag isOutput="false">
<myTag:helloTag/>
</myTag:haveChildTag><br>
</body>
</html>
该程序的运行结果如图13-5所示。
《JSP网络编程从实践到实践》原码下载地址:http://shop.csai.cn/itbook/itbookinfo.asp?lbbh=10051575
五、 开发迭代的标签
【实例112】 开发迭代的标签:iterateTag
对于集合对象的Iterator类对象,在JSP的Java代码中需要用while循环或for循环来输出,难于维护,且可复用性不好,程序员总是在大量地做这样的工作,这时可以考虑用迭代的标签来开发,需要输出数据时只须在JSP页面中声明标签即可。
开发迭代的标签,需要设计两个Java类:标签实现类和表示标签信息的类。本实例中标签实现类为iterateTag.java,表示标签信息的类为IterateTEI.java。开发迭代的标签可实现IterationTag接口,也可从TagSupport类或BodyTagSupport类继承,由于BodyTagSupport类继承自TagSupport类,而TagSupport类又实现了IterationTag接口,为简化开发,直接从BodyTagSupport类继承即可。
(1)第一步:开发标签实现类和表示标签信息的类。
iterateTag.java
package body;
import java.util.Collection;
import java.util.Iterator;
import javax.servlet.jsp.tagext.BodyTagSupport;
public class iterateTag extends BodyTagSupport{
private String name;//在pageContext中标识的一个属性名
private Iterator it;//要迭代的对象
private String type;//it中对象的类型
public void setCollection(Collection collection){
if(collection.size()>0)
it=collection.iterator();
}
//----标签开始时调用此方法-------
public int doStartTag(){
if(it==null) return SKIP_BODY;
else return continueNext(it);
}
//----标签体执行完后调用此方法----
public int doAfterBody(){
return continueNext(it);
}
//----标签结束时调用此方法-------
public int doEndTag(){
try{
if(bodyContent!=null)
bodyContent.writeOut(bodyContent.getEnclosingWriter());
}catch(Exception e){
System.out.println(e);
}
return EVAL_PAGE;
}
//----迭代----
protected int continueNext(Iterator it){
if(it.hasNext()){
pageContext.setAttribute(name,it.next(),pageContext.PAGE_SCOPE);
return EVAL_BODY_TAG;
}else return SKIP_BODY;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getType() {
return type;
}
public void setType(String type) {
this.type = type;
}
}
在标签实现类中,有3个属性:name、type和it。其中,name代表在pageContext中标识一个属性的名字;type代表待迭代内容的数据类型;it为要迭代的内容。在doStartTag()方法中,如果it不为null,就开始迭代,迭代时调用continueNext()方法。
IterateTEI.java
package body;
import javax.servlet.jsp.tagext.TagData;
import javax.servlet.jsp.tagext.TagExtraInfo;
import javax.servlet.jsp.tagext.VariableInfo;
//----提供标签翻译时的一些相关信息----
public class IterateTEI extends TagExtraInfo {
public IterateTEI() {
super();
}
public VariableInfo[] getVariableInfo(TagData data){
return new VariableInfo[]{
new VariableInfo(data.getAttributeString("name"),
data.getAttributeString("type"),
true,VariableInfo.NESTED)
};
}
}
VariableInfo类中有几个常量,具体的含义为:
NESTED:标签中的参数在标签开始到标签结束之间是有效的。
AT_BEGIN:标签中的参数在标签开始到使用它的JSP页面结束是有效的。
AT_END:标签中的参数在标签的结束到使用它的JSP页面结束是有效的。
(2)第二步:编写标签描述tld文件。本例在myTag.tld文件中增加内容。在<taglib>与</taglib>之间增加如下内容:
<!-- iterateTag-->
<tag>
<!-- 标签名称-->
<name>iterateTag</name>
<!-- 标签对应的处理类-->
<tag-class>body.iterateTag</tag-class>
<tei-class>body.IterateTEI</tei-class>
<!-- 标签体内容,有标签体则设为jsp-->
<body-content>jsp</body-content>
<!-- 标签的属性声明-->
<attribute>
<name>collection</name>
<required>true</required>
<rtexprvalue>true</rtexprvalue>
</attribute>
<attribute>
<name>name</name>
<required>true</required>
</attribute>
<attribute>
<name>type</name>
<required>true</required>
</attribute>
</tag>
</taglib>
(3)第三步:在Web应用的web.xml文件中声明标签库引用。同样,本例与本章前面的实例使用同一个tld文件,因此不必再修改。
(4)第四步:在JSP页面中声明并调用标签。
<%@ taglib uri="/myTag" prefix="myTag" %>
<%@ page contentType="text/html;charset=GB2312" %>
<%@ page import="java.util.ArrayList"%>
<head>
<title>开发迭代的标签</title>
</head>
<body>
开发一个迭代的标签,输出结果:<br>
<%//----------设置一个ArrayList对象的初始值----------
ArrayList testCol=new ArrayList();
testCol.add("邓佳容");
testCol.add("黄婧");
testCol.add("邓子云");
request.setAttribute("testCol",testCol);
%>
<myTag:iterateTag name="testColOne" collection="<%=testCol%>" type="String">
输出一个值:<%=testColOne.toString()%><br>
</myTag:iterateTag>
</body>
</html>
该程序的运行结果如图13-6所示。
发表评论
-
http:get和post的区别
2011-01-05 16:48 9601. get 是从服务器上获取数据,post 是向服务器传送数 ... -
JSP动态网页程序设计
2010-11-29 10:27 1152JSP(JavaServer Pages): J ... -
写自定义标签时标记attribute里rtexprvalue的用法
2010-10-31 21:08 964其实以前也有写过自定义标签, 但是没有注意到过<rtex ... -
带标签体的标签
2010-10-31 21:08 1380带标签体的标签,就是允许在标签内嵌套标签,通常可用于完成一些逻 ... -
自定义标签控制过长字符串的显示
2010-10-31 21:06 994问题描述: 关于自动换行问题,正常字符的换行是比较合理的,而 ... -
JSP自定义标签执行顺序
2010-10-31 21:05 1124首先来看一下简单标签 ... -
JSP自定义标签开发流程
2010-10-31 21:04 982一、概述 jsp(SUN企业级应用的首选)中有一 ... -
自定义标签问答
2010-10-31 21:03 8871. 什么是自定义标签 ... -
自定义标签类 判断权限
2010-10-31 21:03 1767功能 :判断当前用户是否有权限访问当页面 思路:读取当 ... -
JSP2的自定义标签(简单,带属性,带标签体)
2010-10-31 21:02 2225引用 在JSP规范的1.1版中增加了自定义标签库规范,自定义标 ... -
JSP自定义标签学习(基础)
2010-10-31 20:57 981自定义标签的最大的特点: 利用 自定义标签,软件开发人员和页面 ... -
关于EL 表达式
2010-10-13 23:10 1180关于EL 表达式 EL表达式总是用大括号括起,而且前面有一个 ... -
页面跳转大全
2010-10-04 13:29 1535JSP中的跳转: (1). forward()方法 使 ... -
JSP、Servlet、Tomcat、JDK、J2EE版本比较(转)
2010-10-03 23:55 734一 JSP2.0与JSP1.2比较 JSP 2.0是对JS ... -
jsp内置对象
2010-04-12 11:27 1119这几天整理项目资料,发现好多东西都快忘记了,因此打算从头整理一 ... -
页面状态响应码
2010-03-29 09:30 1353状态响应码 100~199:表 ... -
JSTL与EL表达式
2010-03-27 14:51 3212取Session中的值 <c:out value=&q ...
相关推荐
本系统的开发与设计是基于vue为前端页面核心框架为django/flask,技术方面主要采用了Html、Js、CSS3、python、Mysql。 本课题使用Python语言进行开发。代码层面的操作主要在PyCharm中进行,将系统所使用到的表以及数据存储到MySQL数据库中,方便对数据进行操作本课题基于WEB的开发平台 ②前端开发选择:Vue。 ②后端开发选择:python、django/flask。 ③数据库选择:MySQL。 ④开发工具选择:pycharm、Navicat for MySQL。 包含了我的信息、用户管理、期货公司管理、开户信息管理、充值信息管理、期货期货信息管理、期货投资管理、取消投资管理、投资风险管理、意见反馈、系统管理
springboot052基于Springboot+Vue旅游管理系统毕业源码案例设计 1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md或论文文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。 5、资源来自互联网采集,如有侵权,私聊博主删除。 6、可私信博主看论文后选择购买源代码。 1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md或论文文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。 5、资源来自互联网采集,如有侵权,私聊博主删除。 6、可私信博主看论文后选择购买源代码。 1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md或论文文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。 5、资源来自互联网采集,如有侵权,私聊博主删除。 6、可私信博主看论文后选择购买源代码。
1.版本:matlab2014/2019a/2024a 2.附赠案例数据可直接运行matlab程序。 3.代码特点:参数化编程、参数可方便更改、代码编程思路清晰、注释明细。 4.适用对象:计算机,电子信息工程、数学等专业的大学生课程设计、期末大作业和毕业设计。 替换数据可以直接使用,注释清楚,适合新手
1.版本:matlab2014/2019a/2024a 2.附赠案例数据可直接运行matlab程序。 3.代码特点:参数化编程、参数可方便更改、代码编程思路清晰、注释明细。 4.适用对象:计算机,电子信息工程、数学等专业的大学生课程设计、期末大作业和毕业设计。 替换数据可以直接使用,注释清楚,适合新手
1.版本:matlab2014/2019a/2024a 2.附赠案例数据可直接运行matlab程序。 3.代码特点:参数化编程、参数可方便更改、代码编程思路清晰、注释明细。 4.适用对象:计算机,电子信息工程、数学等专业的大学生课程设计、期末大作业和毕业设计。 替换数据可以直接使用,注释清楚,适合新手
1.版本:matlab2014/2019a/2024a 2.附赠案例数据可直接运行matlab程序。 3.代码特点:参数化编程、参数可方便更改、代码编程思路清晰、注释明细。 4.适用对象:计算机,电子信息工程、数学等专业的大学生课程设计、期末大作业和毕业设计。 替换数据可以直接使用,注释清楚,适合新手
1.版本:matlab2014/2019a/2024a 2.附赠案例数据可直接运行matlab程序。 3.代码特点:参数化编程、参数可方便更改、代码编程思路清晰、注释明细。 4.适用对象:计算机,电子信息工程、数学等专业的大学生课程设计、期末大作业和毕业设计。 替换数据可以直接使用,注释清楚,适合新手
计算机图形学之动画和模拟算法:Keyframe Animation:碰撞检测与响应.docx
行业研究报告、行业调查报告、研报
调用文心一言api的一个尝试
hertzbeat的docker镜像文件
1.版本:matlab2014/2019a/2024a 2.附赠案例数据可直接运行matlab程序。 3.代码特点:参数化编程、参数可方便更改、代码编程思路清晰、注释明细。 4.适用对象:计算机,电子信息工程、数学等专业的大学生课程设计、期末大作业和毕业设计。 替换数据可以直接使用,注释清楚,适合新手
1.版本:matlab2014/2019a/2024a 2.附赠案例数据可直接运行matlab程序。 3.代码特点:参数化编程、参数可方便更改、代码编程思路清晰、注释明细。 4.适用对象:计算机,电子信息工程、数学等专业的大学生课程设计、期末大作业和毕业设计。 替换数据可以直接使用,注释清楚,适合新手
项目经过测试均可完美运行! 环境说明: 开发语言:java jdk:jdk1.8 数据库:mysql 5.7+ 数据库工具:Navicat11+ 管理工具:maven 开发工具:idea/eclipse
1.版本:matlab2014/2019a/2024a 2.附赠案例数据可直接运行matlab程序。 3.代码特点:参数化编程、参数可方便更改、代码编程思路清晰、注释明细。 4.适用对象:计算机,电子信息工程、数学等专业的大学生课程设计、期末大作业和毕业设计。 替换数据可以直接使用,注释清楚,适合新手
1.版本:matlab2014/2019a/2024a 2.附赠案例数据可直接运行matlab程序。 3.代码特点:参数化编程、参数可方便更改、代码编程思路清晰、注释明细。 4.适用对象:计算机,电子信息工程、数学等专业的大学生课程设计、期末大作业和毕业设计。 替换数据可以直接使用,注释清楚,适合新手
计算机图形学之动画和模拟算法:Procedural Animation:物理基础:力与运动.docx
1.版本:matlab2014/2019a/2024a 2.附赠案例数据可直接运行matlab程序。 3.代码特点:参数化编程、参数可方便更改、代码编程思路清晰、注释明细。 4.适用对象:计算机,电子信息工程、数学等专业的大学生课程设计、期末大作业和毕业设计。 替换数据可以直接使用,注释清楚,适合新手
1.版本:matlab2014/2019a/2024a 2.附赠案例数据可直接运行matlab程序。 3.代码特点:参数化编程、参数可方便更改、代码编程思路清晰、注释明细。 4.适用对象:计算机,电子信息工程、数学等专业的大学生课程设计、期末大作业和毕业设计。 替换数据可以直接使用,注释清楚,适合新手
2112312312321321