客户化JSP标签
- 理解客户化JSP标签的作用
- 了解JSP Tag API
- 掌握创建并运用客户化JS标签的步骤
- 掌握在客户化JSP标签中访问application、session、request和page范围内的共享数据的方法
1、客户化JSP标签的作用
- 客户化JSP标签技术是在JSP1.1版本中出现的它支持客户在JSP文件中自定义标签,这样可以使JSP代码更加简洁。
-这些可重用的标签能处理复杂的逻辑运算和事务,或者定义JSP网页的输出内容和格式。
2、创建客户化JSP标签的步骤
-(1)创建标签的处理类
-(2)创建标签库描述文件
-(3)在JSP文件中引入标签库,然后插入标签,例如:<mm:hello /> mm标签前缀,hello标签名字
3、JSP Tag API
Servlet容器编译JSP网页时,如果遇到自定义标签,就会调用这个标签的处理类;标签处理类必须扩展以下两个类之一:
- javax.servlet.jsp.tagext.TagSupport 和 javax.servlet.jsp.tagext.BodyTagSupport
4、TagSupport类的主要方法
- doStartTag :Servlet容器遇到自定义标签的起始标志时调用该方法
- doEndTag :Servlet容器遇到自定义标签的结束标志时调用该方法
- setValue(String k,Object o) :在标签处理类中设置key/value
- getValue(String k) :在标签处理类中根据参数key返回匹配的value
-removeValue(String k) :在标签处理类中删除key/value
-setPageContext(PageContext pc) :设置PageContext对象,该方法由Servlet容器在调用doStartTag或doEndTag方法前调用
- setParent(Tag t) :设置嵌套了当前标签的上层标签的处理类,该方法由Servlet容器在调用doStartTag或doEndTag方法前调用
-getParent() :返回嵌套了当前标签的上层标签的处理类
5、TagSupport类的两个重要属性
- parent :代表嵌套了当前标签的上层标签的处理类
- pageContext :代表web应用中的javax.servlet.jsp.PageContext对象
- JSP容器在调用doStartTag或doEndTag方法前,会先调用setPageContext和setParent方法,设置pageContext和parent
- 在doStartTag或doEndTag方法中可以通过getParent方法获取上层标签的处理类;在TagSupport类中定义了protected类型的pageContext成员变量,因此在标签处理类中可以直接访问pageContext变量。
6、PageContext类
- PageContext类提供了保存和访问web应用的共享数据的方法:
public void setAttribute(String name,Object value,int scope)
public Object getAttribute(String name,int scope)
- 其中,scope参数用来指定属性存在的范围,它的可选值包括:
- PageContext.PAGE_SCOPE
- PageContext.REQUEST_SCOPE
- PageContext.SESSION_SCOPE
- PageContext.APPLICATION_SCOPE
例如:PageContext.setAttribute("username","zhangs",PageContext.SESSION_SCOPE);
7、doStartTag()方法
- 当Servlet容器遇到自定义标签的起始标志,就会调用doStartTag()方法。
-doStartTag()方法返回一个整数值,用来决定程序的后续流程。他有两个可选值:
- Tag.SKIP_BODY :表示标签之间的内容被忽略。
- Tag.EVAL_BODY_INCLUDE :表示标签之间的内容被正常执行
8、doEndTag()方法
- 当Servlet容器遇到自定义标签的结束标志,就会调用doEndTag()方法。
- doEndTag()方法也返回一个整数值,用来决定程序后续流程。他有两个可选值:
- Tag.SKIP_PAGE :表示立刻停止执行JSP网页,网页上未处理的静态内容和JSP程序均被忽略,任何已有的输出内容立刻返回到客户浏览器上
- Tag.EVAL_PAGE :表示按正常的流程继续执行JSP网页。
9、用户自定义的标签属性
- 在标签中还能包含自定义的属性,如<prefix:mytag username="zhangsan"> </prefix:mytag>
- 在标签处理类中应该将这个属性作为成员变量,并且分别提供设置和读取属性的方法,
10、创建自己的自定义标签
- 创建标签处理类:MyTag类
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)
{
e.printStackTrace();
}
return EVAL_BODY_INCLUDE;
}
@Override
public int doEndTag() throws JspException
{
try
{
this.pageContext.getOut().println("welcome");
}
catch(IOException e)
{
e.printStackTrace();
}
return EVAL_PAGE;
}
}
- 标签库描述文件,后缀名为:tld,文件存放在固定的位置:WebRoot下的WEB-INF,这里起名myTag.tld
<?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.cdtax.tag.MyTag</tag-class>
<body-content>empty</body-content>
</tag>
</taglib>
标签库描述文件中的uri就对应jsp中应用标签库语句 <%@ taglib uri="/myTag" prefix="mypre" %>里的uri,相当于是这个标签库的标识。
- 在jsp中引用标签库并使用标签,引用标签库使用<%@ taglib uri="/myTag" prefix="mypre" %>
<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>
<%@ taglib uri="/myTag" prefix="mypre" %>
<html>
<head>
<title>My JSP 'tag1.jsp' starting page</title>
</head>
<body>
<p><font color="blue"><mypre:firstTag /></font></p>
</body>
</html>
11、创建一个标签,根据标签的属性值,查找一个属性文件,根据属性文件替换页面上的内容
(1)属性文件:message.properties,这个文件的存放位置也在WEB-INF下
title=hello world
body=welcome
(2)创建一个Servlet,在容器启动时自动加载message.properties文件到ServletContext中:
import java.io.InputStream;
import java.util.Properties;
import javax.servlet.ServletConfig;
import javax.servlet.ServletContext;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
public class InitServlet2 extends HttpServlet
{
@Override
public void init(ServletConfig config) throws ServletException
{
Properties ps = new Properties();
try
{
ServletContext context = config.getServletContext();
InputStream is = context.getResourceAsStream("/WEB-INF/message.properties");
ps.load(is);
is.close();
context.setAttribute("ps", ps);
}
catch(Exception e)
{
e.printStackTrace();
}
}
}
web.xml中部署Servlet,因为不需要访问这个servlet,所以只需要配置<servlet>,不需要配置<servlet-mapping>:
<servlet>
<servlet-name>InitServlet2</servlet-name>
<servlet-class>com.cdtax.servlet.InitServlet2</servlet-class>
<load-on-startup>20</load-on-startup>
</servlet>
(3)创建标签处理类:
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;
public String getKey()
{
return key;
}
public void setKey(String key)
{
this.key = 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;
}
}
注意,因为我们的标签带有属性,所以根据上面第9项,需要将这个属性作为处理类的成员变量,并且生成get和set方法,就是上例中的key变量。
然后配置标签库描述文件:
<?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>/myTag11</uri>
<tag>
<name>firstTag</name>
<tag-class>com.cdtax.tag.MyTag</tag-class>
<body-content>empty</body-content>
</tag>
<tag>
<name>message</name>
<tag-class>com.cdtax.tag.MyTag2</tag-class>
<body-content>empty</body-content>
<attribute>
<name>key</name>
<required>true</required>
</attribute>
</tag>
</taglib>
对于message标签,有一个属性,名字为key
(4)创建一个jsp使用标签:
<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>
<%@ taglib uri="/myTag" prefix ="mypre" %>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<title>My JSP 'tag2.jsp' starting page</title>
</head>
<body>
<mypre:message key="title" /><br/>
<mypre:message key="body" />
</body>
</html>
对于<mypre:message key="title" />标签,当servlet容器遇到他时(标签起始标志),就会从标签库描述文件中找到对应的标签处理类,然后调用doStartTag()方法,如果没有这个方法,向后遇到标签结束标志,调用doEndTag()方法,如果标签带有属性,调用方法前,会调用相应属性的set方法,将属性值设置到成员变量中,方法就能获得属性值。InitServlet2这个servlet在servlet容器启动时自动加载,同时执行init()方法,生成一个Properties对象,对象内容为属性文件message.properties的内容,然后设置到ServletContext中,这个其他servlet就可以通过ServletContext获得这个文件内容,从而根据key值进行替换。