自定义标签(客户化jsp标签)
客户化jsp标签技术是在jsp1.1版本中才出现的,他支持用户在jsp文件中自定义标签,这样可以使jsp代码更加简单,这些可重用的标签能够处理复杂的逻辑运算和事物或定义jsp网页的输出内容和格式。
创建客户化jsp标签的步骤:
(1)创建标签的处理类
(2)创建标签的描述文件
(3)在jsp文件中引入标签库,然后插入标签。例如:<mm:hello />其中 mm叫做标签前缀,hello叫做标签名
jsp tag API
Servlet容器编译jsp网页时,如果遇到自定义标签,就会调用这个标签的处理类。
标签处理类必须扩展以下两个类之一:
--javax.servlet.jsp.tagext.TagSupport
--javax.servlet.jsp.tagext.BodyTagSupport
TagSupport方法,其中 里面有两个重要的类,定义标签处理类的时候,都会重写这两个方法:doStartTag() 和 doEndTag()方法。
(1)doStartTag:servlet容器遇到自定义标签的起始标志时。调用该标签
(2)doEndTag:servlet容器遇到自定义标签的结束标志时,调用该标签
(3)setValue(String k, Object o):在标签处理类中设置key/value时,调用该标签
(4)getValue(String k ):在标签处理类中根据参数key返回匹配的value
(5)removeValue(String k):在标签处理类中删除key/value
(6)setPageContext(PageContext pc):设置PageContext对象,该方法由servlet容器在调用doStartTag或doEndTag方法前调用
(7)setParent(Tag t):设置嵌套了当前标签的上一层标签的处理类,该方法由servlet容器在调用doStartTag或doEndTag()方法前调用
(8)setParent():返回嵌套了当前标签的上一层标签的处理类
TagSupport两个重要属性
(1)parent:代表嵌套了当前标签的上层标签的处理类
(2)pageContext:代表web应用中javax.servlet.jsp.pageContext对象
jsp容器在调用doStartTag或doEndTag方法前,会先调用setPageContext和setParent方法,设置pageContext和parent.在doStartTag或doEndTag方法中,可以通过getParent方法获取上层标签的处理类:在TagSupport类中定义了protected类型的pageContext成员变量,因此在标签处理类中可直接访问pageContext变量
pageContext类提供了保存和访问web应用的共享数据的方法:
public void setAttribute(String name, Object value,int scope)
public Object getAttribute(String name,int scope)
其中,scope参数用来指定属性存在范围,他的可选值包括:
--pageContext.PAGE_SCOPE
--pageContext.SESSION_SCOPE
--pageContext.REQUEST_SCOPE
--pageContext.APPLICATION_SCOPE
例如:pageContext.setAttribute("username","zhangsan",pageContext.SESSION_SCOPE);
public int doStartTag() throws jspException
public int doEndTag() throws jspException
doStartTag()方法返回一个整数值,用来决定流程的后续流程,他有iangge可选值:
--Tag.SKIP_BODY 表示标签之间的内同可忽略
--Tag.SKIP_BODY_INCLUDE 表示标签之间的内容正常执行
doEndTag()方法也返回一个整数值,用来决定流程后续流程。他存在两个可选值
--tag.SKIP_PAGE 立刻停止执行jsp网页,网页未处理的静态内容和jsp程序军备忽略,任何已有的输出内容立刻返回到客户端浏览器上。
--tag.EVAL_PAGE: 正常执行流程
在标签中还可以包含自定义的属性:
<prefix:mytag username="zhangsan" >....</prefix:mytag> 在标签处理类中应该讲这个属性作为成员变量并且分别提供设置和读取属性的get和set方法,假定以上username为string类型,可以定义如下方法
private String username;
public void set...
public String get...
举例:
1.创建标签的处理类
package com.tag; import java.io.IOException; import javax.servlet.jsp.JspException; import javax.servlet.jsp.tagext.TagSupport; public class MyTag extends TagSupport { @Override public int doStartTag() throws JspException { try { //向页面上输出字符串 this.pageContext.getOut().println("hello world"); } catch (IOException e) { // TODO 自动生成的 catch 块 e.printStackTrace(); } return EVAL_BODY_INCLUDE; } @Override public int doEndTag() throws JspException { try { this.pageContext.getOut().println("welcome"); } catch (IOException e) { // TODO 自动生成的 catch 块 e.printStackTrace(); } return EVAL_PAGE; } }
2.创建标签的描述文件(放在WEB-INF目录下)
<?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>1.0</tlib-version> <jsp-version>1.1</jsp-version> <short-name>myTag</short-name> <uri>/myTag</uri> <tag> <name>firstTag</name> <tag-class>com.tag.MyTag</tag-class> <body-content>empty</body-content> </tag> <tag> <name>message</name> <tag-class>com.tag.MyTag2</tag-class> <body-content>empty</body-content> <attribute> <name>key</name> <required>true</required> </attribute> </tag> </taglib>
3.mytag.jsp文件
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%> <%@ taglib uri="/myTag" prefix="hello"%> <!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> <p> <font color="blue"> <hello:firstTag ></hello:firstTag> </font></p> </body> </html>
4.标签中含有属性值
package com.tag; import java.util.Properties; import javax.servlet.jsp.JspException; import javax.servlet.jsp.PageContext; import javax.servlet.jsp.tagext.TagSupport; public class MyTag2 extends TagSupport { private String key; @Override public int doEndTag() throws JspException { try { Properties ps = (Properties)this.pageContext.getAttribute("ps", PageContext.APPLICATION_SCOPE); String message = ps.getProperty(key); this.pageContext.getOut().println(message); }catch(Exception e ) { e.printStackTrace(); } return EVAL_PAGE; } public String getKey() { return key; } public void setKey(String key) { this.key = key; } }
5.servlet类
package com.tag.servlet; import java.io.InputStream; import java.util.Properties; import javax.servlet.ServletContext; import javax.servlet.http.HttpServlet; public class InitTag extends HttpServlet { public void init(javax.servlet.ServletConfig config) throws javax.servlet.ServletException { Properties ps= new Properties(); try{ ServletContext context = config.getServletContext(); InputStream is = context.getResourceAsStream("/WEB-INF/message.properties"); ps.load(is); is.close(); //将properties对象放在application范围内 context.setAttribute("ps", ps); }catch(Exception e ) { e.printStackTrace(); } } }
6.已经配置好了tld文件
7.web.xml文件中
<servlet> <description></description> <display-name>InitTag</display-name> <servlet-name>InitTag</servlet-name> <servlet-class>com.tag.servlet.InitTag</servlet-class> <load-on-startup>10</load-on-startup> </servlet>
8.jsp文件中
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%> <%@ taglib uri="/myTag" prefix="hello" %> <!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> <hello:message key="title"/><br> <hello:message key="body"/> </body> </html>