1)作用:当jsp的内置标签或者jstl不满足我们,这时需要自定义标签
2)三个步骤: 需求: 使用自定义标签输出客户的ip地址
SimpleTag接口的方法:
doTag():执行标签的方法,由web服务器调用
getParent(): 得到父标签。
setJspBody(JspFragment jspBody)传入标签主体内容。由web服务器调用
setJspContext(JspContext pc)传入PageContext。由web服务器调用
setParent(JspTag parent) 传入父标签。由web服务器调用
a) 编写一个java类,实现SimpleTag接口或者继承SimpleTagSupport类。
//标签处理类
public class ShowClientIPTag extends SimpleTagSupport{
@Override
public void doTag() throws JspException, IOException {
//得到PageContext对象
PageContext pc = (PageContext)getJspContext();
ServletRequest request = pc.getRequest();
JspWriter out = pc.getOut();
String ip = request.getRemoteAddr();
out.write(ip);
}
}
b)配置这个标签
在项目下的WEB-INF目录下新建一个tld文件。(itcast.tld)
<taglib 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"
version="2.0">
<tlib-version>1.0</tlib-version>
<short-name>itcast</short-name>
<uri>http://gz.itcast.cn/jsp/tags</uri>
<!-- 一个标签的配置 -->
<tag>
<name>showClientIP</name>
<tag-class>gz.itcast.tag.ShowClientIPTag</tag-class>
<!-- 默认empty:表示空标签,么有主体内容 -->
<body-content>empty</body-content>
</tag>
</taglib>
c)使用标签
导入:<%@taglib uri="http://gz.itcast.cn/jsp/tags" prefix="itcast" %>
使用: <itcast:showClientIP/>
必须练习:自定义标签步骤
3)自定义标签的执行过程(原理)
setJspContext()
setParent()
setJspBody()
doTag()
4)使用自定义标签(用途)
4.1 控制标签体内容是否执行
执行: jspFrament.invoke(null)
不执行: 什么都不干!
? 4.2 控制标签后内容是否执行
执行:什么都不干!
不执行: 抛出一个SkipPageException
? 4.3 控制标签体内容复重执行
for (int i = 1; i <= 3 ; i++) {
getJspBody().invoke(null);
}
4.4 带有属性的标签
a) 标签处理类需要有一个setter方法
public void setCount(int count) { // setter属性名称: count
this.count = count;
}
b)在tld文件声明这个属性
<tag>
<name>demo3</name>
<tag-class>gz.itcast.tag.SimpleDemo3</tag-class>
<body-content>scriptless</body-content>
<!-- 属性配置 -->
<attribute>
<!-- 属性名称-->
<name>count</name>
<!--是否必填 -->
<required>true</required>
<!-- 是否支持EL表达式-->
<rtexprvalue>true</rtexprvalue>
</attribute>
</tag>
? 4.5 控制标签体内容改变
//1)得到主体内容
JspFragment jspBody = getJspBody();
//2)用于临时容器对象放主体内容
StringWriter sw = new StringWriter();
//3)把主体内容放到临时容器中
jspBody.invoke(sw);
//4)从临时容器得到主体内容
String content = sw.toString();
//5)改变
content = content.toUpperCase();
//6)直接输出到浏览器
getJspContext().getOut().write(content);