JSP自定义标签

Posted huxiaocong

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了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>

 

以上是关于JSP自定义标签的主要内容,如果未能解决你的问题,请参考以下文章

JSP自定义标签开放入门

JSP-Runoob:JSP 自定义标签

JSP2 的自定义标签

jsp自定义标签

JSP系列:JSP进阶-自定义JSP标签

JSP自定义标签开发入门