1 传统自定义标签技术
1)写一个类实现Tag接口
package
com.dreamli.tag.tradition;
import
java.io.IOException;
import
javax.servlet.jsp.JspException;
import
javax.servlet.jsp.PageContext;
import
javax.servlet.jsp.tagext.Tag;
/**
*
*
@Description
: 以传统方式开发自定义标签
*
@Warning
:
*
@Author
:
dreamli
*
@Package
: Day
-
06
-
JSP
-
Tag
-
com.dreamli.tag.tradition.MyTag1.java
*
@Date
: 2018年3月4日 下午12:09:45
*
@Version
: 1.0.0
*/
public
class
MyTag1
implements
Tag {
private
PageContext
pageContext
;
/**
*
@When
: 第一次遇到自定义标签时创建传处理类对象, 并一直驻留在内存中, 知道服务器关闭
*
@Author
:
dreamli
*
@Date
: 2018年3月4日 下午1:10:47
*/
public
MyTag1() {
System.
out
.println(
"======================== constrtucter =================================="
);
}
/**
*
@Description
: 4 遇到结束标签时调用
*
@Warning
:
*
@Author
:
dreamli
*
@Date
: 2018年3月4日 下午12:06:10
*
@Version
: 1.0.0
*/
@Override
public
int
doEndTag()
throws
JspException {
return
EVAL_PAGE
;
// process content after tag
// skip content after tag ---> 标签后的
html
元素等都不会被解析(查看页面源文件)
// 这将导致每次刷新页面都会创建新的传处理类对象为标签服务, 服务结束后立刻调用release方法销毁处理类对象
//
return SKIP_PAGE;
}
/**
*
@Description
: 3 遇到开始标签时调用
*
@Warning
:
*
@Author
:
dreamli
*
@Date
: 2018年3月4日 下午12:06:10
*
@Version
: 1.0.0
*/
@Override
public
int
doStartTag()
throws
JspException {
// 获取访问者 IP
String
ip
=
pageContext
.getRequest().getRemoteAddr();
try
{
// 将 IP 写到JSP页面上
pageContext
.getOut().write(
ip
);
}
catch
(IOException
e
) {
e
.printStackTrace();
}
// return EVAL_BODY_INCLUDE;//继续解析 if the tag wants to process body
return
SKIP_BODY
;
// if it does not want to process body.
}
/**
*
@Description
: 获取父自定义标签
--->
如
*
@Warning
:
*
@Author
:
dreamli
*
@Date
: 2018年3月4日 下午12:06:10
*
@Version
: 1.0.0
*/
@Override
public
Tag getParent() {
return
null
;
}
/**
*
@Description
: 5 当应用程序关闭时会调用该方法进行一些善后的工作,然后销毁处理类对象
*
@Warning
:
*
@Author
:
dreamli
*
@Date
: 2018年3月4日 下午12:06:10
*
@Version
: 1.0.0
*/
@Override
public
void
release() {
System.
out
.println(
"=====release====="
);
}
/**
*
@Description
: 1 当JSP解析到自定义标签时会首先调用该方法设置 PageContext 对象
*
@Warning
:
*
@Author
:
dreamli
*
@Date
: 2018年3月4日 下午12:06:10
*
@Version
: 1.0.0
*/
@Override
public
void
setPageContext(PageContext
pageContext
) {
this
.
pageContext
=
pageContext
;
}
/**
*
@Description
: 2 如果该自定义标签有父自定义标签时会调用该方法,将父标签传过来
*
@Warning
:
*
@Author
:
dreamli
*
@Date
: 2018年3月4日 下午12:53:35
*
@Version
: 1.0.0
*/
@Override
public
void
setParent(Tag
parentTag
) {
}
}
2)写一个tld文件对标签进行描述
xml
version
=
"1.0"
encoding
=
"UTF-8"
?>
<
taglib
version
=
"2.0"
xmlns
=
" http://java.sun.com/xml/ns/j2ee
"
xmlns:xsi
=
" http://www.w3.org/2001/XMLSchema-instance
"
xsi:schemaLocation
=
" http://java.sun.com/xml/ns/j2ee
http://java.sun.com/xml/ns/j2ee/web-jsptaglibrary_2_0.xsd
"
>
<
description
>
Mytag
Description
description
>
<
tlib-version
>
1.0
tlib-version
>
<
short-name
>
MyTag
short-name
>
<
uri
> http://www.inetsoft.com/dreamli/mytag
uri
>
<
tag
>
<
description
>
传统方式实现自定义标签
description
>
<
name
>
showip
name
>
<
tag-class
>
com.dreamli.tag.tradition.MyTag1
tag-class
>
<
body-content
>
empty
body-content
>
tag
>
taglib
>
3)在JSP页面进行引用
<%@
page
language
=
"java"
contentType
=
"text/html; charset=UTF-8"
pageEncoding
=
"UTF-8"
%>
<%@
taglib
uri
=
" http://www.inetsoft.com/dreamli/mytag
"
prefix
=
"MyTag"
%>
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
>
Java代码:
<
br
>
标签之前的内容
<%
String ip = request.getRemoteAddr();
out.write(ip);
%>
标签之后的内容
<
hr
>
传统自定义标签:
<
br
>
标签之前的内容
<
MyTag:showip
/>
标签之后的内容
<
hr
>
body
>
html
>
2 使用简单标签自定义标签
1)实现SimpleTag接口的方式
a. 写一个类继承SimpleTag接口
package
com.dreamli.tag.simple;
import
java.io.IOException;
import
javax.servlet.jsp.JspContext;
import
javax.servlet.jsp.JspException;
import
javax.servlet.jsp.PageContext;
import
javax.servlet.jsp.tagext.JspFragment;
import
javax.servlet.jsp.tagext.JspTag;
import
javax.servlet.jsp.tagext.SimpleTag;
/**
*
@Description
: 简单标签实现自定义标签
--
显示访问者IP地址
*
@Warning
:
*
@Author
:
dreamli
*
@Package
: Day
-
06
-
JSP
-
Tag
-
com.dreamli.tag.simple.MyTag1.java
*
@Date
: 2018年3月4日 下午2:15:28
*
@Version
: 1.0.0
*/
public
class
MyTag1
implements
SimpleTag {
private
PageContext
pageContext
;
/**
* 4. 处理标签
*/
@Override
public
void
doTag()
throws
JspException, IOException {
System.
out
.println(
"=========dotag======="
);
this
.
pageContext
.getOut().write(
pageContext
.getRequest().getRemoteAddr());
}
/**
* 获取父标签
*/
@Override
public
JspTag getParent() {
return
null
;
}
/**
* 3. 设置 JspFragment 对象, 用来在处理类程序返回前零次或多次调用片段,或传给其他标签
*
@param
jspFragment: 封装了标签体的JSP片段
*/
@Override
public
void
setJspBody(JspFragment
jspFragment
) {
System.
out
.println(
"=========setJspBody======="
);
// 先显示标签体,再显示输出
try
{
//调用 JspFragment 的 invoke 方法显示标签体,该方法接受一个Writer字符流,传入null相当于传入pageContext.getOut()
jspFragment
.invoke(
null
);
}
catch
(JspException | IOException
e
) {
e
.printStackTrace();
}
}
/**
* 1. 设置 PageContext 对象
*/
@Override
public
void
setJspContext(JspContext
jspContext
) {
this
.
pageContext
= (PageContext)
jspContext
;
}
/**
* 2. 如果当前自定义标签存在父自定义标签, 调用该方法将父自定义标签传过来
*/
@Override
public
void
setParent(JspTag
arg0
) {
}
}
b. 写tld 文件
<
tag
>
<
description
>
简单标签实现自定义标签>>>>实现SimpleTag接口
description
>
<
name
>
sshowip
name
>
<
tag-class
>
com.dreamli.tag.simple.MyTag1
tag-class
>
<
body-content
>
scriptless
body-content
>
tag
>
c. 引用
简单自定义标签:
<
br
>
标签之前的内容
<
MyTag:sshowip
>
xxx
MyTag:sshowip
>
标签之后的内容
<
hr
>
2)继承SimpleTagSupport类
a. 写一个类继承 SimpleTagSupport类, 重写 doTag 方法
package
com.dreamli.tag.simple;
import
java.io.IOException;
import
javax.servlet.jsp.JspException;
import
javax.servlet.jsp.PageContext;
import
javax.servlet.jsp.tagext.SimpleTagSupport;
/**
*
@Description
: 简单自定义标签
--
通过继承 SimpleTagSupport
*
@Warning
:
*
@Author
:
dreamli
*
@Package
: Day
-
06
-
JSP
-
Tag
-
com.dreamli.tag.simple.MyTag2.java
*
@Date
: 2018年3月4日 下午3:52:02
*
@Version
: 1.0.0
*/
public
class
MyTag2
extends
SimpleTagSupport {
@Override
public
void
doTag()
throws
JspException, IOException {
super
.doTag();
PageContext
pageContext
= (PageContext)
this
.getJspContext();
String
ip
=
pageContext
.getRequest().getRemoteAddr();
pageContext
.getOut().write(
ip
);
getJspBody().invoke(
null
);
//先显示输出,再显示标签体
}
}
b. 写 tld 文件描述标签
<
tag
>
<
description
>
简单标签实现自定义标签>>>>继承SimpleTagSupport
description
>
<
name
>
sshowip2
name
>
<
tag-class
>
com.dreamli.tag.simple.MyTag2
tag-class
>
<
body-content
>
scriptless
body-content
>
tag
>
c. 引用
简单自定义标签(继承):
<
br
>
标签之前的内容
<
MyTag:sshowip2
>
xxxyyy
MyTag:sshowip2
>
标签之后的内容
<
hr
>
3 开发带有属性的标签
1)写一个处理类, 并为属性声明对应的成员变量, 且
必须提供setter方法
package
com.dreamli.tag.simple;
import
java.io.IOException;
import
javax.servlet.jsp.JspException;
import
javax.servlet.jsp.tagext.SimpleTagSupport;
/**
*
@Description
: 实现 标签
*
@Warning
: 属性对应处理类的成员变量, 且处理类必须提供setter方法
*
@Author
:
dreamli
*
@Package
: Day
-
06
-
JSP
-
Tag
-
com.dreamli.tag.simple.ExecIf.java
*
@Date
: 2018年3月4日 下午5:24:59
*
@Version
: 1.0.0
*/
public
class
ExecIf
extends
SimpleTagSupport {
private
boolean
test
;
public
void
setTest(
boolean
test
) {
this
.
test
=
test
;
}
@Override
public
void
doTag()
throws
JspException, IOException {
if
(
test
) {
getJspBody().invoke(
null
);
}
}
}
2)书写 tld 文件
xml
version
=
"1.0"
encoding
=
"UTF-8"
?>
<
taglib
version
=
"2.0"
xmlns
=
" http://java.sun.com/xml/ns/j2ee
"
xmlns:xsi
=
" http://www.w3.org/2001/XMLSchema-instance
"
xsi:schemaLocation
=
" http://java.sun.com/xml/ns/j2ee
http://java.sun.com/xml/ns/j2ee/web-jsptaglibrary_2_0.xsd
"
>
<
tlib-version
>
1.0
tlib-version
>
<
short-name
>
Exec
short-name
>
<
uri
> http://www.inetsoft.com/dreamli/exec
uri
>
<
tag
>
<
name
>
if
name
>
<
tag-class
>
com.dreamli.tag.simple.ExecIf
tag-class
>
<
body-content
>
scriptless
body-content
>
<
attribute
>
<
name
>
test
name
>
<
required
>
true
required
>
<
rtexprvalue
>
true
rtexprvalue
>
<
type
>
boolean
type
>
attribute
>
tag
>
taglib
>
3)在 JSP 页面引用
<%@
page
language
=
"java"
contentType
=
"text/html; charset=UTF-8"
pageEncoding
=
"UTF-8"
%>
<%@
taglib
uri
=
" http://www.inetsoft.com/dreamli/exec
"
prefix
=
"Exec"
%>
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
>
<
Exec:if
test
=
"
${3 > 2}
"
>
you are right!
Exec:if
>
<
Exec:if
test
=
"
${3 <= 2 }
"
>
This is wrong!
Exec:if
>
body
>
html
>