Test.jsp
HTML
PUBLIC
"-//W3C//DTD
HTML
4.01
Transitional//EN">
<html>
<head>
<title>My
JSP
'Test.jsp'
starting
page</title>
</head>
<body>
This
is
my
JSP
page.
<br>
Date
:
<%=
new
java.util.Date().toString()
%>
<br>
File
:
<input
value="<%=
request.getServletPath()
%>"
/>
</body>
</html>
为了将这个这个Test.jsp改成自定义标签方法,我们分别使用简单标签和内容标签两种不同的方式实现。
1. 简单标签
由于我们需要输出两个内容(日期和文件名),因此我们为标签创建一个参数。具体代码:
DemoTag.java
com;
import
java.util.Date;
import
javax.servlet.http.*;
import
javax.servlet.jsp.*;
import
javax.servlet.jsp.tagext.*;
public
class
DemoTag
extends
TagSupport
{
public
int
doStartTag()
throws
JspException
{
try
{
HttpServletRequest
request
=
(HttpServletRequest)pageContext.getRequest();
JspWriter
out
=
pageContext.getOut();
if
(parameter.compareToIgnoreCase("filename")
==
0)
out.print(request.getServletPath());
else
out.print(new
Date());
}
catch
(java.io.IOException
e)
{
throw
new
JspTagException(e.getMessage());
}
return
SKIP_BODY;
}
private
String
parameter
=
"date";
public
void
setParameter(String
parameter)
{
this.parameter
=
parameter;
}
public
String
getParameter()
{
return
parameter;
}
}
接下来,我们创建标签文件
MyTagLib.tld。标签文件其实只是一个XML格式的说明文件,内容也很简单。
MyTagLib.tld
version="1.0"
encoding="ISO-8859-1"?>
<taglib>
<tlib-version>1.0</tlib-version>
<jsp-version>1.2</jsp-version>
<tag>
<name>demo</name>
<tag-class>com.mycompany.DemoTag</tag-class>
<body-content>empty</body-content>
<attribute>
<name>parameter</name>
<required>false</required>
<rtexprvalue>true</rtexprvalue>
</attribute>
</tag>
</taglib>
在这个标签文件中,我们将我们创建的标签取名
demo,并声明了类型和参数(parameter)。将该文件保存在
/WEB-INF
下面。
当然,我们还需要将我们自定义的标签添加到
web.xml
中,否则还是无法使用。
web.xml
version="1.0"
encoding="UTF-8"?>
<web-app
xmlns="http://java.sun.com/xml/ns/j2ee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
version="2.4"
xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee
http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd">
<jsp-config>
<taglib>
<taglib-uri>/WEB-INF/MyTagLib</taglib-uri>
<taglib-location>/WEB-INF/MyTagLib.tld</taglib-location>
</taglib>
</jsp-config>
</web-app>
你可能在别处看到过类似的声明,只是没有外面的
jsp-config,但是我们使用的是DTD
2.4,如果不加,Eclipse
会提示出错。
到此为止,我们的自定义标签算是创建完毕。接下来,我们可以开始改写那个JSP文件来分离代码了。
Test.jsp
HTML
PUBLIC
"-//W3C//DTD
HTML
4.01
Transitional//EN">
<%@taglib
uri="/WEB-INF/MyTagLib"
prefix="mytag"%>
<html>
<head>
<title>My
JSP
'Test.jsp'
starting
page</title>
</head>
<body>
This
is
my
JSP
page.
<br>
Date
:
<mytag:demo
parameter="date"
/><br>
File
:
<mytag:demo
parameter="filename"
/>
</body>
</html>
上面这些想必你已经很熟悉,我就不做多说了。
2. 内容标签
创建过程和上面大抵相同,只是程序文件和配置内容有些差异。
DemoTag2.java
com;
import
java.io.IOException;
import
java.util.Date;
import
javax.servlet.http.*;
import
javax.servlet.jsp.*;
import
javax.servlet.jsp.tagext.*;
public
class
DemoTag2
extends
BodyTagSupport
{
public
int
doStartTag()
throws
JspTagException
{
return
_BODY_BUFFERED;
}
public
int
doEndTag()
throws
JspTagException
{
String
body
=
this.getBodyContent().getString();
HttpServletRequest
request
=
(HttpServletRequest)pageContext.getRequest();
body
=
body.replace("$date",
new
Date().toString());
body
=
body.replace("$filename",
request.getServletPath());
try
{
pageContext.getOut().print(body);
}
catch
(IOException
e)
{
throw
new
JspTagException(e.getMessage());
}
return
SKIP_BODY;
}
}
我们将新的标签
DemoTag2
加入到上面的标签文件中。
MyTagLib.tld
version="1.0"
encoding="ISO-8859-1"?>
<taglib>
<tlib-version>1.0</tlib-version>
<jsp-version>1.2</jsp-version>
<tag>
<name>demo</name>
<tag-class>com.DemoTag</tag-class>
<body-content>empty</body-content>
<attribute>
<name>parameter</name>
<required>false</required>
<rtexprvalue>true</rtexprvalue>
</attribute>
</tag>
<tag>
<name>demo2</name>
<tag-class>com.DemoTag2</tag-class>
<body-content>jsp</body-content>
</tag>
</taglib>
web.xml
文件无需修改。
看看同时使用两种标签的Test.jsp效果。
Test.jsp
HTML
PUBLIC
"-//W3C//DTD
HTML
4.01
Transitional//EN">
<%@taglib
uri="/WEB-INF/MyTagLib"
prefix="mytag"%>
<html>
<head>
<title>My
JSP
'Test.jsp'
starting
page</title>
</head>
<body>
This
is
my
JSP
page.
<br>
Date
:
<mytag:demo
parameter="date"
/><br>
File
:
<mytag:demo
parameter="filename"
/>
<hr>
<mytag:demo2>
Date:
$date<br>
File:
$filename
</mytag:demo2>
</body>
</html>
带Body的标签处理器类需要覆盖方法
doStartTag()
返回值:
BodyTag.SKIP_BODY:执行后直接调用doEndTag()方法
BodyTag.EVAL_BODY_INCLUDE:执行后直接调用doAfterBody()方法
BodyTag.EVAL_BODY_BUFFERED:
这里面SKIP_BODY表示不显示标签体里的内容,EVAL_BODY_INCLUDE则是显示,用这两个返回值可以写出类似c:if标签的效果。
doEndTag()
返回值:
BodyTag.EVAL_PAGE:标签下面的内容继续执行
BodyTag.SKIP_PAGE:标签下面的内容不执行
doAfterBody()
返回值:
BodyTag.SKIP_BODY:执行后调用doEngTag()方法
BodyTag.EVAL_BODY_AGAIN:执行后调用doAfterBody()方法