JSTL_自定义标签

1.自定义标签步骤

  1. jsp引入tld文件及标签
  2. tld文件描述页面标签
  3. 后端class标签类(TagClass)的关系

2.jsp页面标签——设计(创造)

  1. 标签结构:<前缀:标签名 属性=”属性值”>标签体

3.extends TagSupport实现自定义标签

1.<%@ taglib prefix="mytag" uri="http://www.lps.com/mytag" %>

<mytag:nowTime format="yyyy-MM-dd HH:mm:ss" var="time" outEl="true">当前时间:${time}</mytag:nowTime>

2.

<?xml version="1.0" encoding="UTF-8" ?>
http://java.sun.com/xml/ns/javaee"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-jsptaglibrary_2_1.xsd"
    version="2.1">
  <description>web 1 tag</description>
  <display-name>mytag</display-name>
  <tlib-version>1.0</tlib-version>  <!-- 版本 -->
  <short-name>mytag</short-name> <!-- 前缀 -->
  http://www.lps.com/mytag> 
  <tag>
    <name>nowTime</name> <!-- 标签名 -->
    <tag-class>com.lps.tag.NowTimeTag</tag-class> <!-- 对应类 -->
    <body-content>JSP</body-content> <!-- 标签体内容格式 -->
    <attribute>  <!-- 属性 -->
        <name>format</name> <!-- 属性名 -->
        <required>false</required> <!-- 属性是不是必须添加 -->
        <rtexprvalue>true</rtexprvalue> <!-- 是否可以输入表达式 -->
    </attribute>
    <attribute>
        <name>var</name>
        <required>false</required>
        <rtexprvalue>false</rtexprvalue>
    </attribute>
    <attribute>
        <name>outEl</name>
        <required>false</required>
        <rtexprvalue>true</rtexprvalue>
    </attribute>
  </tag>
  </taglib>

3.

public class NowTimeTag extends TagSupport{
    //结束标签后运行doEndTag(),开始解析标签时执行doStartTag()
    private String format="yyyy年MM月dd日 hh:mm:ss";
    private String var;
    private boolean outEl;
//  @Override
//  public int doEndTag() throws JspException {
//      System.out.println("doEndTag");
//      return EVAL_PAGE;
//  }

    @Override
    public int doStartTag() throws JspException {
        try {
        Date date=new Date();
        SimpleDateFormat sdf=new SimpleDateFormat(format);
        String dateStr=sdf.format(date);
        if(var!=null&&outEl){
            pageContext.setAttribute(var, dateStr);
        }else{
            pageContext.getOut().print(dateStr);
        }
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        return EVAL_BODY_INCLUDE;
    }

    public String getFormat() {
        return format;
    }

    public void setFormat(String format) {
        this.format = format;
    }

    public String getVar() {
        return var;
    }

    public void setVar(String var) {
        this.var = var;
    }

    public boolean isOutEl() {
        return outEl;
    }

    public void setOutEl(boolean outEl) {
        this.outEl = outEl;
    }



}

PS:

  1. doStartTag()执行在属性输入之后
  2. 标签体显示控制:doStartTag()返回值EVAL_BODY_INCLUDE则显示,SKIP_BODY则跳过
  3. doEndTag()控制后续页面是否显示:EVAL_PAGE,SKIP_PAGE

3.extends TagSupport实现for循环自定义标签

    <mytag:for begin="1" end="10" step="1">
        a<br>
    </mytag:for><br>
public class ForTag extends TagSupport{
    private int begin;
    private int end;
    private int step;

    @Override
    //在标签体后循环执行
    public int doAfterBody() throws JspException {

        if(end>=begin){
            begin=begin+step;
            return EVAL_BODY_AGAIN;
        }else{
            return EVAL_BODY_INCLUDE;
        }
    }

    @Override
    public int doStartTag() throws JspException {
        if(end>=begin){
            begin=begin+step;
            return EVAL_BODY_INCLUDE;
        }else{
            return SKIP_BODY;
        }
    }

    public int getBegin() {
        return begin;
    }

    public void setBegin(int begin) {
        this.begin = begin;
    }

    public int getEnd() {
        return end;
    }

    public void setEnd(int end) {
        this.end = end;
    }

    public int getStep() {
        return step;
    }

    public void setStep(int step) {
        this.step = step;
    }

}

4.extends BodyTagSupport创建可获取标签提体的自定义标签

    <mytag:newBean var="user" type="com.lps.pojo.Users" scope="request" regex="," >
        id:1,userName:李四,age:30
    </mytag:newBean>
    ${user.id}<br>
    ${user.userName }
    ${user.age }
public class NewBeanTag extends BodyTagSupport{
    private String var;
    private String type;
    private String regex=",";
    private String scope="page";
    private Class c;
    private Object obj;


    @Override
    public int doEndTag() throws JspException {
        try {
            String body=bodyContent.getString().trim();
            String fields[]=body.split(regex);
            for(String field:fields){
                String fieldName=field.split(":")[0];
                String fieldValue=field.split(":")[1];
                String setMethodName="set"+fieldName.substring(0,1).toUpperCase()+fieldName.substring(1);
                String getMethodName="get"+fieldName.substring(0,1).toUpperCase()+fieldName.substring(1);
                Method getMethod=c.getMethod(getMethodName, null);
                Method setMethod=c.getMethod(setMethodName, getMethod.getReturnType());
                if(getMethod.getReturnType()==Integer.class||getMethod.getReturnType()==int.class){
                    int num=Integer.parseInt(fieldValue);
                    setMethod.invoke(obj, num);
                }else{
                    setMethod.invoke(obj, fieldValue);
                }

            }
        } catch (NoSuchMethodException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (SecurityException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (IllegalAccessException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (IllegalArgumentException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (InvocationTargetException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }

        return EVAL_PAGE;
    }
    @Override
    public int doStartTag() throws JspException {
        try {
            c=Class.forName(type);
            obj=c.newInstance();
            switch(scope){
                case "page":pageContext.setAttribute(var, obj);break;
                case "request":pageContext.getRequest().setAttribute(var, obj);break;
                case "session":pageContext.getSession().setAttribute(var, obj);break;
                case "application":pageContext.getServletContext().setAttribute(var, obj);break;
                default:pageContext.setAttribute(var, obj);
            }

        } catch (ClassNotFoundException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (InstantiationException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (IllegalAccessException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        return EVAL_BODY_BUFFERED;
    }
    public String getVar() {
        return var;
    }
    public void setVar(String var) {
        this.var = var;
    }
    public String getType() {
        return type;
    }
    public void setType(String type) {
        this.type = type;
    }
    public String getRegex() {
        return regex;
    }
    public void setRegex(String regex) {
        this.regex = regex;
    }
    public String getScope() {
        return scope;
    }
    public void setScope(String scope) {
        this.scope = scope;
    }

}

ps:

  1. doStartTag()设置返回值为EVAL_BODY_BUFFERED,将标签体内容放入缓存(内存)
  2. doEndTag()或doAfterBody()中利用父类的bodyContent对象获取标签体内容。

5.extends SimpleTagSupport创建可获取标签提体的自定义标签

  1. 重写doTag()方法,没有任何返回值。
  2. 属性读取,标签体读取getJspBody(),页面输出或会话区间添加值getJspContext(),PageContext.SESSION_SCOPE

标签体读取getJspBody():

StringWriter sw=new StringWriter();
getJspBody().invoke(sw);
System.out.println(sw.toString().trim());
sb.append(sw.toString());

页面输出或会话区间添加值

        System.out.println(getJspContext().getAttribute("demo"));
System.out.println(getJspContext().getAttribute("demo",PageContext.SESSION_SCOPE));
getJspContext().setAttribute("demoStr", "李珍基", PageContext.REQUEST_SCOPE);

6.嵌套标签

一般嵌套和普通标签开发无差别,唯一难点——当父标签采用BodyTagSupport并设置EVAL_BODY_BUFFERED时,必须将子表签重新写入父标签输出流,因为此时子标签的输出流不是pageContext.getOut()页面输出流而是父标签的bodyContent对象本身。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值