TA的每日心情  | 开心 2021-3-12 23:18 | 
|---|
 
  签到天数: 2 天 [LV.1]初来乍到  
 | 
 
| 
 
 1.介绍 
     
  
     
  
     
  
     
  
     
    
     使用过python Django模板的应该清楚,django里面有一个激动人心的功能就是模板可以使用类的继承关系。 即模板是可以继承的,并且不限继承的层次。 
     
    
    如 
     
    
    1. child.HTML extends base.html 
     
    
    2. grandchild.html extends child.html 
     
    
    这样,我们在base.html中定义好html布局,然后在“子类”(我们这样称呼吧)重定义需要父页面内容即可 
     
  
     
  
     
  
     
    
     
  
     
    
    2.jsp继承示例 
     
  
     
  
     
     
     
     现在我们来看jsp中如何实现此功能(django与下面的声明类似)。 
      
  
      
  
      
     
     父页面: base.jsp,定义布局 
      
      
       
        
        
        Jsp代码  
         
        
        
       <%@ taglib uri="http://www.rapid-framework.org.cn/rapid" prefix="rapid" %>    
       <html>    
          <rapid:block name="head">base_head_content</rapid:block>    
       <body>    
          <br />    
          <rapid:block name="content">base_body_content</rapid:block>    
       </body>    
       </html>     
        
       
      
     
       
      
     
     子页面: child.jsp 
      
      
       
        
        
        Jsp代码  
         
        
        
       <%@ taglib uri="http://www.rapid-framework.org.cn/rapid" prefix="rapid" %>    
       <% //重定义父页面的内容为content的内容 %>    
       <rapid:override name="content">    
           child_body_content    
       </rapid:override>    
            
       <!-- extends from base.jsp -->    
       <%@ include file="base.jsp" %>     
        
       
      
     
       
      
      
      
      如上: 我们使用了两个jsp tag: block,override,还有<@include >指令. 
       
  
       
  
       
      
      下面描述各个功能: 
       
       
        
         
        override tag:  会将标签里面的内容保存为pageContext的变量,变量名称为name的属性加前缀,如 __override__$name = tag内容  
        block tag:  根据name属性名称,如果发现__override__$name变量,则显示被重定义的内容,否则显示自身tag的内容.  
        <%@include >指令: 通过该指令来实现继承(extends)的功能(只能使用这个技巧),该指令必须放置在页面的最后面    
         
        
         输出:  
            
            直接访问base.jsp输出: 
             
             
              
               
               
               Html代码  
                
               
               
              <html>    
               base_head_content    
              <body>    
               <br />    
               base_body_content    
              </body>    
              </html>     
               
              
             
            
              
            访问child.jsp输出: 
             
             
              
               
               
               Html代码  
                
               
               
              <html>    
               base_head_content    
              <body>    
               <br />    
               child_body_content    
              </body>    
              </html>     
               
             可以看到,child.jsp的的body输出内容被重定义了. 
             
            
            现该tag可以实现jsp的无限级的继承关系. 即 grandchild.jsp 继承 child.jsp , child.jsp继承 base.jsp  
             
  
             
  
             
  
             
            
             
  
             
            
            3.具体实现方式: 
             
  
             
  
             
  
             
            
            Block Tag: 
             
             
              
               
               
               java代码  
                
               
               
              public class BlockTag extends TagSupport{    
                   
               private String name;    
                   
               public void setName(String name) {    
                this.name = name;    
               }    
                   
               @Override    
               public int doStartTag() throws JspException {    
                return getOverriedContent() == null ? EVAL_BODY_INCLUDE : SKIP_BODY;    
               }    
                   
               @Override    
               public int doEndTag() throws JspException {    
                String overriedContent = getOverriedContent();    
                if(overriedContent == null) {    
                 return EVAL_PAGE;    
                }    
                    
                try {    
                 pageContext.getOut().write(overriedContent);    
                } catch (IOException e) {    
                 throw new JspException("tag output error",e);    
                }    
                return EVAL_PAGE;    
               }    
                   
               private String getOverriedContent() {    
                String varName = Utils.getOverrideVariableName(name);    
                return (String)pageContext.getAttribute(varName);    
               }    
              }     
               
              
             
            
              
            Override Tag: 
             
             
              
               
               
               Java代码  
                
               
               
              public class OverrideTag extends BodyTagSupport{    
                    
               private String name;    
                   
               public void setName(String name) {    
                this.name = name;    
               }    
                   
               @Override    
               public int doStartTag() throws JspException {    
                return isOverrided() ? SKIP_BODY : EVAL_BODY_BUFFERED;    
               }    
                   
               @Override    
               public int doEndTag() throws JspException {    
                if(isOverrided()) {    
                 return EVAL_PAGE;    
                }    
                BodyContent b = getBodyContent();    
                String varName = Utils.getOverrideVariableName(name);    
                pageContext.setAttribute(varName, b.getString());    
                return EVAL_PAGE;    
               }    
                   
               private boolean isOverrided() {    
                String varName = Utils.getOverrideVariableName(name);    
                return pageContext.getAttribute(varName) != null;    
               }    
                    
              }     
               
              
             
            
              
            工具类: 
             
             
              
               
               
               Java代码  
                
               
               
              class Utils {    
               public static String BLOCK = "__override__";    
               public static String getOverrideVariableName(String name) {    
                return BLOCK + name;    
               }    
              }     
               
              
             
            
              
             
          
          
          可以看到,实现代码不需要100行,重要是的实现技巧。 
           
          
         
        
       
      
     
  
     
      
      
        
        
 
         
        
 
         
        
      
     
 
   
 
 
源码下载:http://file.javaxxz.com/2014/10/2/085335875.zip |   
 
 
 
 |