【JavaEE】自定义标签技术



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 : 获取父自定义标签 ---> <c:choose> <c:when></c:when></c:choose>
* @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 "
< description > Mytag Description </ description >
< tlib-version > 1.0 </ tlib-version >
< short-name > MyTag </ short-name > <!-- 标签简写,也即引入时的 prefix -->
< uri > http://www.inetsoft.com/dreamli/mytag </ uri > <!-- 当前 tld 的命名空间, 也即引入时的uri -->
< tag <!-- 声明一个标签 -->
< description > 传统方式实现自定义标签 </ description >
< name > showip </ name <!— 引用的名字,也即引用标签冒号后面的部分 -->
< tag-class > com.dreamli.tag.tradition.MyTag1 </ tag-class >
<!--
empty: 该自定义标签没有标签体
JSP: 该自定义标签有标签体, 可以是Java代码,JSP元素,文本等
scriptless : 该自定义标签有标签体,但是不能有Java代码
tagdependent : 该自定义标签有标签体, 但是是给后台用的,如 sql 标签  -> 现在一般不用
-->
< 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 >
<!--
empty: 该自定义标签没有标签体
JSP: -> 简单标签不支持JSP属性, JSP2.0认为JSP页面不应该嵌入Java代码
scriptless : 该自定义标签有标签体,但是不能有Java代码
tagdependent : 该自定义标签有标签体, 但是是给后台用的,如 sql 标签  -> 现在一般不用
-->
< 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 >
<!--
empty: 该自定义标签没有标签体
JSP: -> 简单标签不支持JSP属性, JSP2.0认为JSP页面不应该嵌入Java代码
scriptless : 该自定义标签有标签体,但是不能有Java代码
tagdependent : 该自定义标签有标签体, 但是是给后台用的,如 sql 标签  -> 现在一般不用
-->
< 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 : 实现 <c:if test="">标签
 * @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 "
< tlib-version > 1.0 </ tlib-version >
< short-name > Exec </ short-name >
< 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 > <!-- 是否支持 el 表达式 -->
< type > boolean </ type > <!-- 属性所对应的 Java 类型 -->
</ 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 >




发布了25 篇原创文章 · 获赞 36 · 访问量 6万+

猜你喜欢

转载自blog.csdn.net/DreamLi1314/article/details/79438232