Jsp自定义标签

来源:互联网 发布:波士顿矩阵图怎么制作 编辑:程序博客网 时间:2024/06/06 19:05

JSP自定义标签

自定义标签是用户定义的JSP语言元素。当JSP页面包含一个自定义标签时将被转化为servlet,标签转化为对被 称为tag handler的对象的操作,即当servlet执行时Web container调用那些操作。JSP标签扩展可以让你创建新的标签并且可以直接插入到一个JSP页面。
JSP1.0规范中可以继承TagSupport类并重写的doStartTag()方法来开发自定义标签;JSP2.0规范也可以继承SimpleTagSupport类并重写的doTag()方法来开发自定义标签。建议使用继承SimpleTagSupport的方式开发自定义标签。

tld文件中attribute属性

属性 描述 name 定义属性的名称。每个标签的是属性名称必须是唯一的。 required 指定属性是否是必须的或者可选的,如果设置为false为可选。 rtexprvalue 声明在运行表达式时,标签属性是否有效。 type 定义该属性的Java类类型 。默认指定为 String description 描述信息 fragment 如果声明了该属性,属性值将被视为一个 JspFragment。

继承TagSupport的方式

开发步骤:
1、继承TagSupport,重写doStartTag方法。

/** * 自定义日期标签 */public class DateTag extends TagSupport {    private static final long serialVersionUID = 1L;    @Override    public int doStartTag() throws JspException {        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");        String dateFormat = sdf.format(new Date());        try {            pageContext.getOut().write(dateFormat);        } catch (IOException e) {            e.printStackTrace();        }        return super.doStartTag();    }}

2、编写tld文件

<?xml version="1.0" encoding="UTF-8" ?><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>TagLibrary</short-name>    <uri>/aric-Tag</uri>    <tag>        <name>date</name>        <tag-class>cn.aric.tag.DateTag</tag-class>        <!-- 空的标签体 -->        <body-content>empty</body-content>    </tag> </taglib>

3、编写jsp文件,在jsp页面中使用自定义标签

<%@ page language="java" contentType="text/html; charset=UTF-8"    pageEncoding="UTF-8"%><!-- 引入自定义标签库 --><%@ taglib uri="/aric-Tag" prefix="a" %><!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>登陆页面</title></head><body>    欢迎登陆系统!当前时间:<a:date/></body></html>

标签中静态常量:
EVAL_BODY_INCLUDE:告诉服务器正文的内容,并把这些内容送入输出流
SKIP_BODY:告诉服务器不要处理正文内容
EVAL_PAGE:让服务器继续执行页面
SKIP_PAGE:让服务器不要处理剩余的页面
EVAL_BODY_AGAIN:让服务器继续处理正文内容,只有doAfterBody方法可以返回
EVAL_BODY_BUFFERED:BodyTag接口的字段,在doStartTag()返回
EVAL_BODY_INCLUDE、SKIP_BODY一般由doStartTag()返回,而EVAL_PAPGE、SKIP_PAGE由doEndTag()返回。

BodyTagSupport

BodyTagSupport类几个方法:doStartTag(), setBodyContent(), doInitBody(), doAfterBody(), doEndTag();他们执行顺序:
doStartTag()→doInitBody()→setBodyContent()→doAfterBody()→doEndTag()

doStartTag()方法可返回EVAL_BODY_INCLUDESKIP_BODY,如果返回EVAL_BODY_INCLUDE则继续执行;如果返回SKIP_BODY则接下来的doInitBody(),setBodyContent(), doAfterBody()三个方法不会被执行,而直接执行doEndTag()方法。

setBodyContent()方法用于设置标签体内容,如果在此之前要作一些初始化工作,则在doInitBody()方法中完成。标签体内容执行完后,会调用doAfterBody()方法,此方法可返回EVAL_BODY_TAG, SKIP_BODY, EVAL_PAGESKIP_PAGE
如果返回EVAL_BODY_TAG则会再次设置标签体内容,直到返回SKIP_BODY;如果返回EVAL_PAGE则标签体执行完后会继续执行JSP页面中接下来的部分;如果返回SKIP_PAGE,则JSP页面的后续内容将不再执行。

1、Java代码:

/** * 继承BodyTagSupport,实现修改页面内容 */public class BodyTag extends BodyTagSupport{    private BodyContent bodyContent;    @Override    public void setBodyContent(BodyContent b) {        this.bodyContent = b;    }    @Override    public int doEndTag() throws JspException {        String content = bodyContent.getString();        System.out.println(content);        //修改页面内容        String newStr = "www.abc.com";        JspWriter jspWriter = bodyContent.getEnclosingWriter();        try {            jspWriter.write(newStr);        } catch (IOException e) {            e.printStackTrace();        }        //服务器继续执行该页面        return EVAL_PAGE;    }}

2、tld文件,完成标签

<?xml version="1.0" encoding="UTF-8" ?><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>TagLibrary</short-name>    <uri>/aric-Tag</uri>    <tag>        <name>date</name>        <tag-class>cn.aric.tag.DateTag</tag-class>        <!-- 空的标签体 -->        <body-content>empty</body-content>    </tag>    <tag>        <name>body</name>        <tag-class>cn.aric.tag.BodyTag</tag-class>        <body-content>scriptless</body-content>    </tag> </taglib>

3、编写jsp页面,使用自定义标签

<%@ page language="java" contentType="text/html; charset=UTF-8"    pageEncoding="UTF-8"%><%@ taglib uri="/aric-Tag" prefix="a" %><!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></title></head><body>    <a:body>        欢迎访问网站!    </a:body></body></html>

继承SimpleTagSupport的方式

开发步骤:
1、继承SimpleTagSupport,重写doTag方法。

/** * 自定义日期标签 */public class DateSimpleTag extends SimpleTagSupport {    @Override    public void doTag() throws JspException, IOException {        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");        String dateFormat = sdf.format(new Date());        //获取jsp输出流        JspWriter jspWriter = getJspContext().getOut();        jspWriter.write(dateFormat);    }}

2、新建aricTag.tld文件,写标签及属性

<?xml version="1.0" encoding="UTF-8" ?><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>SimpleTagLibrary</short-name>    <uri>/aric-SimpleTag</uri>    <tag>        <name>date</name>        <tag-class>cn.aric.simpleTag.DateSimpleTag</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="/aric-SimpleTag" prefix="s" %><!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></title></head><body>    欢迎登陆网站!当前时间:<s:date/></body></html>

修改标签内容

Java代码:

/** * 修改页面内容 */public class BodySimpleTag extends SimpleTagSupport{    @Override    public void doTag() throws JspException, IOException {        StringWriter stringWriter = new StringWriter();        JspFragment jspFragment = getJspBody();        jspFragment.invoke(stringWriter);        String content = stringWriter.toString();        System.out.println(content);        content = "www.shuai.com";        PageContext pageContext = (PageContext) getJspContext();        pageContext.getOut().write(content);    }}

在aricTag.tld文件中加自定义标签:

<tag>    <name>body</name>    <tag-class>cn.aric.simpleTag.BodySimpleTag</tag-class>    <body-content>scriptless</body-content></tag>

url访问权限

Java代码:

/** * 根据链接来源判断是否有权限访问 */public class LinkSimpleTag extends SimpleTagSupport {    @Override    public void doTag() throws JspException {        PageContext pageContext =  (PageContext) getJspContext();        HttpServletRequest request = (HttpServletRequest) pageContext.getRequest();        //http协议中头文件属性,告诉服务器是从哪个页面链接过来的        String referer = request.getHeader("referer");        if (referer == null) {            //如果不是链接过来的抛出异常            throw new SkipPageException();        }    }}

在aricTag.tld文件中加自定义标签:

<tag>    <name>link</name>    <tag-class>cn.aric.simpleTag.LinkSimpleTag</tag-class>    <body-content>empty</body-content></tag>

新建link.jsp页面,访问不到页面

<%@ page language="java" contentType="text/html; charset=UTF-8"    pageEncoding="UTF-8"%><%@ taglib uri="/aric-SimpleTag" prefix="s" %><!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></title></head><body>    <s:link/>    <h3>我是测试超链接的网页!</h3></body></html>

新建access.jsp页面,添加a标签链接到link.jsp页面,能访问到

<%@ page language="java" contentType="text/html; charset=UTF-8"    pageEncoding="UTF-8"%><!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></title></head><body>    <a href="http://localhost:8008/tag/simplePage/link.jsp">超链接访问</a></body></html>

循环遍历

Java代码:

/** * 循环表达式,用来遍历集合 */@SuppressWarnings("unused")public class LoopSimpleTag extends SimpleTagSupport{    //自定义属性,并添加setter方法    private String var;    private String[] items;    public void setVar(String var) {        this.var = var;    }    public void setItems(String[] items) {        this.items = items;    }    @Override    public void doTag() throws JspException, IOException {        if (items != null && items.length > 0) {            PageContext pageContext = (PageContext) getJspContext();            for (int i = 0; i < items.length; i++) {                pageContext.setAttribute("name", items[0]);                getJspBody().invoke(null);            }        }    }}

在aricTag.tld文件中加自定义标签:

<tag>    <name>loop</name>    <tag-class>cn.aric.simpleTag.LoopSimpleTag</tag-class>    <body-content>scriptless</body-content>    <attribute>        <name>var</name>        <required>true</required>    </attribute>    <attribute>        <name>items</name>        <required>true</required>        <rtexprvalue>true</rtexprvalue>    </attribute></tag>

新建loop.jsp页面,在页面中使用自定义标签

<%@ page language="java" contentType="text/html; charset=UTF-8"    pageEncoding="UTF-8"%><%@ taglib uri="/aric-SimpleTag" prefix="s" %><!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></title></head><body>    <!-- 实际是从后台传输数据,以下的java代码只是为了简单演示循环效果 -->    <%         String[] persons = {"张三","李四","王五"};        pageContext.setAttribute("persons", persons);    %>    <s:loop items="${persons }" var="name">        ${name }    </s:loop></body></html>

参数表达式

Java代码:

/** * 根据参数来确定是否显示标签体中内容 */public class ParamSimpleTag extends SimpleTagSupport{    @Override    public void doTag() throws JspException, IOException {        PageContext pageContext =  (PageContext) getJspContext();        String name = pageContext.getRequest().getParameter("name");        //如果页面传过来的参数是aric,显示标签体中内容        if (name != null && "aric".equals(name)) {            getJspBody().invoke(null);        }        super.doTag();    }}

在aricTag.tld文件中加自定义标签:

<tag>    <name>param</name>    <tag-class>cn.aric.simpleTag.ParamSimpleTag</tag-class>    <body-content>scriptless</body-content></tag>

新建param.jsp页面,在页面中使用自定义标签

<%@ page language="java" contentType="text/html; charset=UTF-8"    pageEncoding="UTF-8"%><%@ taglib uri="/aric-SimpleTag" prefix="s" %><!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></title></head><body>    <s:param>        <h3>测试params</h3>    </s:param></body></html>

条件表达式

Java代码:

/** * 条件表达式 */public class IfSimpleTag extends SimpleTagSupport{    //条件属性    private boolean flag;    public void setFlag(boolean flag) {        this.flag = flag;    }    @Override    public void doTag() throws JspException, IOException {        if (flag) {            getJspBody().invoke(null);        }    }}

在aricTag.tld文件中加自定义标签:

<tag>    <name>if</name>    <tag-class>cn.aric.simpleTag.IfSimpleTag</tag-class>    <body-content>scriptless</body-content>    <attribute>        <name>flag</name>        <!-- 必要的 -->        <required>true</required>        <!-- 允许使用EL表达式 -->        <rtexprvalue>true</rtexprvalue>    </attribute></tag>

jsp页面

<%@ page language="java" contentType="text/html; charset=UTF-8"    pageEncoding="UTF-8"%><%@ taglib uri="/aric-SimpleTag" prefix="s" %><!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></title></head><body>    <!-- 实际是从后台传输数据,以下的java代码只是为了简单演示循环效果 -->    <%        String name ="aric";        pageContext.setAttribute("name", name);    %>    <s:if flag="${name == 'aric' }">        欢迎访问网站!    </s:if>    <s:if flag="${name != 'aric' }">        请您先注册!    </s:if></body></html>

复合标签

Java标签:

/** * 复合标签中父标签 */public class ChooseSimpleTag extends SimpleTagSupport{    //条件标记    private boolean flag;    public void setFlag(boolean flag) {        this.flag = flag;    }    public boolean isFlag() {        return flag;    }    @Override    public void doTag() throws JspException, IOException {        getJspBody().invoke(null);    }}
/** * 复合表达式,符合条件情况的表达式 */public class WhenSimpleTag extends SimpleTagSupport{    //测试是否符合条件的标记    private boolean test;    public void setTest(boolean test) {        this.test = test;    }    @Override    public void doTag() throws JspException, IOException {        //符合test条件        if (test) {            getJspBody().invoke(null);            ChooseSimpleTag choose = (ChooseSimpleTag) getParent();            //设置父标签的标记为true            choose.setFlag(true);        }    }}
/** * 复合表达式,其他不符合when情况的表达式 */public class OtherSimpleTag extends SimpleTagSupport{    @Override    public void doTag() throws JspException, IOException {        ChooseSimpleTag choose = (ChooseSimpleTag) getParent();        //不符合条件        if (!choose.isFlag()) {            getJspBody().invoke(null);        }    }}

在aricTag.tld文件中加自定义标签:

<tag>    <name>choose</name>    <tag-class>cn.aric.simpleTag.ChooseSimpleTag</tag-class>    <body-content>scriptless</body-content></tag><tag>    <name>when</name>    <tag-class>cn.aric.simpleTag.WhenSimpleTag</tag-class>    <body-content>scriptless</body-content>    <attribute>        <name>test</name>        <required>true</required>        <rtexprvalue>true</rtexprvalue>    </attribute></tag><tag>    <name>other</name>    <tag-class>cn.aric.simpleTag.OtherSimpleTag</tag-class>    <body-content>scriptless</body-content></tag>

jsp页面:

<%@ page language="java" contentType="text/html; charset=UTF-8"    pageEncoding="UTF-8"%><%@ taglib uri="/aric-SimpleTag" prefix="s" %><!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></title></head><body>    <%        pageContext.setAttribute("name", "java");    %>    <s:choose>        <s:when test="${name eq 'java'}">我是Java程序员</s:when>        <s:other>我不是Java程序员</s:other>    </s:choose></body></html>