JSP自定义标签

当jsp的内置标签和jstl标签库内的标签都满足不了需求,这时候就需要开发者自定义标签。

自定义标签的开发步骤

1 创建一个标签助手类(继承BodyTagSupport)

标签属性必须助手类的属性对应、且要提供对应get/set方法rtexprvalue

2 在你的web应用目录下,找到WEB-INF文件夹,在里面新建一个tld类型的文件

如果你忘记了怎么写,可以参考jstl里的tld文件,如下:

<!DOCTYPE taglib
  PUBLIC "-//Sun Microsystems, Inc.//DTD JSP Tag Library 1.2//EN"
   "http://java.sun.com/dtd/web-jsptaglibrary_1_2.dtd">
<!-- 标签库描述符 -->
<taglib xmlns="http://java.sun.com/JSP/TagLibraryDescriptor">
    <!-- 代表标签库的版本号 -->
    <tlib-version>1.0</tlib-version>
    <!-- 代表jsp的版本 -->
    <jsp-version>1.2</jsp-version>
    <!-- 你的标签库的简称 -->
    <short-name>test</short-name>
    <!-- 你标签库的引用uri -->
    <uri>/zking</uri>

    <tag>
        <!-- 标签名 -->
        <name>yy</name>
        <!-- 标签工具类 -->
        <tag-class>com.TestTag</tag-class>
        <!-- 标签的内容类型:empty表示空标签,jsp表示可以为任何合法的JSP元素 -->
        <body-content>jsp</body-content>
        <!-- 自定义标签的属性定义,请注意一定要在标签类中提供对应的get/set方法 -->
        <attribute>
            <!-- 自定义标签的属性名称 -->
            <name>name</name>
            <!-- true表示必填 -->
            <required>true</required>
            <!-- true支持动态值,可以向值里面填jsp表达式、EL表达式,false则不支持 -->
            <rtexprvalue>false</rtexprvalue>
        </attribute>
    </tag>
</taglib>

3在JSP通过taglib指令导入标签库,并通过指定后缀访问自定义标签

JSP自定义标签生命周期图:

SKIP_BODY:跳过主体

EVAL_BODY_INCLUDE:计算标签主体内容并[输出]

EVAL_BODY_BUFFERED:计算标签主体内容并[缓存]

EVAL_PAGE:计算页面的后续部分

SKIP_PAGE:跳过页面的后续部分

EVAL_BODY_AGAIN:再计算主体一次

自定义set和out标签

分别创建一个·set和out的助手类

1.set

package com.jsp;
import
javax.servlet.jsp.JspException; import javax.servlet.jsp.tagext.BodyTagSupport; public class SetTag extends BodyTagSupport{ private static final long serialVersionUID = 1L; private String var; private Object value; public String getVar() { return var; } public void setVar(String var) { this.var = var; } public Object getValue() { return value; } public void setValue(Object value) { this.value = value; } @Override public int doStartTag() throws JspException { pageContext.setAttribute(var, value);//将值存入pageContext return SKIP_BODY; }

2.out

package com.jsp;

import java.io.IOException;

import javax.servlet.jsp.JspException;
import javax.servlet.jsp.JspWriter;
import javax.servlet.jsp.tagext.BodyTagSupport;

public class OutTag extends BodyTagSupport {

    private static final long serialVersionUID = 5811663341301161566L;

    private String value;

    public String getValue() {
        return value;
    }

    public void setValue(String value) {
        this.value = value;
    }

    @Override
    public int doStartTag() throws JspException {
        JspWriter out = pageContext.getOut();
        try {
            out.print(value);
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        return SKIP_BODY;
    }
}

在tld文件中添加set和out的标签

  <tag>
        <name>set</name>
        <tag-class>com.jsp.SetTag</tag-class>
        <body-content>JSP</body-content>
        <attribute>
            <name>var</name>
            <required>true</required>
            <rtexprvalue>false</rtexprvalue>
        </attribute>
        <attribute>
            <name>value</name>
            <required>true</required>
            <rtexprvalue>true</rtexprvalue>
        </attribute>
    </tag>
    <tag>
        <name>out</name>
        <tag-class>com.jsp.OutTag</tag-class>
        <body-content>JSP</body-content>
        <attribute>
            <name>value</name>
            <required>true</required>
            <rtexprvalue>true</rtexprvalue>
        </attribute>
    </tag>

jsp页面演示set,out标签

<z:set var="name" value="hello"></z:set>
<z:out value="${name }"></z:out>

自定义if标签

步骤同上:

package com.jsp.jsp;
/*
 * if助手类
 */
import javax.servlet.jsp.JspException;
import javax.servlet.jsp.tagext.BodyTagSupport;
 
public class IfTag extends BodyTagSupport{
  private boolean test;
 
public boolean isTest() {
    return test;
}
 
public void setTest(boolean test) {
    this.test = test;
}
   
   @Override
    public int doStartTag() throws JspException {
        if(!test) {
            return SKIP_BODY;//不显示标签中间的内容
        }
        return EVAL_BODY_INCLUDE;//显示标签中间的内容
    }
     
}
    <tag>
        <name>if</name>
        <tag-class>com.jsp.IfTag</tag-class>
        <body-content>JSP</body-content>
        <attribute>
            <name>test</name>
            <required>true</required>
            <rtexprvalue>true</rtexprvalue>
        </attribute>
    </tag>   

jsp页面演示:

<c:if test="true" >你看得见我</c:if>
<c:if test="false">你看不见我</c:if>

定义foreach标签

package com.jsp;
/**
 * foreach助手类
 */
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;

import javax.servlet.jsp.JspException;
import javax.servlet.jsp.tagext.BodyTagSupport;

public class ForeachTag extends BodyTagSupport {

    private static final long serialVersionUID = -6290285418914929131L;
    private String var;
    private List<Object> items = new ArrayList<>();

    public String getVar() {
        return var;
    }

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

    public List<Object> getitems() {
        return items;
    }

    public void setitems(List<Object> items) {
        this.items = items;
    }

    @Override
    public int doStartTag() throws JspException {
        if (items == null || items.size() == 0) {
            return SKIP_BODY;
        } else {
            Iterator<Object> it = items.iterator();
            // 作用域进行传递
            pageContext.setAttribute("it", it);
            // 第一次给变量进行赋值
            pageContext.setAttribute(var, it.next());
            return EVAL_BODY_INCLUDE;
        }
    }

    @Override
    public int doAfterBody() throws JspException {
        // TODO Auto-generated method stub
        Iterator<Object> its = (Iterator<Object>) pageContext.getAttribute("it");
        while (its.hasNext()) {
            // 将循环读取出来的数据显示在界面上
            pageContext.setAttribute(var, its.next());
            return EVAL_BODY_AGAIN;
        }
        return SKIP_BODY;
    }
}
  <tag>
        <name>foreah</name>
        <tag-class>com.jsp.ForeachTag</tag-class>
        <body-content>JSP</body-content>
        <attribute>
            <name>var</name>
            <required>true</required>
            <rtexprvalue>true</rtexprvalue>
        </attribute>
        <attribute>
            <name>items</name>
            <required>true</required>
            <rtexprvalue>true</rtexprvalue>
        </attribute>
    </tag>

jsp页面演示foreach标签

    <%
        List<String> is = new ArrayList<>();
        is.add("aa");
        is.add("bb");
        is.add("cc");
        is.add("dd");
        is.add("sb");
        pageContext.setAttribute("is", is);
    %> 
    <ol>
        <z:foreah items="${is }" var="i">
            <li>${i }</li>
        </z:foreah>
    </ol>

JSP自定义select标签

创建一个学生类

package com.entity;

public class Student {

    private String sid;
    private String sname;
    public String getsid() {
        return sid;
    }
    public void setsid(String sid) {
        this.sid = sid;
    }
    public String getsname() {
        return sname;
    }
    public void setsname(String sname) {
        this.sname = sname;
    }
    public Student(String sid, String sname) {
        super();
        this.sid = sid;
        this.sname = sname;
    }
    public Student() {
        super();
        // TODO Auto-generated constructor stub
    }
    
}
package com.jsp;

import java.io.IOException;
import java.lang.reflect.Field;
import java.util.ArrayList;
import java.util.List;

import javax.servlet.jsp.JspException;
import javax.servlet.jsp.JspWriter;
import javax.servlet.jsp.tagext.BodyTagSupport;

import org.apache.commons.beanutils.BeanUtils;

public class SelectTag extends BodyTagSupport {

    private static final long serialVersionUID = 1L;
    private String id;
    private String name;
    private List<Object> items = new ArrayList<Object>();
    private String textKey;
    private String textval;
    private String headTextKey;
    private String headTextVal;
    private String selectedval;
 
    public String getId() {
        return id;
    }
 
    public void setId(String id) {
        this.id = id;
    }
 
    public String getName() {
        return name;
    }
 
    public void setName(String name) {
        this.name = name;
    }
 
    public List<Object> getItems() {
        return items;
    }
 
    public void setItems(List<Object> items) {
        this.items = items;
    }
 
    public String getTextKey() {
        return textKey;
    }
 
    public void setTextKey(String textKey) {
        this.textKey = textKey;
    }
 
    public String getTextval() {
        return textval;
    }
 
    public void setTextval(String textval) {
        this.textval = textval;
    }
 
    public String getHeadTextKey() {
        return headTextKey;
    }
 
    public void setHeadTextKey(String headTextKey) {
        this.headTextKey = headTextKey;
    }
 
    public String getHeadTextVal() {
        return headTextVal;
    }
 
    public void setHeadTextVal(String headTextVal) {
        this.headTextVal = headTextVal;
    }
 
    public String getSelectedval() {
        return selectedval;
    }
 
    public void setSelectedval(String selectedval) {
        this.selectedval = selectedval;
    }
 
    @Override
    public int doStartTag() throws JspException {
        JspWriter out = pageContext.getOut();
        try {
            out.write(toHTML());
        } catch (Exception e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        return super.doStartTag();
    }
    /**
     * 拼接出下拉列表所对应的select的html代码
     * <select id='' name=''>
     *  <option value='-1'selected>=======请选择======</option>
     *   </select>
     */
    private String toHTML() throws Exception {
        StringBuilder sb = new StringBuilder();
        sb.append("<select id='" + id + "' name='" + name + "'>");
        if (headTextKey == null || "".equals(headTextKey) || headTextVal == null || "".equals(headTextVal)) {
            sb.append("<option value='" + headTextKey + "' selected>" + headTextVal + "</option>");
        }
        String val;
        String html;
        for (Object obj : items) {
            // 要让学生的id存入数据库,让学生的名字展示在jsp页面
            // <option value='s001'>ls</option>
            // obj sid sname
            Field textKeyField = obj.getClass().getDeclaredField(textKey);
            textKeyField.setAccessible(true);
            val = (String) textKeyField.get(obj);
            html = BeanUtils.getProperty(obj, textval);
            if(val.equals(selectedval)) {
                sb.append(" <option value='"+val+"'selected>"+html+"</option>");
            }else {
                sb.append("<option value='"+val+"'>"+html+"</option>");
            }
        }
        sb.append("</select>");
        return sb.toString();
    }

}

select标签的tld文件

<tag>
        <name>select</name>
        <tag-class>com.jsp.ServletTag</tag-class>
        <body-content>JSP</body-content>
        <attribute>
            <name>id</name>
            <required>false</required>
            <rtexprvalue>flase</rtexprvalue>
        </attribute>
        <attribute>
            <name>name</name>
            <required>flase</required>
            <rtexprvalue>flase</rtexprvalue>
        </attribute>
        <attribute>
            <name>items</name>
            <required>true</required>
            <rtexprvalue>true</rtexprvalue>
        </attribute>
        <attribute>
            <name>textKey</name>
            <required>true</required>
            <rtexprvalue>false</rtexprvalue>
        </attribute>
        <attribute>
            <name>textval</name>
            <required>true</required>
            <rtexprvalue>flase</rtexprvalue>
        </attribute>
        <attribute>
            <name>headTextKey</name>
            <required>false</required>
            <rtexprvalue>false</rtexprvalue>
        </attribute>
        <attribute>
            <name>headTextVal</name>
            <required>false</required>
            <rtexprvalue>flase</rtexprvalue>
        </attribute>
        <attribute>
            <name>selectedval</name>
            <required>false</required>
            <rtexprvalue>true</rtexprvalue>
        </attribute>
    </tag>
    <%
    List<Student> student=new ArrayList();
    student.add(new Student("1","zs"));
    student.add(new Student("2","ls"));
    student.add(new Student("3","ww"));
    student.add(new Student("4","zl"));
    student.add(new Student("5","qq"));
    student.add(new Student("6","gd"));
    student.add(new Student("7","wb"));
    pageContext.setAttribute("stus", student);
    %>

    <p:select  items="${stus }" textval="sname" textKey="sid"></p:select>
    <p:select headTextKey="-1" headTextVal="===请选择学生===" items="${stus }" textval="sname" textKey="sid"></p:select>
原文地址:https://www.cnblogs.com/huxiaocong/p/11059697.html