zoukankan      html  css  js  c++  java
  • 自定义的JSP标签

    JSP标签

    JSP标准标签库(JSTL)是一个JSP标签集合,它封装了JSP应用的通用核心功能。

    JSTL支持通用的、结构化的任务,比如迭代,条件判断,XML文档操作,国际化标签,SQL标签。 除了这些,它还提供了一个框架来使用集成JSTL的自定义标签。

    我们称之为C标签;

    自定义标签开发步骤(简要)

    1.助手类(标签功能的主要实现类 继承BodyTagSupport 类)

    2.tld文件 (用于配置所有自定义标签的实现类以及每个自定义标签所有的属性)

    3.taglib (jsp页面的调用)
     


    1. 标签语言特点  

       <开始标签 属性="属性值">标签体</结束标签>

    自定义标签实列代码

    .下面是几个比较简单的自定义标签实列

    1.根据以上步骤先创建助手类(Set   Out  If   ForEach

    Set

    package com.temptag;
    
    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 String value;
        public String getVar() {
            return var;
        }
        public void setVar(String var) {
            this.var = var;
        }
        public String getValue() {
            return value;
        }
        public void setValue(String value) {
            this.value = value;
        }
        
        @Override
        public int doStartTag() throws JspException {
            pageContext.setAttribute(var, value);
            return SKIP_BODY;
        }
        
        
    
    }

    Out :

    package com.temptag;
    
    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 = 8402945242L;
    
        private Object value;
        
        
        public Object getValue() {
            return value;
        }
    
        public void setValue(Object value) {
            this.value = value;
        }
    
        @Override
        public int doStartTag() throws JspException {
          JspWriter out =    pageContext.getOut();
          try {
            out.write(value.toString());
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
            return SKIP_BODY;
        }
        
    }

    if :

    package com.temptag;
    
    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 {
            return test ? EVAL_BODY_INCLUDE :  SKIP_BODY;
            
            //if判断
    //        if(!test) {
    //            return SKIP_BODY;//不显示标签中间的内容
    //        }
    //        
    //        return EVAL_BODY_INCLUDE;//显示标签中的内容
        }
        
    }

    ForEach :

    package com.temptag;
    
    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 = -91652238343L;
    
        // 1 itema  集合  2.var 变量名
        private List<Object> items;
        private String var;
        public List<Object> getItems() {
            return items;
        }
        public void setItems(List<Object> items) {
            this.items = items;
        }
        public String getVar() {
            return var;
        }
        public void setVar(String var) {
            this.var = var;
        }
        
        //<开始> doSartTag <结束>
        @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 {
        Iterator<Object> it=(Iterator<Object>)    pageContext.getAttribute("it");
        while(it.hasNext()) {
            //如何将循环取出的数据显示在页面上
            pageContext.setAttribute(var, it.next());
            return EVAL_BODY_AGAIN;
        }
            return SKIP_BODY;
        }
        
    }

    2.助手类写完之后就可以开始创建tld文件(mytag.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>/yuan</uri>
    
            <!-- set标签 -->
        <tag>
          <name>set</name>
          <tag-class>com.temptag.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>

    <!-- out标签 --> <tag> <name>out</name> //标签库中的标签名 <tag-class>com.temptag.Outtag</tag-class>//标签的助手类全路径名 <body-content>JSP</body-content>//标签类型 <attribute> <name>value</name>//标签属性名 在配置的时候必须与助手类的属性一致 <required>true</required>//该属性是否必填 <rtexprvalue>true</rtexprvalue>//是否支持表达式(EL) </attribute> </tag> <!-- if标签 --> <tag> <name>if</name> <tag-class>com.temptag.IfTag</tag-class> <body-content>JSP</body-content> <attribute> <name>test</name> <required>true</required> <rtexprvalue>true</rtexprvalue> </attribute> </tag> <!-- foreach标签 --> <tag> <name>foreach</name> <tag-class>com.temptag.ForEachTag</tag-class> <body-content>JSP</body-content> <attribute> <name>items</name> <required>true</required> <rtexprvalue>true</rtexprvalue> </attribute> <attribute> <name>var</name> <required>true</required> <rtexprvalue>false</rtexprvalue> </attribute> </tag>

    set和out标签调用

    代码:

    <%@taglib prefix="z" uri="/yuan" %>//在jsp页面的html标签以上调用,根据标签库名称调用。
    <body>
    
    <z:set var="name" value="zhangsan"></z:set>
       <z:out value="${name }"/> 
    
    </body>

    输出结果:zhangsan

    if标签调用:

    <z:if test="${1>0 }">"后续"</z:if>

    test返回true,结果显示   "后续",

    test改为${1>2 } 返回false 结果不显示出   "后续"。

    ForEach调用:

    <%
         List<String> ls= new ArrayList<>();
         ls.add("zs");
         ls.add("ls");
         ls.add("ww");
         ls.add("zl");
         ls.add("dg");
         ls.add("tr");
         ls.add("mt");
         pageContext.setAttribute("ls", ls);
      
      %>
      
      
      <ol>
      
      <z:foreach items="${ls }" var="l">
      <li>${l }</li>
      </z:foreach>
      </ol>

    显示结果:

    1. zs
    2. ls
    3. ww
    4. zl
    5. dg
    6. tr
    7. mt

    这些标签JSTL标签库基本上都有的,下面是一个自定义selects(下拉框)标签 ,

    selects标签助手类:

    package com.temptag;
    
    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;
    
    /**
     * <select id='' name=''>
     * <option value='-1' selected>===请选择===</option>
     * </select>
     * 查询维度:下拉列表
     * 修改页面:下拉列表  数据回显
     * 
     * 
     * 1、id  name
     * 2、需要数据源items(传入数据)、存入数据库的值textKey、展示列textVal
     * 3、加入属性(默认的头部属性 headTextKey 和默认的展示列值headTextVal)
     * 4、加入属性,能实现数据回显的功能selectedVal
     * @author ***
     *
     */
    
    
    public class selectT extends BodyTagSupport{
    
        /**
         * 
         */
        private static final long serialVersionUID = 1L;
    
        private String id;
        private String name;
        private List<Object> items= new ArrayList<>();
        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>
         * @return
         */
         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存入数据库,把name展示在jsp页面
    //             <option value='s001' selected>zhangsan</option>
    //             得到obj的id和name
                 Field textKeyField = obj.getClass().getDeclaredField(textKey);
                 textKeyField.setAccessible(true);
                 val=(String)textKeyField.get(obj);
                 //此方法需要用到两个jar包, 也可改用上面getDeclaredField();方法
                 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();
         }
        
        
        
    }

    tld文件配置:

    <!-- select2标签 -->
        <tag>
          <name>selects</name>
          <tag-class>com.temptag.selectT</tag-class>
          <body-content>JSP</body-content>
          <attribute>
            <name>id</name>
            <required>false</required>
            <rtexprvalue>false</rtexprvalue>
          </attribute>
          <attribute>
            <name>name</name>
            <required>false</required>
            <rtexprvalue>false</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>false</rtexprvalue>
          </attribute>
          <attribute>
            <name>headTextKey</name>
            <required>false</required>
            <rtexprvalue>false</rtexprvalue>
          </attribute>
          <attribute>
            <name>headTextVal</name>
            <required>false</required>
            <rtexprvalue>false</rtexprvalue>
          </attribute>
          <attribute>
            <name>selectedVal</name>
            <required>false</required>
            <rtexprvalue>true</rtexprvalue>
          </attribute>
        </tag>

    在调用的时候需要用到一个实体类 (Student)

    Student信息:

    package com.temp.entity;
    
    public class Student {
        private String sid;
    
        private String sname;
    
        public Integer age;
    
        public Student() {
            super();
            System.out.println("调用无参构造方法创建了一个学生对象");
        }
    
        public Student(String sid) {
            super();
            this.sid = sid;
            System.out.println("调用带一个参数的构造方法创建了一个学生对象");
        }
    
        public Student(String sid, String sname) {
            super();
            this.sid = sid;
            this.sname = sname;
            System.out.println("调用带二个参数的构造方法创建了一个学生对象");
        }
    
        @SuppressWarnings("unused")
        private Student(Integer age) {
            System.out.println("调用Student类私有的构造方法创建一个学生对象");
            this.age = age;
        }
    
        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 void hello() {
            System.out.println("你好!我是" + this.sname);
        }
    
        public void hello(String name) {
            System.out.println(name + "你好!我是" + this.sname);
        }
    
        @SuppressWarnings("unused")
        private Integer add(Integer a, Integer b) {
            return new Integer(a.intV
    alue() + b.intValue());
        }
    }

    selects调用:

     <%
        List list = new ArrayList<>();
      list.add(new Student("s001","zhangsan")); 
      list.add(new Student("s002","zhangsan2"));
      list.add(new Student("s003","zhangsan3"));
      list.add(new Student("s004","zhangsan4"));
      list.add(new Student("s005","zhangsan5"));
      list.add(new Student("s006","zhangsan6"));
      list.add(new Student("s007","zhangsan7"));
        
        pageContext.setAttribute("list",list );
      %>
    
      <z:selects headTextKey="-1" headTextVal="请选择...." selectedVal="s006" textVal="sname" items="${list }" textKey="sid"></z:selects>

    其中headTextKey和headTextVal以及selectedVal可不添加,

    添加headTextKey和headTextVal则显示:

    添加selectedVal则显示:

    自定义标签的扩展空间很大,如果可以使用自定义标签来实现的代码这样就可以帮我们省去很多重复的代码。

                                                                                                                                                                                      谢谢观看^_^  !

  • 相关阅读:
    列表页无限滚动翻页组件--解决性能问题
    UI组件化介绍
    js请求数据的例子
    移动端bug和优化
    利用字符串路径获取对象集合的值
    n个骰子的和,组成数字m的可能
    算法-回形路径
    学习python-跨平台获取键盘事件
    获取数组中多个相加等于0的一组数字 javascript
    一个矩阵 JavaScript
  • 原文地址:https://www.cnblogs.com/ly-0919/p/11042611.html
Copyright © 2011-2022 走看看