zoukankan      html  css  js  c++  java
  • 08.十分钟学会JSP传统标签编程

    一、认识标签

    1,说明:传统标签编程在开发中基本用不到,学习标签编程主要还是为了完善知识体系。

    2,标签的主要作用:移除或减少jsp中的java代码

    3,标签的主要组成部分及运行原理

    4,简单标签示例:继承javax.servlet.jsp.tagext.TagSupport

    标签开发步骤

    4.1编写一个继承TagSupport(或实现Tag接口)的类

    package com.chen.ying;
    
    import java.io.IOException;
    
    import javax.servlet.http.HttpServletRequest;
    
    import javax.servlet.jsp.JspException;
    
    import javax.servlet.jsp.JspWriter;
    
    import javax.servlet.jsp.tagext.TagSupport;
    
    public class FirstTag extends TagSupport {
    
    public int doStartTag()throws JspException{
    
         System.out.println("调用doStartTag方法");
    
         HttpServletRequest req=(HttpServletRequest)pageContext.getRequest();
    
         JspWriter out=pageContext.getOut();
    
         String ip=req.getRemoteAddr();//通过request对象取得ip地址
    
         try {
    
             out.write(ip);//输出时有可能会抛出异常
    
         } catch (IOException e) {
    
             e.printStackTrace();
    
         }
    
         return TagSupport.SKIP_BODY;//表示跳过标签体
    
    }
    
    }

    4.2在WEB-INF目录下新建*.tld文件,用于表示标签库,在*.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">
    
          <!-- description用来添加对taglib(标签库)的描述 -->
    
         <description>陈程编程开发的自定义标签库</description>
    
          <!--taglib(标签库)的版本号 -->
    
         <tlib-version>1.0</tlib-version>
    
         <short-name>GaclTagLibrary</short-name>
    
         <!--
    
             为自定义标签库设置一个uri用于表示标签库,uri以/开头,/后面的内容随便写,如这里的/chen ,
    
             在Jsp页面中引用标签库时,需要通过uri找到标签库
    
             在Jsp页面中就要这样引入标签库:<%@taglib uri="/chen" prefix="anyword"%>
    
         -->
    
         <uri>/chen</uri>
    
        
    
         <!--一个taglib(标签库)中包含多个自定义标签,每一个自定义标签使用一个tag标记来描述  -->
    
         <!-- 一个tag标记对应一个自定义标签 -->
    
          <tag>
    
             <description>这个标签的作用是用来输出客户端的IP地址</description>
    
             <!--
    
                 为标签处理器类配一个标签名,在Jsp页面中使用标签时是通过标签名来找到要调用的标签处理器类
    
                 通过IP就能找到对应的com.chen.ying.FirstTag类
    
              -->
    
             <name>IP</name>
    
             <!-- 标签对应的处理器类-->
    
             <tag-class>com.chen.ying.FirstTag</tag-class>
    
             <body-content>empty</body-content>
    
         </tag>
    
        
    
     </taglib>
    
     

    4.3在jsp页面中使用自定义标签

    使用<%@taglib uri=”标签库的uri”  prefix=”标签的使用前缀”%>来引入要使用的标签库,前缀可任意设置

     

    显示结果

    每次调用<haha:IP>标签时,都会触发doStartTag()方法

    从上面代码可以看到,使用标签可以移除jsp中的java代码

    二、定义有属性的标签

    1,  要求

     

    2,  完成一个日期格式化显示的操作,即根据用户输入的日期格式化模板显示日期。

    2.1编写标签类

    package com.chen.ying;
    
    import java.io.IOException;
    
    import java.text.SimpleDateFormat;
    
    import java.util.Date;
    
    import javax.servlet.jsp.JspException;
    
    import javax.servlet.jsp.tagext.TagSupport;
    
    public class DataTag extends TagSupport {
    
        private String format;
    
        public int doStartTag()throws JspException{
    
           SimpleDateFormat sdf=new SimpleDateFormat(this.format);//设置日期格式
    
           try {
    
               pageContext.getOut().write(sdf.format(new Date()));//用指定格式显示日期
    
           } catch (IOException e) {
    
               e.printStackTrace();
    
           }
    
           return TagSupport.SKIP_BODY;
    
        }
    
        public String getFormat() {
    
           return format;
    
        }
    
        public void setFormat(String format) {//在标签中通过反射机制设置
    
           this.format = format;
    
        }
    
    }

    2.2在标签库中配置标签

     

    2.3在jsp使用标签

     

    3,  小结

     

    三、TagSupport类

    1,  要求

     

    2,  TagSupport主要属性及方法

     

         Int doStartTag()

        

         int doAfterBody()

        

         int doEndTag()

        

         3,Tag接口执行流程

        

    4,含标签体的标签:判断某个属性范围内是否存在指定的属性名称的属性

    4.1编写标签处理器类

    package com.chen.ying;
    
    import javax.servlet.jsp.JspException;
    
    import javax.servlet.jsp.tagext.TagSupport;
    
    public class AttributeTag extends TagSupport {
    
    private String name;//接收属性的名称
    
    private String scope;//接收属性的范围
    
    public int doStartTag()throws JspException{
    
         Object value=null;
    
         if("page".equals(this.scope)){//是否是page属性范围
    
             value=pageContext.getAttribute(this.name,pageContext.PAGE_SCOPE);
    
         }
    
         if("request".equals(this.scope)){//是否是request属性范围
    
             value=pageContext.getAttribute(this.name,pageContext.REQUEST_SCOPE);
    
         }
    
         if("session".equals(this.scope)){//是否是session属性范围
    
             value=pageContext.getAttribute(this.name,pageContext.SESSION_SCOPE);
    
         }
    
         if("application".equals(this.scope)){//是否是属性范围
    
             value=pageContext.getAttribute(this.name,pageContext.APPLICATION_SCOPE);
    
         }
    
         if(value==null){//表示没有此属性,不执行标签体
    
             return TagSupport.SKIP_BODY;
    
         }
    
         else{//执行标签体
    
             return TagSupport.EVAL_BODY_INCLUDE;
    
         }  
    
    }
    
    public void setName(String name) {
    
         this.name = name;
    
    }
    
    public void setScope(String scope) {
    
         this.scope = scope;
    
    }
    
     
    
    }

    4.2在标签库中配置标签

     

    4.3在jsp中使用标签‘

     

     是否执行标签体,由返回值决定

    5,小结

     

    四、迭代标签

    1,  要求

     

    在MVC模式中强调,在一个JSP文件中最好不要出现script代码,因为这样会破坏程序的结构,维护起来非常麻烦,JSP文件就只是用来接收、判断与输出的。现在要在JSP中完成集合的输出,为了不出现script代码,可以用迭代标签

    2,  迭代标签开发步骤

    2.1编写标签处理类

    public class IteratorTag extends TagSupport {
    
        private String name;
    
        private String scope;
    
        private String id;//指定保存集合中的每个元素的属性名称
    
        private Iterator<?> iter=null;
    
        public int doStartTag()throws JspException{
    
            Object value=null;
    
            if("page".equals(this.scope)){//是否是page属性范围
    
                value=pageContext.getAttribute(this.name,pageContext.PAGE_SCOPE);
    
            }
    
            if("request".equals(this.scope)){//是否是request属性范围
    
                value=pageContext.getAttribute(this.name,pageContext.REQUEST_SCOPE);
    
            }
    
            if("session".equals(this.scope)){//是否是session属性范围
    
                value=pageContext.getAttribute(this.name,pageContext.SESSION_SCOPE);
    
            }
    
            if("application".equals(this. Scope)){//是否是属性范围
    
                value=pageContext.getAttribute(this.name,pageContext.APPLICATION_SCOPE);
    
            }
    
            if(value!=null&&value instanceof List<?>){//有此属性且为List类型
    
                this.iter=((List<?>)value).iterator();
    
                if(iter.hasNext()){
    
                    pageContext.setAttribute(this.id,iter.next());
    
                    //将集合元素保存在指定属性名的属性范围中
    
                    return TagSupport.EVAL_BODY_INCLUDE;//执行标签体,通过id属性名输出集合元素
    
                }
    
                else{
    
                    return TagSupport.SKIP_BODY;
    
                }
    
            }
    
            else{
    
                return TagSupport.SKIP_BODY;
    
            }  
    
        }
    
        public int doAfterBody()throws JspException{
    
            if(iter.hasNext()){
    
                pageContext.setAttribute(this.id,iter.next());
    
                //将集合元素保存在属性范围中,属性名在jsp中指定
    
                return TagSupport.EVAL_BODY_AGAIN;//如果还有元素,交给doAfterBody()处理
    
            }
    
            else{
    
                return TagSupport.SKIP_BODY;
    
            }
    
        }
    
        public void setName(String name) {
    
            this.name = name;
    
        }
    
        public void setScope(String scope) {
    
            this.scope = scope;
    
        }
    
        public void setId(String id) {
    
            this.id = id;
    
        }  
    
    }

    注意,如果是要执行一次标签体则在doStartTag()中返回EVAL_BODY_INCLUDE,如果是要多次执行标签体,则在doAfterBody()中返回EVAL_BODY_AGAIN;

    2.2在标签库中配置标签处理类

     
        

    有时候tomcat会出现如下错误

    Unable to find setter method for ***

    只要在对应属性配置处添加<type>属性类型</type>即可解决

     

    2.3在jsp中使用标签

     

    id用于指定list中每个元素保存在属性范围中的属性名,以方便用表达式语言输出

    2.4结果

     

    3,  小结

    通过标签操作对象,可分为以下步骤:首先在servlet中将对象保存在属性范围内,然后:1,确定标签的属性有哪些,如要操作对象属性的名称,范围等2,通过对象属性得到对象,然后处理对象,可将处理后的结果保存在指定属性名的属性范围内,然后在标签体中显示处理结果,如上述id=”person”.

    五、 BodyTagSupport类

    1, 要求

     

    2, 定义

     

    3, 主要扩充方法

     

    4, BodyContent类

     

    5, BodyTag接口的执行流程

     

    6,TagExtraInfo类和VariableInfo类

     

    TagExtraInfo类的主要方法

     

    VariableInfo类的主要方法

     

    7,小结

    以上都是传统标签开发,在实际开发中并不常用,下面的简单标签才是重点

     

  • 相关阅读:
    vscode 整理————开篇之力(一)
    重学c#系列——datetime 和 datetimeoffset[二十一]
    重新点亮shell————什么是shell[一]
    重新整理 .net core 实践篇——— 权限中间件源码阅读[四十六]
    为什么构建容器需要Namespace?
    基于Windows Mobile 5.0的掌上天气预报设计
    使用.NE平台调用服务访问非托管 DLL 中的函数
    .NET Framework 3.0 RC1 开发环境构建
    ASP.NET未处理异常的处理
    基于Silverlight的Windows Phone 推箱子程序开发
  • 原文地址:https://www.cnblogs.com/chenxd/p/7816075.html
Copyright © 2011-2022 走看看