来看看javaweb的自定义标签
1.为什么需要自定义标签?
jsp的简单标签其实就是jsp的自定义标签,主要作用就是移除jsp页面中的java代码,使得jsp页面只有标签和EL表达式,而没有java代码。利用自定义标签,可以使软件开发人员和页面设计人员合理分工,页面设计人员可以把精力集中在使用标签(html,xml或jsp)创建网站上,而软件开发人员则可以将精力集中在实现底层功能上面。
2.什么是自定义标签?
用户定义的一种自定义的jsp标记。当一个含有自定义标签的jsp页面被jsp引擎编译成servlet时,tag标签被转化成了对一个称为标签处理类的对象的操作。于是,当jsp页面被jsp引擎转化为servlet后实际上tag标签被转化成了对tag处理类的操作。
3.标签库API
标签库API定义在javax.servlet.jsp.tagext包中,
左边的三个接口Tag接口,IterationTag接口和BodyTag接口以及两个实现类TagSupport类和BodyTagSupport类为传统标签(导入传统标签,右击项目,Build Path->Add Libraries->MyEclipse Library->next->JSTL...Library),右边的一个接口SimpleTag接口和一个实现类SimpleTagSupport类为自定义标签。即所有标签处理器类实现了Tag接口的标签为传统标签,实现SimpleTag接口的标签为简单标签。简单标签可以实现传统标签的一切功能,而且开发起来更容易。开发自定义标签核心就是要编写处理器类,需要继承的就是SimpleTagSupport类。SimpleTagSupport类实现了SimpleTag接口。
标签的形式:
- 空标签:<hello/>
- 带有属性的空标签:<max num="3" num2="5"/>
- 带有内容的标签:<greeting>hello</greeting>
- 带有内容和属性的标签:<greeting name="Tom">hello</greeting>
4.自定义标签的开发与应用步骤
- 编写完成标签功能的java类(标签处理器)
- 编写标签库描述(tld)文件,在tld文件中对自定义标签进行描述
- 在jsp页面中导入和使用自定义标签
示例如下:
编写完成标签功能的java类:
HelloSimpleTag.java
package com.javaweb.tag; import java.io.IOException; import javax.servlet.jsp.JspContext; import javax.servlet.jsp.JspException; import javax.servlet.jsp.tagext.JspFragment; import javax.servlet.jsp.tagext.JspTag; import javax.servlet.jsp.tagext.SimpleTag; public class HelloSimpleTag implements SimpleTag { @Override public void doTag() throws JspException, IOException { // TODO Auto-generated method stub System.out.println("doTag"); } @Override public JspTag getParent() { // TODO Auto-generated method stub System.out.println("getParent"); return null; } @Override public void setJspBody(JspFragment arg0) { // TODO Auto-generated method stub System.out.println("setJspBody"); } @Override public void setJspContext(JspContext arg0) { // TODO Auto-generated method stub System.out.println("setJspContext"); } @Override public void setParent(JspTag arg0) { // TODO Auto-generated method stub System.out.println("setParent"); } }
编写标签库描述(tld)文件,在tld文件中对自定义标签进行描述:
helloTag.tld
<?xml version="1.0" encoding="UTF-8"?> <taglib 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-jsptaglibrary_2_1.xsd" version="2.1"> <!-- 描述TLD文件 --> <description>MyTag 1.1 core library</description> <display-name>MyTag core</display-name> <tlib-version>1.1</tlib-version> <!-- 建议在jsp页面上使用的标签的前缀 --> <short-name>koala</short-name> <!-- 作为tld文件的id,用来唯一标识当前的TLD文件,多个TLD文件的URI不能重复,通过jsp页面的taglib标签的uri属性来引用 --> <uri>http://www.com.koala/jsp/jstl/core</uri> <!-- 描述自定义的HelloSimpleTag标签 --> <tag> <!-- 标签的名字 --> <name>hello</name> <!-- 标签所在的全类名(.java文件所在的全类名) --> <tag-class>com.javaweb.tag.HelloSimpleTag</tag-class> <!-- 标签体的类型 --> <body-content>empty</body-content> </tag> </taglib>
在jsp页面中导入和使用自定义标签:
simpletag.jsp
<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%> <!-- 导入标签库(描述文件) --> <%@taglib uri="http://www.com.koala/jsp/jstl/core" prefix="koala" %> <% String path = request.getContextPath(); String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/"; %> <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"> <html> <head> <base href="<%=basePath%>"> <title>My JSP 'simpletag.jsp' starting page</title> <meta http-equiv="pragma" content="no-cache"> <meta http-equiv="cache-control" content="no-cache"> <meta http-equiv="expires" content="0"> <meta http-equiv="keywords" content="keyword1,keyword2,keyword3"> <meta http-equiv="description" content="This is my page"> <!-- <link rel="stylesheet" type="text/css" href="styles.css"> --> </head> <body> <koala:hello/> </body> </html>
在jsp中导入和使用自定义标签时需注意:
<%@taglib uri="http://www.com.koala/jsp/jstl/core" prefix="koala" %>对应于.tld文件中的<uri>http://www.com.koala/jsp/jstl/core</uri>和<short-name>koala</short-name>,<koala:hello/>对应于.tld文件中的<short-name>koala</short-name>和<name>hello</name>。
在上面的例子中,
①创建一个标签处理类,实现了SimpleTag接口
public class HelloSimpleTag implements SimpleTag {}
②在WEB-INF文件夹下新建一个.tld为扩展名的xml文件,并考入固定的部分,并对description,display-name,tlib-version,short-name,uri做出修改
<description>MyTag 1.1 core library</description> <display-name>MyTag core</display-name> <tlib-version>1.1</tlib-version> <!-- 建议在jsp页面上使用的标签的前缀 --> <short-name>koala</short-name> <!-- 作为tld文件的id,用来唯一标识当前的TLD文件,多个TLD文件的URI不能重复,通过jsp页面的taglib标签的uri属性来引用 --> <uri>http://www.com.koala/jsp/jstl/core</uri>
③在tld文件中描述自定义标签
<tag> <!-- 标签的名字 --> <name>hello</name> <!-- 标签所在的全类名(.java文件所在的全类名) --> <tag-class>com.javaweb.tag.HelloSimpleTag</tag-class> <!-- 标签体的类型 --> <body-content>empty</body-content> </tag>
⑤在jsp页面上使用自定义的标签
>使用taglib指令导入标签库描述文件:
<%@taglib uri="http://www.com.koala/jsp/jstl/core" prefix="koala" %>
>使用自定义的标签
<body> <koala:hello/>
</body>
5.带属性的自定义标签
5.1 先在标签处理器中定义setter方法,建议把所有的属性类型都设置为String类型。
package com.javaweb.tag; import java.io.IOException; import javax.servlet.jsp.JspContext; import javax.servlet.jsp.JspException; import javax.servlet.jsp.JspWriter; import javax.servlet.jsp.PageContext; import javax.servlet.jsp.tagext.JspFragment; import javax.servlet.jsp.tagext.JspTag; import javax.servlet.jsp.tagext.SimpleTag; public class HelloSimpleTag implements SimpleTag { private String value; private String count; public void setCount(String count) { this.count = count; } public void setValue(String value) { this.value = value; } //标签体的逻辑实际应该编写到此方法中 @Override public void doTag() throws JspException, IOException { JspWriter out=pageContext.getOut(); int c=0; c=Integer.parseInt(count); for(int i=0;i<c;i++){ out.print((i+1)+":"+value); out.print("<br>"); } } @Override public JspTag getParent() { System.out.println("getParent"); return null; } @Override public void setJspBody(JspFragment arg0) { System.out.println("setJspBody"); } private PageContext pageContext; //JSP引擎调用,把代表jsp页面的PageContext对象传入 @Override public void setJspContext(JspContext arg0) { System.out.println(arg0 instanceof PageContext); this.pageContext=(PageContext)arg0; } @Override public void setParent(JspTag arg0) { System.out.println("setParent"); } }
5.2 在tld文件中描述属性
<attribute> <!-- 属性名,需和标签处理器类的setter方法定义的属性相同 --> <name>value</name> <!-- 该属性是否被必须 --> <required>true</required> <!-- rtexprvalue:runtime expression value 当前属性是否可以接受运行时表达式的动态值 --> <rtexprvalue>true</rtexprvalue> </attribute> <attribute> <name>count</name> <required>true</required> <rtexprvalue>true</rtexprvalue> </attribute>
5.3 在jsp页面中使用属性
属性名同tld文件中定义的名字(<name>value</name>)。
<koala:hello value="koala" count="8"/>
搜索微信公众号“程序员考拉”欢迎关注!