JSP自定义标签 实例
定义:自定义标签是一种非常优秀的组件技术。通过使用自定义标签库,可以在简单的标签中封装复杂的
???????? 功能;
?
理解:其将JSP页面中的(复杂、重复并且格式统一的)内容封装,使用一个标签代替;
???????? 标签对应一个类,在类中有固定的方法,这些方法在编译JSP页面中的自定义标签时,被调用。方法内输出被封装的内容;
?
???????? 标签——>JAVA类——>类方法输出页面内容
?
自定义标签的分类:
???? 1.简单标签;
???? 2.带属性的标签;
???? 3.带标签体的标签;
???? 4.可以被script使用的标签;
?
实现自定义标签的步骤
??? 1.开发自定义标签处理类;
????2.建立一个*.tld文件,每个*.tld文件对应一个标签库,每个标签库对应多个标签;
??? 3.在web.xml文件中增加自定义标签的定义;
??? 4.在JSP文件中使用自定义标签;
?
一;开发自定义标签类
???
?
?
类名方法名作用备用TagSupportdoEndTag()
destroy()
该方法在标签结束生成页面内容
销毁标签时调用的方法
简单标签
带属性的标签
BodyTagSupportdoStartTag()
doAfterBody()
doEndTag()
?
开始处理方法时,调用该方法
每次标签体处理完后调用该方法
标签体结束时调用该方法
带标签体的标签????2.2?标签流向控制
返回值
意义
SKIP_BODY
表示不用处理标签体,直接调用doEndTag()方法。
SKIP_PAGE
忽略标签后面的JSP内容。
EVAL_PAGE
处理标签后,继续处理JSP后面的内容。
EVAL_BODY_BUFFERED
表示需要处理标签体。
EVAL_BODY_INCLUDE
表示需要处理标签体,但绕过setBodyContent()和doInitBody()方法
EVAL_BODY_AGAIN
对标签体循环处理。
二;建立TLD文件
???? TLD是Tag Library Definition的缩写,即标签库定义,文件的后缀是.tld,每个TLD文件对应一个标签库,一个标签库对应多个标签;
??? <taglib>
?????? 定义标签库版本
?????? <tlib-version>1.0</tlib-version>
?????? 定义JSP版本
?????? <jsp-version>1.2</jsp-version>
?????? 配置第一个标签
?????? <short-name>mytag</short-name>
?
???? <tag>
????????? 配置标签名
???????? <name>helloworld</name>
????????? 确定标签的处理类
?????????<tag-class>mytag.HelloWorldTag</tag-class>
??????????确定标签体,标签体为空
?????????<body-content>empty</body-content>
???? </tag>
?? </taglib>
?
三;在web.xml文件中增加标签库定义
?
???? ?<jsp-config>
???????????定义标签库
????????? <taglib>
???????????确定标签库的URL
??????????<taglib-uri>/helloworld</taglib-uri>
?????????? 确定标签库定义文件的位置
??????????<taglib-location>/WEB-INF/helloworld.tld</taglib-location>
????????? </taglib>
??????</jsp-config>
?
四:使用标签库
????? 1.导入标签库:使用taglib编译指令导入标签
????? <%@ taglib uri="/helloworld" prefix="mytag"%>
????? 2.使用标签:在JSP页面中使用自定义标签
????? <mytag:helloworld></mytag:helloworld>
????
?
?---------------------------------------------------
?案例
?案例目标
?配置三种标签
?1.简单
?2.带属性
?3.带标签体
?一;标签类的实现
??? 1.简单标签
package mytag;
import java.io.IOException;
import javax.servlet.jsp.*;
import javax.servlet.jsp.tagext.*;
/**
?* 简单标签实体类
?*/
public class HelloWorldTag extends TagSupport {
?/**
? * 标签开始 执行语句
? */
?@Override
?public int doStartTag() throws JspException {
??return EVAL_BODY_INCLUDE;
?}
?/**
? * 标签结束 执行语句
? */
?@Override
?public int doEndTag() throws JspException {
??try{
???pageContext.getOut().write("Hello world");
??}catch(Exception ex){
???throw new JspTagException("错误");
??}
??return EVAL_PAGE;
?}
}
?2.带属性标签类
package mytag;
import java.io.Writer;
import java.util.Arrays;
import java.util.List;
import javax.servlet.jsp.JspException;
import javax.servlet.jsp.tagext.TagSupport;
import entity.Peron;
/**
?* 带属性的标签
?*/
public class QueryTag extends TagSupport {
?// 标签的属性
?private int rows;
?
?public int getRows() {
??return rows;
?}
?public void setRows(int rows) {
??this.rows = rows;
?}
?/**
? * 标签处理
? */
?@Override
?public int doEndTag() throws JspException {
??try {
???// 生成假数据对象
???Peron p1 = new Peron("no1", 10), p2 = new Peron("no2", 13), p3 = new Peron(
?????"no3", 15);
???// 生成假集合
???List<Peron> PL = Arrays.asList(p1, p2, p3);
???// 获取页面输出流
???Writer out = pageContext.getOut();
???// 输出
???out.write("<table>");
???Peron p = null;
???for (int i = 0;i < rows;i++) {
????p = PL.get(i);
????out.write("<tr>");
?????out.write("<td>");
??????out.write(p.getName());
?????out.write("</td>");
?????out.write("<td>");
??????out.write(p.getAge());
?????out.write("</td>");
????out.write("</tr>");
???}
???out.write("</table>");
??} catch (Exception ex) {
???System.out.println("标签处理产生异常");
??}
??return EVAL_PAGE;
?}
}
3.带标签体的标签
?? 1.外部标签类
package mytag;
import java.util.List;
import javax.servlet.jsp.JspException;
import javax.servlet.jsp.tagext.BodyTagSupport;
/**
?*?带标签体的标签
?*?完成迭代功能
?*/
public class MyiteratorTag extends BodyTagSupport{
?//标签需要迭代的集合对象名
?//从页面内传递一个值,该值代表页面page内的一个集合的名称
?private String bean;
?//集合对象的元素下标值
?private String item;
?//集合当前索引
?private int i = 0;
?//集合大小
?private int size ;
?//?
?private List<String> itemList;
?
?public String getBean() {
??return bean;
?}
?public void setBean(String bean) {
??this.bean = bean;
?}
?public String getItem() {
??return item;
?}
?public void setItem(String item) {
??this.item = item;
?}
?
?/**
? * 开始处理标签时,调用该方法
? */
?@Override
?public int doStartTag() throws JspException {
??try{
??pageContext.getOut().write("进入MyiteratorTag-doStartTag方法");
??}catch(Exception ex){}
??//从page范围中获取List对象
??itemList = (List<String>)pageContext.getAttribute(bean);
??//获取集合长度
??size = itemList.size();
??//将集合当前索引的值放在page范围的item变量中
??pageContext.setAttribute(item, itemList.get(i));
??//返回值为EVAL_BODY_BUFFERED;表明需要计算标签体
??return EVAL_BODY_BUFFERED;
?}
?/**
? * 每次标签体处理完后调用该方法
? *
? */
?@Override
?public int doAfterBody() throws JspException {
??try{
???pageContext.getOut().write("进入MyiteratorTag-doAfterbody方法");
??}catch(Exception ex){}
??//移动List对象的索引位置
??i++;
??//如果索引已经超过集合的长度
??if(i>=size){
???//索引归零
???i=0;
???//不在计算标签体
???return SKIP_BODY;
??}
??//将集合的当前元素值放入page范围的item属性中
??pageContext.setAttribute(item, itemList.get(i));
??//循环计算标签体
??return?EVAL_BODY_AGAIN;
?}
?/**
? * 标签体结束时调用该方法
? */
?@Override
?public int doEndTag() throws JspException {
??try{
???pageContext.getOut().write("进入MyiteratorTag-doEndTag方法");
???//输出标签体内容
???bodyContent.writeOut(pageContext.getOut());
??}catch(Exception ex){
???throw new JspException("错误");
??}
??return super.doEndTag();
?}
}
2.内部标签类
package mytag;
import javax.servlet.jsp.JspException;
import javax.servlet.jsp.tagext.TagSupport;
/**
?*?嵌套的内部标签
?*/
public class WritorTag extends TagSupport {
?//item属性 该标签从page中查找item的属性,并输出属性值
?private String item;
?public String getItem() {
??return item;
?}
?public void setItem(String item) {
??this.item = item;
?}
?/**
? * 开始处理标签时的调用方法
? */
?@Override
?public int doStartTag() throws JspException {
??try{
???pageContext.getOut().write((String)pageContext.getAttribute("item"));
??}catch(Exception ex){
???throw new JspException("错误");
??}
??return super.doStartTag();
?}
}
二。标签体的TLD文件配置
1.简单标签
<?xml version="1.0" encoding="GBK"?>
<!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>1.0</tlib-version>
?<!-- 定义JSP版本 -->
?<jsp-version>1.2</jsp-version>
?<!-- 定义标签库名称 -->
?<short-name>mytag</short-name>
?<!-- 定义第一个标签 -->
?<tag>
??<!-- 配置标签名 -->
??<name>helloworld</name>
??<!-- 确定实现标签的标签类 -->
??<tag-class>mytag.HelloWorldTag</tag-class>
??<!-- 确定标签的标签体,标签体为空 -->
??<body-content>empty</body-content>
?</tag>
</taglib>
2.带属性的标签
<?xml version="1.0" encoding="GBK"?>
<!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>1.0</tlib-version>
?<!-- 定义JSP版本 -->
?<jsp-version>1.2</jsp-version>
?<short-name>querytag</short-name>
?<!-- 配置标签 -->
?<tag>
??<!-- 配置标签名称 -->
??<name>query</name>
??<!-- 配置标签实现类 -->
??<tag-class>mytag.QueryTag</tag-class>
??<!-- 指定标签体为空 -->
??<body-content>empty</body-content>
??<!-- 配置属性 -->
??<attribute>
???<name>rows</name>
???<required>true</required>
???<rtexprvalue>true</rtexprvalue>
??</attribute>
?</tag>
</taglib>
3.带标签体的标签
<?xml version="1.0" encoding="GBK"?>
<!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>1.0</tlib-version>
?<jsp-version>1.2</jsp-version>
?<short-name>iterator</short-name>
?<!-- 配置迭代器标签 -->
?<!-- 外部标签 -->
?<tag>
??<!-- 配置标签名 -->
??<name>iterator</name>
??<!-- 配置标签的实现类 -->
??<tag-class>mytag.MyiteratorTag</tag-class>
??<!-- 配置标签体 -->
??<body-content>JSP</body-content>
??<!-- 配置标签属性 -->
??<attribute>
???<name>bean</name>
???<required>true</required>
???<rtexprvalue>true</rtexprvalue>
??</attribute>
??<attribute>
???<name>item</name>
???<required>true</required>
???<rtexprvalue>true</rtexprvalue>
??</attribute>
?</tag>
?<!-- 配置输出标签 -->
?<!-- 内部标签 -->
?<tag>
??<!-- 配置标签名 -->
??<name>write</name>
??<!-- 配置标签的实现类 -->
??<tag-class>mytag.WritorTag</tag-class>
??<!-- 配置标签内容 -->
??<body-content>empty</body-content>
??<!-- 配置标签属性 -->
??<attribute>
???<name>item</name>
???<required>true</required>
???<rtexprvalue>true</rtexprvalue>
??</attribute>
?</tag>
</taglib>
?
三。WEB.XML文件配置
<?xml version="1.0" encoding="UTF-8"?>
<web-app version="2.5" xmlns="http://java.sun.com/xml/ns/javaee"
?xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
?xsi:schemaLocation="http://java.sun.com/xml/ns/javaee
?http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd">
?<jsp-config>
??<taglib>
???<!-- 配置标签的引用地址 JSP页面中引用时使用-->
???<taglib-uri>/helloworld</taglib-uri>
???<!-- 配置标签的TLD文件地址 -->
???<taglib-location>/WEB-INF/helloworld.tld</taglib-location>
??</taglib>
??<taglib>
???<taglib-uri>/query</taglib-uri>
???<taglib-location>/WEB-INF/query.tld</taglib-location>
??</taglib>
??<taglib>
???<taglib-uri>/iterator</taglib-uri>
???<taglib-location>/WEB-INF/iterator.tld</taglib-location>
??</taglib>
?</jsp-config>
?<welcome-file-list>
??<welcome-file>index.jsp</welcome-file>
?</welcome-file-list>
</web-app>
四:JSP调用
<%@ page language="java" contentType="text/html; charset=GBK"
?pageEncoding="GBK" import="java.util.*"%>
<%@ taglib uri="/helloworld" prefix="mytag"%>
<%@ taglib uri="/query" prefix="query"%>
<%@ taglib uri="/iterator" prefix="iter"%>
<!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=ISO-8859-1">
??<title>Insert title here</title>
?</head>
?<body>
??<mytag:helloworld></mytag:helloworld>
??<query:query rows="3" />
??<%
???//创建输出对象
???List<String> a = new ArrayList<String>();
???a.add("a");
???a.add("b");
???a.add("c");
???//将a放入 page 范围内
???pageContext.setAttribute("a", a);
??%>
??<table>
???<iter:iterator bean="a" item="item">
????<tr>
?????<td>
??????<iter:write item="item"/>
?????</td>
????</tr>
???</iter:iterator>
??</table>
?</body>
</html>