Jsp自定义标签

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>
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值