一、JSP自定义标签简介
标签是一种XML元素,通过标签可以使JSP网页变得简洁并且易于维护,还可以方便地实现同一个JSP文件支持多种语言版本。由于标签是XML元素,所以它的名称和属性都是大小写敏感的
标准JSP标签是用来调用JavaBean组件的操作,处理定向请求以简化JSP页面开发与维护。JSP技术提供了一种封装其它动态类型的机制——自定义标签,它扩展了JSP语言。自定义标签通常发布在标签库中,该库定义了一个自定义标签集并包含实现标签的对象。
自定义标签是用户定义的JSP语言元素。当JSP页面包含一个自定义标签时被转化为servlet,标签转化为对称为tag handler的对象的操作。接着当servlet执行时Web container调用那些操作。
二、两种标签
可以定义两种类型的标签:
javax.servlet.jsp.tagext.Tag
javax.servlet.jsp.tagext.BodyTag
有标签体的标签必须实现 BodyTag 接口。
Html代码
<jsptag:map scope=“session” name=“tagMap”>
body
</jsptag:map>
<jsptag:map scope=“session” name=“tagMap”>
body
</jsptag:map>
也可能没有标签体:
Html代码
<jsptag:map/>
<jsptag:map/> 无标签体的简单标签可以实现 Tag 接口。
三、标签处理程序
int doStartTag() throws JspException---处理开始标签
int doEndTag() throws JspException---处理结束标签
Tag getParent()/void setParent(Tag t)---获得/设置标签的父标签
void setPageContext(PageContext pc)--- pageContext 属性的 setter 方法
void release() 释放获得的所有资源
doStartTag()和doEndTag()方法的返回值说明:
SKIP_BODY 表示不用处理标签体,直接调用doEndTag()方法。
SKIP_PAGE 忽略标签后面的jsp(SUN企业级应用的首选)内容。
EVAL_PAGE 处理标签后,继续处理jsp(SUN企业级应用的首选)后面的内容。
EVAL_BODY_BUFFERED 表示需要处理标签体,且需要重新创建一个缓冲(调用setBodyContent方法)。
EVAL_BODY_INCLUDE 表示在现有的输出流对象中处理标签体,但绕过setBodyContent()和doInitBody()方法
EVAL_BODY_AGAIN 对标签体循环处理。(存在于javax.servlet.jsp.tagext.IterationTag接口中)
实现javax.servlet.jsp.tagext.Tag接口
扩展javax.servlet.jsp.tagext.TagSupport类
TagSupport 类定义了 get/setParent() 和 setPageContext(),这与所有标签处理程序几乎相同。
get/setParent() 方法允许标签嵌套。
TagSupport 类还定义了一个可以被子类使用的 pageContext 实例变量 (protected PageContext pageContext),这个变量是由 setPageContext() 方法设置的。
在创建自定义标签之前,需要创建一个 标签处理程序。标签处理程序是一个执行自定义标签操作的 Java 对象。在使用自定义标签时,要导入一个 标签库 —— 即一组标签/标签处理程序对。通过在 Web 部署描述符中声明库导入它,然后用指令 taglib 将它导入 JSP 页。
Html代码
<%@ taglib uri="firstTag" prefix="my"%>
<%@ taglib uri="firstTag" prefix="my"%>
如果 JSP 容器在转换时遇到了自定义标签,那么它就检查 标签库描述符(tag library descriptor) (TLD) 文件以查询相应的标签处理程序。TLD 文件对于自定义标签处理程序,就像 Web 部署描述符对于 servlet 一样。
在运行时,JSP 页生成的 servlet 得到对应于这一页面所使用的标签的标签处理程序的一个实例。生成的 servlet 用传递给它的属性初始化标签处理程序。
标签处理程序实现了 生存周期 方法。生成的 servlet 用这些方法通知标签处理程序应当启动、停止或者重复自定义标签操作。生成的 servlet 调用这些生存周期方法执行标签的功能。
四、TLD 文件
TLD 文件的根元素是 taglib。taglib 描述了一个 标签库 —— 即一组标签/标签处理程序对。
因为我们使用的是 JSP 版本 1.2,所以在这个例子中需要 tlib-version 和 short-name 元素。
tlib-version 元素对应于标签库版本。
jsp-version 对应于标签库所依赖的 JSP 技术的版本。
short-name 元素定义了 IDE 和其他开发工具可以使用的标签库的简单名。
taglib 元素包含许多 tag 元素,标签库中每一个标签有一个 tag 元素。
五、编写自定义迭代标签和el表达式调用类的静态方法实例
循环标签体类:ForEach.java
Java代码
import java.util.Collection;
import java.util.Iterator;
import javax.servlet.jsp.JspException;
import javax.servlet.jsp.tagext.BodyContent;
import javax.servlet.jsp.tagext.BodyTagSupport;
public class ForEach extends BodyTagSupport
{
private String id;
private String collection;
private Iterator iter;
public void setCollection(String collection)
{
this.collection = collection;
}
public void setId(String id)
{
this.id = id;
}
//遇到开始标签执行
public int doStartTag() throws JspException
{
Collection coll = (Collection) pageContext.findAttribute(collection);
// 表示如果未找到指定集合,则不用处理标签体,直接调用doEndTag()方法。
if(coll==null||coll.isEmpty()) return SKIP_BODY;
iter = coll.iterator();
pageContext.setAttribute(id, iter.next());
// 表示在现有的输出流对象中处理标签体,但绕过setBodyContent()和doInitBody()方法
// 这里一定要返回EVAL_BODY_INCLUDE,否则标签体的内容不会在网页上输出显示
return EVAL_BODY_INCLUDE;
}
//在doInitBody方法之前执行,在这里被绕过不执行
@Override
public void setBodyContent(BodyContent arg0)
{
System.out.println("setBodyContent...");
super.setBodyContent(arg0);
}
//此方法被绕过不会被执行
@Override
public void doInitBody() throws JspException
{
System.out.println("doInitBody...");
super.doInitBody();
}
//遇到标签体执行
public int doAfterBody() throws JspException
{
if(iter.hasNext())
{
pageContext.setAttribute(id, iter.next());
return EVAL_BODY_AGAIN;// 如果集合中还有对像,则循环执行标签体
}
return SKIP_BODY;//迭代完集合后,跳过标签体,调用doEndTag()方法。
}
//遇到结束标签执行
public int doEndTag() throws JspException
{
System.out.println("doEndTag...");
return EVAL_PAGE;
}
}
import java.util.Collection;
import java.util.Iterator;
import javax.servlet.jsp.JspException;
import javax.servlet.jsp.tagext.BodyContent;
import javax.servlet.jsp.tagext.BodyTagSupport;
public class ForEach extends BodyTagSupport
{
private String id;
private String collection;
private Iterator iter;
public void setCollection(String collection)
{
this.collection = collection;
}
public void setId(String id)
{
this.id = id;
}
//遇到开始标签执行
public int doStartTag() throws JspException
{
Collection coll = (Collection) pageContext.findAttribute(collection);
// 表示如果未找到指定集合,则不用处理标签体,直接调用doEndTag()方法。
if(coll==null||coll.isEmpty()) return SKIP_BODY;
iter = coll.iterator();
pageContext.setAttribute(id, iter.next());
// 表示在现有的输出流对象中处理标签体,但绕过setBodyContent()和doInitBody()方法
// 这里一定要返回EVAL_BODY_INCLUDE,否则标签体的内容不会在网页上输出显示
return EVAL_BODY_INCLUDE;
}
//在doInitBody方法之前执行,在这里被绕过不执行
@Override
public void setBodyContent(BodyContent arg0)
{
System.out.println("setBodyContent...");
super.setBodyContent(arg0);
}
//此方法被绕过不会被执行
@Override
public void doInitBody() throws JspException
{
System.out.println("doInitBody...");
super.doInitBody();
}
//遇到标签体执行
public int doAfterBody() throws JspException
{
if(iter.hasNext())
{
pageContext.setAttribute(id, iter.next());
return EVAL_BODY_AGAIN;// 如果集合中还有对像,则循环执行标签体
}
return SKIP_BODY;//迭代完集合后,跳过标签体,调用doEndTag()方法。
}
//遇到结束标签执行
public int doEndTag() throws JspException
{
System.out.println("doEndTag...");
return EVAL_PAGE;
}
} 获取VO属性类:GetProperty.java
Java代码
import java.lang.reflect.Method;
import javax.servlet.jsp.JspException;
import javax.servlet.jsp.tagext.BodyTagSupport;
public class GetProperty extends BodyTagSupport
{
private String name;
private String property;
public void setName(String name)
{
this.name = name;
}
public void setProperty(String property)
{
this.property = property;
}
@SuppressWarnings("unchecked")
public int doStartTag() throws JspException
{
try
{
Object obj = pageContext.findAttribute(name);
if (obj == null) return SKIP_BODY;
Class c = obj.getClass();
//构造GET方法名字 get+属性名(属性名第一个字母大写)
String getMethodName = "get" + property.substring(0, 1).toUpperCase()
+ property.substring(1, property.length());
Method getMethod = c.getMethod(getMethodName, new Class[]{});
pageContext.getOut().print(getMethod.invoke(obj));
System.out.print(property + ":" + getMethod.invoke(obj) + "\t");
} catch (Exception e)
{
e.printStackTrace();
}
return SKIP_BODY;
}
public int doEndTag() throws JspException
{
return EVAL_PAGE;
}
}
import java.lang.reflect.Method;
import javax.servlet.jsp.JspException;
import javax.servlet.jsp.tagext.BodyTagSupport;
public class GetProperty extends BodyTagSupport
{
private String name;
private String property;
public void setName(String name)
{
this.name = name;
}
public void setProperty(String property)
{
this.property = property;
}
@SuppressWarnings("unchecked")
public int doStartTag() throws JspException
{
try
{
Object obj = pageContext.findAttribute(name);
if (obj == null) return SKIP_BODY;
Class c = obj.getClass();
//构造GET方法名字 get+属性名(属性名第一个字母大写)
String getMethodName = "get" + property.substring(0, 1).toUpperCase()
+ property.substring(1, property.length());
Method getMethod = c.getMethod(getMethodName, new Class[]{});
pageContext.getOut().print(getMethod.invoke(obj));
System.out.print(property + ":" + getMethod.invoke(obj) + "\t");
} catch (Exception e)
{
e.printStackTrace();
}
return SKIP_BODY;
}
public int doEndTag() throws JspException
{
return EVAL_PAGE;
}
} 表达式直接访问此类中静态的方法:ELFunction.java
Java代码
public class ELFunction
{
public static int add( int i,int j )
{
return i+j;
}
}
public class ELFunction
{
public static int add( int i,int j )
{
return i+j;
}
}写一个测试用的VO类:UserVo.java
Java代码
public class UserVo
{
private String name;
private String password;
public String getName()
{
return name;
}
public void setName(String name)
{
this.name = name;
}
public String getPassword()
{
return password;
}
public void setPassword(String password)
{
this.password = password;
}
}
public class UserVo
{
private String name;
private String password;
public String getName()
{
return name;
}
public void setName(String name)
{
this.name = name;
}
public String getPassword()
{
return password;
}
public void setPassword(String password)
{
this.password = password;
}
} 建好TLD文件tag.tld,放在WEB-INF目录下
Xml代码
<?xml version="1.0" encoding="utf-8"?>
<taglib version="2.0"
xmlns="http://java.sun.com/xml/ns/j2ee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:shcemalocation="http://java.sun.com/xml/ns/j2ee
http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd">
<description>自定义标签</description>
<display-name>JSTL core</display-name>
<tlib-version>1.1</tlib-version>
<short-name>firstLabel</short-name>
<uri>http://java.sun.com/jsp/jstl/core</uri>
<!-- 创建自定义 迭代标签 -->
<tag>
<name>forEach</name>
<tag-class>exercise.taglib.ForEach</tag-class>
<!-- 如果没有标签体,设置empty , 如果有标签休必须设置JSP-->
<body-content>JSP</body-content>
<attribute>
<name>id</name>
<required>true</required><!-- 标识属性是否是必须的 -->
<rtexprvalue>true</rtexprvalue><!-- 标识属性值是否可以用表达式语言 -->
</attribute>
<attribute>
<name>collection</name>
<required>true</required>
<rtexprvalue>true</rtexprvalue>
</attribute>
</tag>
<!-- 创建自定义获得属性标签 -->
<tag>
<name>getProperty</name>
<tag-class>exercise.taglib.GetProperty</tag-class>
<body-content>empty</body-content>
<attribute>
<name>name</name>
<required>true</required>
<rtexprvalue>true</rtexprvalue>
</attribute>
<attribute>
<name>property</name>
<required>true</required>
<rtexprvalue>true</rtexprvalue>
</attribute>
</tag>
<!-- 配置一个表达式调用 的函数 -->
<function>
<name>add</name><!-- 配置一个标签,在JSP页面通过引用前缀调用 -->
<function-class>exercise.taglib.ELFunction</function-class><!-- 实现类 -->
<function-signature>int add(int,int)</function-signature><!-- 静态的方法:包括返回类型,方法名,入参的类型 -->
</function>
</taglib>
<?xml version="1.0" encoding="utf-8"?>
<taglib version="2.0"
xmlns="http://java.sun.com/xml/ns/j2ee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:shcemalocation="http://java.sun.com/xml/ns/j2ee
http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd">
<description>自定义标签</description>
<display-name>JSTL core</display-name>
<tlib-version>1.1</tlib-version>
<short-name>firstLabel</short-name>
<uri>http://java.sun.com/jsp/jstl/core</uri>
<!-- 创建自定义 迭代标签 -->
<tag>
<name>forEach</name>
<tag-class>exercise.taglib.ForEach</tag-class>
<!-- 如果没有标签体,设置empty , 如果有标签休必须设置JSP-->
<body-content>JSP</body-content>
<attribute>
<name>id</name>
<required>true</required><!-- 标识属性是否是必须的 -->
<rtexprvalue>true</rtexprvalue><!-- 标识属性值是否可以用表达式语言 -->
</attribute>
<attribute>
<name>collection</name>
<required>true</required>
<rtexprvalue>true</rtexprvalue>
</attribute>
</tag>
<!-- 创建自定义获得属性标签 -->
<tag>
<name>getProperty</name>
<tag-class>exercise.taglib.GetProperty</tag-class>
<body-content>empty</body-content>
<attribute>
<name>name</name>
<required>true</required>
<rtexprvalue>true</rtexprvalue>
</attribute>
<attribute>
<name>property</name>
<required>true</required>
<rtexprvalue>true</rtexprvalue>
</attribute>
</tag>
<!-- 配置一个表达式调用 的函数 -->
<function>
<name>add</name><!-- 配置一个标签,在JSP页面通过引用前缀调用 -->
<function-class>exercise.taglib.ELFunction</function-class><!-- 实现类 -->
<function-signature>int add(int,int)</function-signature><!-- 静态的方法:包括返回类型,方法名,入参的类型 -->
</function>
</taglib> 在web.xml文件中配置自定义标签
Xml代码
<jsp-config>
<taglib>
<taglib-uri>firstTag</taglib-uri>
<taglib-location>/WEB-INF/tag.tld</taglib-location>
</taglib>
</jsp-config>
<jsp-config>
<taglib>
<taglib-uri>firstTag</taglib-uri>
<taglib-location>/WEB-INF/tag.tld</taglib-location>
</taglib>
</jsp-config> 在jsp文件中使用标签:tag.jsp
Java代码
<%@ page language="java" import="java.util.*" pageEncoding="utf-8"%>
<%@ taglib uri="firstTag" prefix="my"%>
<jsp:useBean id="userVo1" class="exercise.vo.UserVo" scope="request">
<jsp:setProperty name="userVo1" property="name" value="Hackiller"/>
<jsp:setProperty name="userVo1" property="password" value="123"/>
</jsp:useBean>
<jsp:useBean id="userVo2" class="exercise.vo.UserVo" scope="request">
<jsp:setProperty name="userVo2" property="name" value="YangYang"/>
<jsp:setProperty name="userVo2" property="password" value="456"/>
</jsp:useBean>
<%
List list = new ArrayList();
list.add(userVo1);
list.add(userVo2);
pageContext.setAttribute("voList",list);
%>
<html>
<head>
<title>My JSP 'tag.jsp' starting page</title>
</head>
<body>
<h2 align="center">This is my JSP page:测试taglib.</h2>
<hr>
<h2>自定义迭代标签:</h2>
<table>
<tr><td>姓名</td><td>密码</td></tr>
<my:forEach collection="voList" id="uservo">
<tr>
<td><my:getProperty name="uservo" property="name"/></td>
<td><my:getProperty name="uservo" property="password"/></td>
</tr>
</my:forEach>
</table>
<hr>
<h2>表达式调用类的静态方法:</h2>
2+5=${my:add(2,5)}
</body>
</html>
标签是一种XML元素,通过标签可以使JSP网页变得简洁并且易于维护,还可以方便地实现同一个JSP文件支持多种语言版本。由于标签是XML元素,所以它的名称和属性都是大小写敏感的
标准JSP标签是用来调用JavaBean组件的操作,处理定向请求以简化JSP页面开发与维护。JSP技术提供了一种封装其它动态类型的机制——自定义标签,它扩展了JSP语言。自定义标签通常发布在标签库中,该库定义了一个自定义标签集并包含实现标签的对象。
自定义标签是用户定义的JSP语言元素。当JSP页面包含一个自定义标签时被转化为servlet,标签转化为对称为tag handler的对象的操作。接着当servlet执行时Web container调用那些操作。
二、两种标签
可以定义两种类型的标签:
javax.servlet.jsp.tagext.Tag
javax.servlet.jsp.tagext.BodyTag
有标签体的标签必须实现 BodyTag 接口。
Html代码
<jsptag:map scope=“session” name=“tagMap”>
body
</jsptag:map>
<jsptag:map scope=“session” name=“tagMap”>
body
</jsptag:map>
也可能没有标签体:
Html代码
<jsptag:map/>
<jsptag:map/> 无标签体的简单标签可以实现 Tag 接口。
三、标签处理程序
int doStartTag() throws JspException---处理开始标签
int doEndTag() throws JspException---处理结束标签
Tag getParent()/void setParent(Tag t)---获得/设置标签的父标签
void setPageContext(PageContext pc)--- pageContext 属性的 setter 方法
void release() 释放获得的所有资源
doStartTag()和doEndTag()方法的返回值说明:
SKIP_BODY 表示不用处理标签体,直接调用doEndTag()方法。
SKIP_PAGE 忽略标签后面的jsp(SUN企业级应用的首选)内容。
EVAL_PAGE 处理标签后,继续处理jsp(SUN企业级应用的首选)后面的内容。
EVAL_BODY_BUFFERED 表示需要处理标签体,且需要重新创建一个缓冲(调用setBodyContent方法)。
EVAL_BODY_INCLUDE 表示在现有的输出流对象中处理标签体,但绕过setBodyContent()和doInitBody()方法
EVAL_BODY_AGAIN 对标签体循环处理。(存在于javax.servlet.jsp.tagext.IterationTag接口中)
实现javax.servlet.jsp.tagext.Tag接口
扩展javax.servlet.jsp.tagext.TagSupport类
TagSupport 类定义了 get/setParent() 和 setPageContext(),这与所有标签处理程序几乎相同。
get/setParent() 方法允许标签嵌套。
TagSupport 类还定义了一个可以被子类使用的 pageContext 实例变量 (protected PageContext pageContext),这个变量是由 setPageContext() 方法设置的。
在创建自定义标签之前,需要创建一个 标签处理程序。标签处理程序是一个执行自定义标签操作的 Java 对象。在使用自定义标签时,要导入一个 标签库 —— 即一组标签/标签处理程序对。通过在 Web 部署描述符中声明库导入它,然后用指令 taglib 将它导入 JSP 页。
Html代码
<%@ taglib uri="firstTag" prefix="my"%>
<%@ taglib uri="firstTag" prefix="my"%>
如果 JSP 容器在转换时遇到了自定义标签,那么它就检查 标签库描述符(tag library descriptor) (TLD) 文件以查询相应的标签处理程序。TLD 文件对于自定义标签处理程序,就像 Web 部署描述符对于 servlet 一样。
在运行时,JSP 页生成的 servlet 得到对应于这一页面所使用的标签的标签处理程序的一个实例。生成的 servlet 用传递给它的属性初始化标签处理程序。
标签处理程序实现了 生存周期 方法。生成的 servlet 用这些方法通知标签处理程序应当启动、停止或者重复自定义标签操作。生成的 servlet 调用这些生存周期方法执行标签的功能。
四、TLD 文件
TLD 文件的根元素是 taglib。taglib 描述了一个 标签库 —— 即一组标签/标签处理程序对。
因为我们使用的是 JSP 版本 1.2,所以在这个例子中需要 tlib-version 和 short-name 元素。
tlib-version 元素对应于标签库版本。
jsp-version 对应于标签库所依赖的 JSP 技术的版本。
short-name 元素定义了 IDE 和其他开发工具可以使用的标签库的简单名。
taglib 元素包含许多 tag 元素,标签库中每一个标签有一个 tag 元素。
五、编写自定义迭代标签和el表达式调用类的静态方法实例
循环标签体类:ForEach.java
Java代码
import java.util.Collection;
import java.util.Iterator;
import javax.servlet.jsp.JspException;
import javax.servlet.jsp.tagext.BodyContent;
import javax.servlet.jsp.tagext.BodyTagSupport;
public class ForEach extends BodyTagSupport
{
private String id;
private String collection;
private Iterator iter;
public void setCollection(String collection)
{
this.collection = collection;
}
public void setId(String id)
{
this.id = id;
}
//遇到开始标签执行
public int doStartTag() throws JspException
{
Collection coll = (Collection) pageContext.findAttribute(collection);
// 表示如果未找到指定集合,则不用处理标签体,直接调用doEndTag()方法。
if(coll==null||coll.isEmpty()) return SKIP_BODY;
iter = coll.iterator();
pageContext.setAttribute(id, iter.next());
// 表示在现有的输出流对象中处理标签体,但绕过setBodyContent()和doInitBody()方法
// 这里一定要返回EVAL_BODY_INCLUDE,否则标签体的内容不会在网页上输出显示
return EVAL_BODY_INCLUDE;
}
//在doInitBody方法之前执行,在这里被绕过不执行
@Override
public void setBodyContent(BodyContent arg0)
{
System.out.println("setBodyContent...");
super.setBodyContent(arg0);
}
//此方法被绕过不会被执行
@Override
public void doInitBody() throws JspException
{
System.out.println("doInitBody...");
super.doInitBody();
}
//遇到标签体执行
public int doAfterBody() throws JspException
{
if(iter.hasNext())
{
pageContext.setAttribute(id, iter.next());
return EVAL_BODY_AGAIN;// 如果集合中还有对像,则循环执行标签体
}
return SKIP_BODY;//迭代完集合后,跳过标签体,调用doEndTag()方法。
}
//遇到结束标签执行
public int doEndTag() throws JspException
{
System.out.println("doEndTag...");
return EVAL_PAGE;
}
}
import java.util.Collection;
import java.util.Iterator;
import javax.servlet.jsp.JspException;
import javax.servlet.jsp.tagext.BodyContent;
import javax.servlet.jsp.tagext.BodyTagSupport;
public class ForEach extends BodyTagSupport
{
private String id;
private String collection;
private Iterator iter;
public void setCollection(String collection)
{
this.collection = collection;
}
public void setId(String id)
{
this.id = id;
}
//遇到开始标签执行
public int doStartTag() throws JspException
{
Collection coll = (Collection) pageContext.findAttribute(collection);
// 表示如果未找到指定集合,则不用处理标签体,直接调用doEndTag()方法。
if(coll==null||coll.isEmpty()) return SKIP_BODY;
iter = coll.iterator();
pageContext.setAttribute(id, iter.next());
// 表示在现有的输出流对象中处理标签体,但绕过setBodyContent()和doInitBody()方法
// 这里一定要返回EVAL_BODY_INCLUDE,否则标签体的内容不会在网页上输出显示
return EVAL_BODY_INCLUDE;
}
//在doInitBody方法之前执行,在这里被绕过不执行
@Override
public void setBodyContent(BodyContent arg0)
{
System.out.println("setBodyContent...");
super.setBodyContent(arg0);
}
//此方法被绕过不会被执行
@Override
public void doInitBody() throws JspException
{
System.out.println("doInitBody...");
super.doInitBody();
}
//遇到标签体执行
public int doAfterBody() throws JspException
{
if(iter.hasNext())
{
pageContext.setAttribute(id, iter.next());
return EVAL_BODY_AGAIN;// 如果集合中还有对像,则循环执行标签体
}
return SKIP_BODY;//迭代完集合后,跳过标签体,调用doEndTag()方法。
}
//遇到结束标签执行
public int doEndTag() throws JspException
{
System.out.println("doEndTag...");
return EVAL_PAGE;
}
} 获取VO属性类:GetProperty.java
Java代码
import java.lang.reflect.Method;
import javax.servlet.jsp.JspException;
import javax.servlet.jsp.tagext.BodyTagSupport;
public class GetProperty extends BodyTagSupport
{
private String name;
private String property;
public void setName(String name)
{
this.name = name;
}
public void setProperty(String property)
{
this.property = property;
}
@SuppressWarnings("unchecked")
public int doStartTag() throws JspException
{
try
{
Object obj = pageContext.findAttribute(name);
if (obj == null) return SKIP_BODY;
Class c = obj.getClass();
//构造GET方法名字 get+属性名(属性名第一个字母大写)
String getMethodName = "get" + property.substring(0, 1).toUpperCase()
+ property.substring(1, property.length());
Method getMethod = c.getMethod(getMethodName, new Class[]{});
pageContext.getOut().print(getMethod.invoke(obj));
System.out.print(property + ":" + getMethod.invoke(obj) + "\t");
} catch (Exception e)
{
e.printStackTrace();
}
return SKIP_BODY;
}
public int doEndTag() throws JspException
{
return EVAL_PAGE;
}
}
import java.lang.reflect.Method;
import javax.servlet.jsp.JspException;
import javax.servlet.jsp.tagext.BodyTagSupport;
public class GetProperty extends BodyTagSupport
{
private String name;
private String property;
public void setName(String name)
{
this.name = name;
}
public void setProperty(String property)
{
this.property = property;
}
@SuppressWarnings("unchecked")
public int doStartTag() throws JspException
{
try
{
Object obj = pageContext.findAttribute(name);
if (obj == null) return SKIP_BODY;
Class c = obj.getClass();
//构造GET方法名字 get+属性名(属性名第一个字母大写)
String getMethodName = "get" + property.substring(0, 1).toUpperCase()
+ property.substring(1, property.length());
Method getMethod = c.getMethod(getMethodName, new Class[]{});
pageContext.getOut().print(getMethod.invoke(obj));
System.out.print(property + ":" + getMethod.invoke(obj) + "\t");
} catch (Exception e)
{
e.printStackTrace();
}
return SKIP_BODY;
}
public int doEndTag() throws JspException
{
return EVAL_PAGE;
}
} 表达式直接访问此类中静态的方法:ELFunction.java
Java代码
public class ELFunction
{
public static int add( int i,int j )
{
return i+j;
}
}
public class ELFunction
{
public static int add( int i,int j )
{
return i+j;
}
}写一个测试用的VO类:UserVo.java
Java代码
public class UserVo
{
private String name;
private String password;
public String getName()
{
return name;
}
public void setName(String name)
{
this.name = name;
}
public String getPassword()
{
return password;
}
public void setPassword(String password)
{
this.password = password;
}
}
public class UserVo
{
private String name;
private String password;
public String getName()
{
return name;
}
public void setName(String name)
{
this.name = name;
}
public String getPassword()
{
return password;
}
public void setPassword(String password)
{
this.password = password;
}
} 建好TLD文件tag.tld,放在WEB-INF目录下
Xml代码
<?xml version="1.0" encoding="utf-8"?>
<taglib version="2.0"
xmlns="http://java.sun.com/xml/ns/j2ee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:shcemalocation="http://java.sun.com/xml/ns/j2ee
http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd">
<description>自定义标签</description>
<display-name>JSTL core</display-name>
<tlib-version>1.1</tlib-version>
<short-name>firstLabel</short-name>
<uri>http://java.sun.com/jsp/jstl/core</uri>
<!-- 创建自定义 迭代标签 -->
<tag>
<name>forEach</name>
<tag-class>exercise.taglib.ForEach</tag-class>
<!-- 如果没有标签体,设置empty , 如果有标签休必须设置JSP-->
<body-content>JSP</body-content>
<attribute>
<name>id</name>
<required>true</required><!-- 标识属性是否是必须的 -->
<rtexprvalue>true</rtexprvalue><!-- 标识属性值是否可以用表达式语言 -->
</attribute>
<attribute>
<name>collection</name>
<required>true</required>
<rtexprvalue>true</rtexprvalue>
</attribute>
</tag>
<!-- 创建自定义获得属性标签 -->
<tag>
<name>getProperty</name>
<tag-class>exercise.taglib.GetProperty</tag-class>
<body-content>empty</body-content>
<attribute>
<name>name</name>
<required>true</required>
<rtexprvalue>true</rtexprvalue>
</attribute>
<attribute>
<name>property</name>
<required>true</required>
<rtexprvalue>true</rtexprvalue>
</attribute>
</tag>
<!-- 配置一个表达式调用 的函数 -->
<function>
<name>add</name><!-- 配置一个标签,在JSP页面通过引用前缀调用 -->
<function-class>exercise.taglib.ELFunction</function-class><!-- 实现类 -->
<function-signature>int add(int,int)</function-signature><!-- 静态的方法:包括返回类型,方法名,入参的类型 -->
</function>
</taglib>
<?xml version="1.0" encoding="utf-8"?>
<taglib version="2.0"
xmlns="http://java.sun.com/xml/ns/j2ee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:shcemalocation="http://java.sun.com/xml/ns/j2ee
http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd">
<description>自定义标签</description>
<display-name>JSTL core</display-name>
<tlib-version>1.1</tlib-version>
<short-name>firstLabel</short-name>
<uri>http://java.sun.com/jsp/jstl/core</uri>
<!-- 创建自定义 迭代标签 -->
<tag>
<name>forEach</name>
<tag-class>exercise.taglib.ForEach</tag-class>
<!-- 如果没有标签体,设置empty , 如果有标签休必须设置JSP-->
<body-content>JSP</body-content>
<attribute>
<name>id</name>
<required>true</required><!-- 标识属性是否是必须的 -->
<rtexprvalue>true</rtexprvalue><!-- 标识属性值是否可以用表达式语言 -->
</attribute>
<attribute>
<name>collection</name>
<required>true</required>
<rtexprvalue>true</rtexprvalue>
</attribute>
</tag>
<!-- 创建自定义获得属性标签 -->
<tag>
<name>getProperty</name>
<tag-class>exercise.taglib.GetProperty</tag-class>
<body-content>empty</body-content>
<attribute>
<name>name</name>
<required>true</required>
<rtexprvalue>true</rtexprvalue>
</attribute>
<attribute>
<name>property</name>
<required>true</required>
<rtexprvalue>true</rtexprvalue>
</attribute>
</tag>
<!-- 配置一个表达式调用 的函数 -->
<function>
<name>add</name><!-- 配置一个标签,在JSP页面通过引用前缀调用 -->
<function-class>exercise.taglib.ELFunction</function-class><!-- 实现类 -->
<function-signature>int add(int,int)</function-signature><!-- 静态的方法:包括返回类型,方法名,入参的类型 -->
</function>
</taglib> 在web.xml文件中配置自定义标签
Xml代码
<jsp-config>
<taglib>
<taglib-uri>firstTag</taglib-uri>
<taglib-location>/WEB-INF/tag.tld</taglib-location>
</taglib>
</jsp-config>
<jsp-config>
<taglib>
<taglib-uri>firstTag</taglib-uri>
<taglib-location>/WEB-INF/tag.tld</taglib-location>
</taglib>
</jsp-config> 在jsp文件中使用标签:tag.jsp
Java代码
<%@ page language="java" import="java.util.*" pageEncoding="utf-8"%>
<%@ taglib uri="firstTag" prefix="my"%>
<jsp:useBean id="userVo1" class="exercise.vo.UserVo" scope="request">
<jsp:setProperty name="userVo1" property="name" value="Hackiller"/>
<jsp:setProperty name="userVo1" property="password" value="123"/>
</jsp:useBean>
<jsp:useBean id="userVo2" class="exercise.vo.UserVo" scope="request">
<jsp:setProperty name="userVo2" property="name" value="YangYang"/>
<jsp:setProperty name="userVo2" property="password" value="456"/>
</jsp:useBean>
<%
List list = new ArrayList();
list.add(userVo1);
list.add(userVo2);
pageContext.setAttribute("voList",list);
%>
<html>
<head>
<title>My JSP 'tag.jsp' starting page</title>
</head>
<body>
<h2 align="center">This is my JSP page:测试taglib.</h2>
<hr>
<h2>自定义迭代标签:</h2>
<table>
<tr><td>姓名</td><td>密码</td></tr>
<my:forEach collection="voList" id="uservo">
<tr>
<td><my:getProperty name="uservo" property="name"/></td>
<td><my:getProperty name="uservo" property="password"/></td>
</tr>
</my:forEach>
</table>
<hr>
<h2>表达式调用类的静态方法:</h2>
2+5=${my:add(2,5)}
</body>
</html>
相关推荐
本教程将深入探讨JSP自定义标签的使用,同时结合实例介绍分页和下拉框绑定值的封装。 一、JSP自定义标签基础 1. **定义标签库(Tag Library)**:自定义标签首先需要定义一个TLD(Tag Library Descriptor)文件,它...
本实例将深入探讨如何实现一个简单的JSP自定义标签。 首先,自定义标签的实现主要依赖于两个核心概念:Tag接口和TagSupport类。`Tag`接口定义了自定义标签必须实现的方法,如`doStartTag()`和`doEndTag()`,它们...
在JSP自定义标签的例子中,我们可以看到这个压缩包文件可能包含了一个完整的示例项目,可以在Apache Tomcat这样的Servlet容器下直接运行。Apache Tomcat是一款开源的Servlet容器,广泛用于部署和运行Java Web应用...
本篇学习笔记将深入探讨JSP自定义标签的相关概念、创建方法以及实际应用。 一、概述 1.1 使用简单标签机制 JSP自定义标签提供了类似HTML标签的语法结构,通过自定义标签,开发者可以封装复杂的Java代码,使得页面...
在使用JSP自定义标签时,开发者可能会遇到一些报错问题,这通常涉及到项目结构、类路径设置或自定义标签的编译与打包方式。在本文中,我们将深入探讨这些问题,以及如何解决“JspException”这个特定异常。 首先,...
本文将详细讲解如何利用JSP自定义标签库实现数据列表的显示,以及涉及到的相关技术。 首先,`UserListTag.java` 是自定义标签的核心类,它继承了`javax.servlet.jsp.tagext.TagSupport` 或 `javax.servlet.jsp....
首先,我们要理解JSP自定义标签的概念。自定义标签是JSP的一种扩展机制,它允许开发者创建自己的标签库,以更加清晰和可维护的方式编写页面。自定义标签的实现通常涉及三个主要部分:标签库描述符(TLD)、标签处理...
本篇将深入探讨“JSP自定义标签之日期显示”,以及如何通过自定义标签来优雅地处理日期格式化和展示。 首先,我们要理解JSP自定义标签的基本概念。自定义标签是JSP的一种扩展,它不是Java内置的标签,而是由开发者...
综上所述,“权威实用jsp自定义标签demo,checkbox,radio>”教程旨在帮助开发者掌握如何创建和使用与选择器相关的自定义标签,从而提升JSP开发的效率和质量。通过学习这个教程,你可以了解到自定义标签的核心概念、...
综上所述,JSP自定义标签提供了一种强大的机制,使得JSP开发者能够创建定制的、可重用的代码片段,提升Web应用的开发效率和质量。通过理解和熟练运用自定义标签,开发者可以更好地组织和管理JSP项目,实现更高效的...
本教程将深入探讨如何利用JSP自定义标签来编写一个灵活、可扩展的分页系统,该系统不依赖于特定的数据库,具有很高的通用性。 首先,理解JSP自定义标签的工作原理至关重要。自定义标签由三部分组成:标签库描述符...
【jsp自定义标签库注意事项】 在Java服务器页面(JSP)开发中,自定义标签库是一种强大的工具,它能够帮助开发者创建可重用的代码片段,提高代码的可读性和可维护性。以下是对JSP自定义标签库的详细解释和使用注意...
使用jsp自定义标签的功能实现权限的控制。(如果用户没有某个模块的删除权限,就不现实这个删除按钮) 在整个项目中所有的页面都可以引入自定义的标签去做到权限的控制。 自定义标签文件 删除 可以控制页面中的每...
首先,我们需要理解JSP自定义标签的基本结构。自定义标签通常由两部分组成:标签库描述符(TLD)和标签处理类。TLD文件定义了标签的名称、属性、行为等元数据,而标签处理类则实现了这些行为,处理由JSP页面传递过来的...
jsp自定义标签jsp自定义标签jsp自定义标签jsp自定义标签
本资源“jsp自定义标签大全.rar”提供了一套全面的JSP自定义标签的实例和指南,旨在帮助开发者深入理解和应用这一特性。 **JSP自定义标签的基本概念** JSP自定义标签不同于标准动作标签(如<jsp:include>或<jsp:...
本教程将深入探讨JSP自定义标签的实例与详细讲解。 一、JSP自定义标签概述 JSP自定义标签是类似于HTML标签的自定义组件,但它们提供了更强大的功能,可以封装Java代码,提供复杂的业务逻辑。自定义标签通过TLD(Tag...
本文将深入讲解JSP自定义标签的相关概念、格式、处理过程以及创建和使用自定义标签库的基本步骤。 1. 基本概念: - **标签**:JSP标签是XML元素,用于简化JSP页面,使其更易读且支持多语言版本。标签名和属性区分...