• JavaWeb学习之JSTL自定义标签库的使用、JSTL自定义函数库(7)


    一、自定义标签,步骤
        * 确定需求
            * <my:date />  输出当前系统的时间  yyyy-MM-dd hh:mm:ss:SSS
        * 编写Java类
            新建包名:com.yxl.tag,新建类MyDateTag,实现SimpleTag接口
            * 只要与此接口有关的实现类,javax.servlet.jsp.tagext.JspTag
            * 需要实现具体的接口
                * javax.servlet.jsp.tagext.SimpleTag,简单标签,JSP2.0**,选择这个
                * javax.servlet.jsp.tagext.Tag,经典标签
            package com.yxl.tag;
    
            import java.io.IOException;
            import java.text.SimpleDateFormat;
            import java.util.Date;
            
            import javax.servlet.jsp.JspContext;
            import javax.servlet.jsp.JspException;
            import javax.servlet.jsp.PageContext;
            import javax.servlet.jsp.tagext.JspFragment;
            import javax.servlet.jsp.tagext.JspTag;
            import javax.servlet.jsp.tagext.SimpleTag;
            
            public class MyDateTag implements SimpleTag {
            
                public MyDateTag(){
                    System.out.println("默认构造");
                }
                
                private PageContext pageContext;
                
                /**
                 * 1、被调用的方法,tomcat调用
                 */
                public void setJspContext(JspContext pc) {
            //        System.out.println(pc);
            //        System.out.println("setJspContext");
                    this.pageContext = (PageContext) pc;
                    
                }
            
                /**
                 * 2、tomcat调用
                 *  建议,在doTage方法中完成整个tag的功能
                 *  需要再doTage方法之前,完成准备工作
                 */
                public void doTag() throws JspException, IOException {
            //        System.out.println("doTag");
                    //输出当前系统的时间  yyyy-MM-dd hh:mm:ss:SSS
                    SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd hh:mm:ss:SSS");
                    String date = format.format(new Date());
                    //将获得的时间输出到浏览器
                    this.pageContext.getOut().print(date);
                    
                }
            
                @Override
                public JspTag getParent() {
                    // TODO Auto-generated method stub
                    return null;
                }
            
                @Override
                public void setJspBody(JspFragment arg0) {
                    // TODO Auto-generated method stub
                    
                }
            
                
            
                @Override
                public void setParent(JspTag arg0) {
                    // TODO Auto-generated method stub
                    
                }
            
            }
            
        * 编写tld文件
            在WEB-INF下新建文件夹tld,在tld文件夹下新建mytag.tld
            * tld文件是xml文档
            * 扩展名为*.tld
            * 位置:必须放置到WEB-INF目录下
            * 内容:
                <taglib xmlns="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">
                    <!-- 确定当前标签库的版本 -->
                    <tlib-version>1.0</tlib-version>
                    <!-- 建议引入当前便签库是,使用的简写   @taglib prefix="my" -->
                    <short-name>my</short-name>
                    <!-- 为当前标签库配置文件,起一个名称
                        * 内容:自定义,全球唯一
                     -->
                    <uri>http://www.yxl.cn/jsp/mytag</uri>
                    
                    <!-- <my:date / >  注册标签 -->
                    <tag>
                        <!-- 确定标签名称 -->
                        <name>date</name>
                        <!-- 确定实现类 -->
                        <tag-class>com.yxl.tag.MyDateTag</tag-class>
                        <!-- 格式化当前标签的body内容
                            * empty:当前标签没有标签体
                         -->
                        <body-content>empty</body-content>
                    
                    </tag>
                    
                    
                </taglib>
        * 在JSP页面引入
            * <%@ taglib uri="http://www.yxl.cn/jsp/mytag" prefix="my"%>
        * 测试
            * <my:date />
            
    二、案例
        * 需求:<my:maxVal num1="12" num2="13" />
        package com.yxl.tag;
    
        import java.io.IOException;
        import java.text.SimpleDateFormat;
        import java.util.Date;
        
        import javax.servlet.jsp.JspContext;
        import javax.servlet.jsp.JspException;
        import javax.servlet.jsp.PageContext;
        import javax.servlet.jsp.tagext.JspFragment;
        import javax.servlet.jsp.tagext.JspTag;
        import javax.servlet.jsp.tagext.SimpleTag;
        
        public class MyMaxValueTag implements SimpleTag {
        
            public MyMaxValueTag() {
                System.out.println("默认构造");
            }
        
            private PageContext pageContext;
            private Integer num1;
            private Integer num2;
        
            // num1
            public void setNum1(Integer num) {
                this.num1 = num;
            }
        
            public void setNum2(Integer num) {
                this.num2 = num;
            }
        
            /**
             * 1、被调用的方法,tomcat调用
             */
            public void setJspContext(JspContext pc) {
                // System.out.println(pc);
                // System.out.println("setJspContext");
                this.pageContext = (PageContext) pc;
        
            }
        
            /**
             * 2、tomcat调用 建议,在doTage方法中完成整个tag的功能 需要再doTage方法之前,完成准备工作
             */
            public void doTag() throws JspException, IOException {
                System.out.println(this.num1);
                System.out.println(this.num2);
                // 判断两个数据的大小,然后输出
                if (this.num1 > this.num2) {
                    this.pageContext.getOut().print(num1 + "大于" + num2);
                } else if (this.num1 < this.num2){
        
                    this.pageContext.getOut().print(num1 + "小于" + num2);
                }
                else{
                    this.pageContext.getOut().print(num1 + "等于" + num2);
                }
        
            }
        
            @Override
            public JspTag getParent() {
                // TODO Auto-generated method stub
                return null;
            }
        
            @Override
            public void setJspBody(JspFragment arg0) {
                // TODO Auto-generated method stub
        
            }
        
            @Override
            public void setParent(JspTag arg0) {
                // TODO Auto-generated method stub
        
            }
        
        }
        <taglib xmlns="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">
        <!-- 确定当前标签库的版本 -->
        <tlib-version>1.0</tlib-version>
        <!-- 建议引入当前便签库是,使用的简写 @taglib prefix="my" -->
        <short-name>my</short-name>
        <!-- 为当前标签库配置文件,起一个名称 * 内容:自定义,全球唯一 -->
        <uri>http://www.yxl.cn/jsp/mytag</uri>
    
        <!-- <my:date / > 注册标签 -->
        <tag>
            <!-- 确定标签名称 -->
            <name>date</name>
            <!-- 确定实现类 -->
            <tag-class>com.yxl.tag.MyDateTag</tag-class>
            <!-- 格式化当前标签的body内容 * empty:当前标签没有标签体 -->
            <body-content>empty</body-content>
    
        </tag>
    
        <!-- <my:maxValue / > 注册标签 -->
        <tag>
            <!-- 确定标签名称 -->
            <name>maxValue</name>
            <!-- 确定实现类 -->
            <tag-class>com.yxl.tag.MyMaxValueTag</tag-class>
            <!-- 格式化当前标签的body内容 * empty:当前标签没有标签体 -->
            <body-content>empty</body-content>
            <!-- 确定当前标签使用了哪些属性 -->
            <attribute>
                <!-- 设置属性名称 -->
                <name>num1</name>
                <!-- 设置属性是否必须 * true/false * yes/no -->
                <required>true</required>
                <!-- rtexprvalue 运行时表达式的值 * runtime expression value -->
                <rtexprvalue>true</rtexprvalue>
                <!-- 确定标签类型 -->
                <type>java.lang.Integer</type>
            </attribute>
    
            <attribute>
                <!-- 设置属性名称 -->
                <name>num2</name>
                <!-- 设置属性是否必须 * true/false * yes/no -->
                <required>true</required>
                <!-- rtexprvalue 运行时表达式的值 * runtime expression value -->
                <rtexprvalue>true</rtexprvalue>
            </attribute>
        </tag>
        </taglib>
        
        * 需求:<my:toUpperCase>xxYYdfsdDFwerd</my:toUpperCase>
        标签体
        package com.yxl.tag;
    
        import java.io.IOException;
        import java.io.StringWriter;
        import java.text.SimpleDateFormat;
        import java.util.Date;
        
        import javax.servlet.jsp.JspContext;
        import javax.servlet.jsp.JspException;
        import javax.servlet.jsp.PageContext;
        import javax.servlet.jsp.tagext.JspFragment;
        import javax.servlet.jsp.tagext.JspTag;
        import javax.servlet.jsp.tagext.SimpleTag;
        
        
        public class MyToUpperCaseTag implements SimpleTag {
        
            public MyToUpperCaseTag() {
                System.out.println("默认构造");
            }
        
            private PageContext pageContext;
        
            private JspFragment jspBody;
            
            
           
            
            /**
             * 1、被调用的方法,tomcat调用
             */
            public void setJspContext(JspContext pc) {
                
                this.pageContext = (PageContext) pc;
        
            }
            
             public void setJspBody(JspFragment jspBody){
                    this.jspBody = jspBody;
             }
        
            /**
             * 2、tomcat调用 建议,在doTage方法中完成整个tag的功能 需要再doTage方法之前,完成准备工作
             */
            public void doTag() throws JspException, IOException {
                StringWriter stringWriter = new StringWriter();
                this.jspBody.invoke(stringWriter);
                String data = stringWriter.toString();
                this.pageContext.getOut().print(data.toUpperCase());
        
            }
        
            @Override
            public JspTag getParent() {
                // TODO Auto-generated method stub
                return null;
            }
        
        
        
            @Override
            public void setParent(JspTag arg0) {
                // TODO Auto-generated method stub
        
            }
        
            
        
            
        
        }
        <!-- <my:toUpperCase / > 转换为大写 -->
        <tag>
            <!-- 确定标签名称 -->
            <name>toUpperCase</name>
            <!-- 确定实现类 -->
            <tag-class>com.yxl.tag.MyToUpperCaseTag</tag-class>
            
            <!-- 格式化当前标签的body内容 * empty:当前标签没有标签体 -->
            <!-- JSP:支持JSP所有的语法,在Tag中使用
            scriptless:对于JSP页面的脚本不支持
            tagdependent:标签体不做处理,原样输出 -->
            <body-content>scriptless</body-content>
            
        </tag>
        <my:toUpperCase>abcd</my:toUpperCase>
        * 需求:循环
        使用extends SimpleTagSupport这种方式实现标签类,SimpleTagSupport已经实现了SimpleTag接口
        三种循环遍历
        <taglib xmlns="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">
        <!-- 确定当前标签库的版本 -->
        <tlib-version>1.0</tlib-version>
        <!-- 建议引入当前便签库是,使用的简写 @taglib prefix="my" -->
        <short-name>my</short-name>
        <!-- 为当前标签库配置文件,起一个名称 * 内容:自定义,全球唯一 -->
        <uri>http://www.yxl.cn/jsp/mytag</uri>
    
    
         <!-- 
        <my:myeach start="0" end="9" step="1" var="ss">
            ${ss} ** <br/>
        </my:myeach>
         -->
         
         <tag>
             <name>myeach</name>
             <tag-class>com.yxl.tag.MyEachTag</tag-class>
             <body-content>scriptless</body-content>
             
             <attribute>
                 <name>start</name>
                 <required>true</required>
                 <rtexprvalue>true</rtexprvalue>
             </attribute>
             <attribute>
                 <name>end</name>
                 <required>true</required>
                 <rtexprvalue>true</rtexprvalue>
             </attribute>
             <attribute>
                 <name>step</name>
                 <required>true</required>
                 <rtexprvalue>true</rtexprvalue>
             </attribute>
             <attribute>
                 <name>var</name>
                 <required>true</required>
                 <rtexprvalue>true</rtexprvalue>
             </attribute>
         </tag>
         
         
         <!-- 
         <my:myList items="${listObj}" var="yyyyy">
            ${yyyyy}  ## <br/>
        </my:myList>
         
          -->
          
          <tag>
              <name>myList</name>
              <tag-class>com.yxl.tag.MyListTag</tag-class>
              <body-content>scriptless</body-content>
          
              <attribute>
                  <name>items</name>
                  <required>true</required>
                  <rtexprvalue>true</rtexprvalue>
              </attribute>
              <attribute>
                  <name>var</name>
                  <required>true</required>
                  <rtexprvalue>true</rtexprvalue>
              </attribute>
          </tag>
          
          
           <tag>
              <name>forEach</name>
              <tag-class>com.yxl.tag.ForEachTag</tag-class>
              <body-content>scriptless</body-content>
          
              <attribute>
                  <name>items</name>
                  <required>true</required>
                  <rtexprvalue>true</rtexprvalue>
              </attribute>
              <attribute>
                  <name>var</name>
                  <required>true</required>
                  <rtexprvalue>true</rtexprvalue>
              </attribute>
          </tag>
        </taglib>
        package com.yxl.tag;
        
        import java.io.IOException;
        
        import javax.servlet.jsp.JspException;
        import javax.servlet.jsp.tagext.SimpleTagSupport;
        
        public class MyEachTag extends SimpleTagSupport{
            
            /*
             * <my:myeach start="0" end="9" step="1" var="ss">
                ${ss} ** <br/>
            </my:myeach>
             */
            
            private Integer start;
            private Integer end;
            private Integer step;
            private String var;
        
            public void setStart(Integer start) {
                this.start = start;
            }
        
            public void setEnd(Integer end) {
                this.end = end;
            }
        
            public void setStep(Integer step) {
                this.step = step;
            }
        
            public void setVar(String var) {
                this.var = var;
            }
        
            public void doTag() throws JspException, IOException {
                //完成功能:将获得的变量信息,输出到浏览器
                
                for(int i = start ; i <= end ; i +=step){
                    //从父类中,获得pagecontext对象
                    this.getJspContext().setAttribute(var, i);
                    //将el表达式的结果发送到浏览器
                    // * el表达式的位置
                    // * 如何发送
                    this.getJspBody().invoke(null);
                    //this.getJspBody().invoke(this.getJspContext().getOut());
                }
                
            }
            
            
            
        
        }
        
        
        
        
        package com.yxl.tag;
    
        import java.io.IOException;
        import java.util.Iterator;
        import java.util.List;
        
        import javax.servlet.jsp.JspException;
        import javax.servlet.jsp.tagext.SimpleTagSupport;
        
        public class MyListTag extends SimpleTagSupport {
        
            /*
            <my:myList items="${listObj}" var="yyyyy">
                ${yyyyy}  ## <br/>
            </my:myList>
             */
            
            private List items;
            private String var;
            public void setItems(List items) {
                this.items = items;
            }
        
            public void setVar(String var) {
                this.var = var;
            }
        
            @Override
            public void doTag() throws JspException, IOException {
                //完成功能:将获得的list信息遍历输出到浏览器
                Iterator it = items.iterator();
                while(it.hasNext()){
                    Object str = it.next();
                    //将结果放置到作用域
                    this.getJspContext().setAttribute(var, str);
                    //将el表达式的结果数据到浏览器
                    this.getJspBody().invoke(null);
                }
            }
            
            
        
        }
            
            
        
        package com.yxl.tag;
    
        import java.io.IOException;
        import java.util.Arrays;
        import java.util.Iterator;
        import java.util.List;
        import java.util.Map;
        
        import javax.servlet.jsp.JspException;
        import javax.servlet.jsp.tagext.SimpleTagSupport;
        
        public class ForEachTag extends SimpleTagSupport {
        
            /*
            <my:myList items="${listObj}" var="yyyyy">
                ${yyyyy}  ## <br/>
            </my:myList>
             */
            
            private Iterator<Object> items;
            private String var;
            public void setItems(Object items) {
                //list
                if(items instanceof List){
                    this.items = ((List)items).iterator();
                }
                //map
                if(items instanceof Map){
                    this.items = ((Map)items).entrySet().iterator();
                }
                //object[]
                if(items instanceof Object[]){
                    this.items = Arrays.asList((Object[])items).iterator();
                }
                
            }
        
            public void setVar(String var) {
                this.var = var;
            }
        
            @Override
            public void doTag() throws JspException, IOException {
                //完成功能:将获得的list信息遍历输出到浏览器
        
                while(items.hasNext()){
                    Object str = items.next();
                    //将结果放置到作用域
                    this.getJspContext().setAttribute(var, str);
                    //将el表达式的结果数据到浏览器
                    this.getJspBody().invoke(null);
                }
            }
            
            
        
        }
        
        
        <my:myeach start="0" end="9" step="1" var="eeee">
            ${eeee} ** <br/>
        </my:myeach>
        <%
        
            List<String> list = new ArrayList<String>();
            list.add("abc");
            list.add("123");
            list.add("wasd");
        
            pageContext.setAttribute("listObj",list);
        %>
        myList<br/>
        <my:myList items="${listObj}" var="yyyyy">
            ${yyyyy}  ## <br/>
        </my:myList>
        
        <my:forEach items="${listObj}" var="mm">
            ${mm} <br/> 
        </my:forEach>
        
        <hr/>
        
        <%
        
            Map<String,String> map = new HashMap<String,String>();
            map.put("11111","11111");
            map.put("22222","222222");
            map.put("33333","33333");
        
            pageContext.setAttribute("mapObj",map);
        
        %>
        遍历Map<br/>
        
        <my:forEach items="${mapObj}" var="map">
            ${map.key} ---- ${map.value} <br/> 
        </my:forEach>
    三、自定义函数
        * 创建类,但方法必须是静态的
        package com.yxl.domain;
    
        public class Calculator {
            private String firstNum;
            private String operator;
            private String secondNum;
            private String result;
            public String getFirstNum() {
                return firstNum;
            }
            public void setFirstNum(String firstNum) {
                this.firstNum = firstNum;
            }
            public String getOperator() {
                return operator;
            }
            public void setOperator(String operator) {
                this.operator = operator;
            }
            public String getSecondNum() {
                return secondNum;
            }
            public void setSecondNum(String secondNum) {
                this.secondNum = secondNum;
            }
            public String getResult() {
                return result;
            }
            public void setResult(String result) {
                this.result = result;
            }
            public Calculator() {
            }
            
            //计算方法
            public static void calculator(Calculator cal){
                
                //通过运算符,将firstNum和secondNum处理的结果,存放到result
            
                
                
                double first = Double.valueOf(cal.firstNum);
                double second = Double.valueOf(cal.secondNum);
                char ope = cal.operator.charAt(0);
                
                switch (ope) {
                    case '+':
                        cal.result = String.valueOf(first + second);
                        break;
                    case '-':
                        cal.result = String.valueOf(first - second);
                        break;
                    case '*':
                        cal.result = String.valueOf(first * second);
                        
                        break;
                    case '/':
                        cal.result = String.valueOf(first / second);
                        break;
            
                    default:
                        throw new RuntimeException("非法操作符");
                }
                
            }
        }
            
        * 书写配置文件tld
            新建myFun.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>myfn</short-name>
                <uri>http://www.yxl.cn/mytag/functions</uri>
                <!-- 确定当前函数 myfn:calculator(cal) -->
                <function>
                    <name>calculator</name>
                    <function-class>com.yxl.domain.Calculator</function-class>
                    <!-- 当前使用函数的声明 public static void calculator(Calculator cal) -->
                    <function-signature>void calculator(com.yxl.domain.Calculator)</function-signature>
                </function>
            
            </taglib>
        * 引用
            * <%@ taglib uri="http://www.yxl.cn/mytag/functions" prefix="myFn" %>
        * 测试
            <jsp:useBean id="cal" class="com.yxl.domain.Calculator"></jsp:useBean>
            <jsp:setProperty property="firstNum" value="1" name="cal"/>
            <jsp:setProperty property="operator" value="+" name="cal"/>
            <jsp:setProperty property="secondNum" value="4" name="cal"/>
            ${myFn:calculator(cal)}
            ${cal.result}
    四、总结
        * 共同点:
            * 需要引入
                * <%@ taglib uri="http://www.yxl.cn/mytag/myeach" prefix="my" %>
            * 都需要配置tld文件
        * 区别:
            * 自定义标签
                * 创建一个类,完成一个功能或一组功能。
                * 可以选择el表达式
            * 自定义函数
                * 创建一个静态方法,完成一个操作。
                * 必须与EL表达式结合使用
                    ${fn:xxxx}
  • 相关阅读:
    Word转pdf
    jquery 中json数组的操作 增删改
    Js、Jquery定时执行(一次或者重复多次,取消重复)
    sql server 2008 (不允许保存更改,您所做的更改要求删除并重新创建以下表) 的解决办法
    C#中 ArrayList 的使用
    Jquery正则表达式公式
    C#判断字符串是否存在字母及字符串中字符的替换实例
    纳闷的EF异常:在提供程序连接上启动事务时出错
    C# WinForm获取当前路径汇总
    Entity Framwork 6 编译出错的问题(VS2012)
  • 原文地址:https://www.cnblogs.com/yxlblogs/p/4158792.html
Copyright © 2020-2023  润新知