jsp 模板继承--rapid (附下载链接)


rapid下载地址:http://www.java2s.com/Code/Jar/r/Downloadrapidcore40jar.htm



    1.为啥要使用

在开发jsp页面时,有很多网页使用的部分页面结构相同,这些相同的页面结构不仅添加时每个页面都要添加,而且如果要修改这些相同的地方都要修改,给开发及维护带来了工作量。

通过面向对象的问题思考问题:如果相同的部分抽离出来,使用继承的关系,基本的有父类定义,子类可以重写父类的变化的内容。父类可以有多个子类,子类只有一个父类,子类可以有很多子类,这样多层次的继承,可以解决以上问题。

对于页面也是一样,如果把相同的部分页面结构抽离成一个父页面,使用到这个页面的子页面就可以继承这个父页面,可以覆盖自己与主页面不同的页面内容,也可以自己定义让子页面的子页面覆写。添加时 只要引入父页面并修改针对自己的内容就行不再关心相同的页面结构。在要修改相同页面结构时只要修改父页面内容,其下面引用的子孙页面都会得到相应的更新。

2.寻找答案

下面介绍一下用的到这种技术:rapid中的一种功能 原理和上面说的差不多 

3.使用rapid

 我主要用在了jsp页面中,所以只介绍下在jsp中的使用 所需要引入的jar 包:rapid-core-4.0.jar

因为这个功能主要在jsp页面中使用的,所以使用的标签库方式来实现的,因此先在jsp中引用标签库

<%@taglib uri="http://www.rapid-framework.org.cn/rapid" prefix="rapid" %>

主要页面:base.jsp child.jsp grandChildA.jsp grandChildB.jsp

先来看base.jsp即父页面 ,页面中使用了rapid:block定义了四个可以让子页面重写的内容块 head top content footer

[html]  view plain  copy
  1. <%@ page language="java" contentType="text/html; charset=UTF-8"  
  2.     pageEncoding="UTF-8"%>  
  3. <%@taglib uri="http://www.rapid-framework.org.cn/rapid" prefix="rapid" %>  
  4. <%@taglib uri="http://java.sun.com/jstl/core" prefix="c" %>  
  5. >  
  6. <html>  
  7. <head>  
  8.     <rapid:block name="head">  
  9.     <title>base headtitle>  
  10.     rapid:block>  
  11. head>  
  12. <body>  
  13.     <rapid:block name="top">  
  14.             base top  
  15.     rapid:block>  
  16.     <rapid:block name="content">  
  17.             base content  
  18.     rapid:block>  
  19.     <rapid:block name="footer">  
  20.             base footer  
  21.     rapid:block>  
  22. body>  
  23. html>  
base.jsp生成后的页面:

[html]  view plain  copy
  1. >  
  2. <html>  
  3. <head>  
  4.     <title>base headtitle>  
  5. head>  
  6. <body>  
  7.     base top  
  8.         base content  
  9.     base footer  
  10. body>  
  11. html>  
下面是child.jsp这里面使用include引用了base.jsp,这样代表了直接使用了base.jsp页面,又使用rapid:override重写了header和content,并在content创建了一个mychild内容块

[html]  view plain  copy
  1. <%@ page language="java" contentType="text/html; charset=UTF-8"  
  2.     pageEncoding="UTF-8"%>  
  3. <%@taglib uri="http://www.rapid-framework.org.cn/rapid" prefix="rapid" %>  
  4.     <rapid:override name="head">  
  5.         <title>child headtitle>     
  6.     rapid:override>  
  7.     <rapid:override name="content">  
  8.         child content  
  9.         <rapid:block name="mychild">  
  10.             child mychild  
  11.         rapid:block>  
  12.     rapid:override>  
  13. <%@include file="base.jsp" %>  
[html]  view plain  copy
  1. child.jsp生成后的页面  
[html]  view plain  copy
  1. >  
  2. <html>  
  3. <head>  
  4. <span style="white-space:pre">    span><title>child headtitle>    
  5. head>  
  6. <body>  
  7. <span style="white-space:pre">    span>base top  
  8.     child content  
  9. <span style="white-space:pre">    span>base footer  
  10. body>  
  11. html>  
grandChildA.jsp grandChildB.jsp使用了多层错乱使用的例子:

grandChildA.jsp

[html]  view plain  copy
  1. <%@ page language="java" contentType="text/html; charset=UTF-8"  
  2.     pageEncoding="UTF-8"%>  
  3. <%@taglib uri="http://www.rapid-framework.org.cn/rapid" prefix="rapid" %>  
  4.     <rapid:override name="top">  
  5.         grandChildA top  
  6.     rapid:override>  
  7.     <rapid:override name="footer">  
  8.         grandChildA footer  
  9.     rapid:override>  
  10. <%@include file="base.jsp"%>  

grandChildA生成的页面:

[html]  view plain  copy
  1. >  
  2. <html>  
  3. <head>  
  4.     <title>base headtitle>  
  5.       
  6. head>  
  7. <body>  
  8.     grandChildA top  
  9.     base content  
  10. <span style="white-space:pre">    span>grandChildA footer  
  11. body>  
  12. html>  
grandChildB.jsp
[html]  view plain  copy
  1. <%@ page language="java" contentType="text/html; charset=UTF-8"  
  2.     pageEncoding="UTF-8"%>  
  3. <%@taglib uri="http://www.rapid-framework.org.cn/rapid" prefix="rapid" %>  
  4.     <rapid:override name="top">  
  5.         grandChildB top  
  6.     rapid:override>  
  7.     <rapid:override name="mychild">  
  8.         grandChildB mychild  
  9.     rapid:override>  
  10.     <rapid:override name="footer">  
  11.         grandChildB footer  
  12.     rapid:override>  
  13. <%@include file="child.jsp"%>  

grandChildB.jsp生成的页面

[html]  view plain  copy
  1. >  
  2. <html>  
  3. <head>  
  4.     <title>child headtitle>     
  5. head>  
  6. <body>   
[html]  view plain  copy
  1. <span style="white-space:pre">    span>grandChildB top  
  2.     child content  
  3.     grandChildB mychild  
  4.     grandChildB footer  
  5. body>  
  6. html>  
通过灵活多变的使用可以达到各种复用的效果。

4.源码理解

看下源码中标签库中的定义吧:

[html]  view plain  copy
  1. xml version="1.0" encoding="UTF-8" ?>  
  2.   
  3. <taglib xmlns="http://java.sun.com/xml/ns/j2ee"  
  4.     xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"  
  5.     xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee web-jsptaglibrary_2_0.xsd"  
  6.     version="2.0">  
  7.       
  8.   <description>rapid-framework tag librarydescription>  
  9.   <display-name>rapid-framework tagdisplay-name>  
  10.   <tlib-version>1.0tlib-version>  
  11.   <short-name>rapidshort-name>  
  12.   <uri>http://www.rapid-framework.org.cn/rapiduri>  
  13.   
  14.   <tag>  
  15.     <description>  
  16.         block tag  
  17.     description>  
  18.     <name>blockname>  
  19.     <tag-class>cn.org.rapid_framework.web.tags.BlockTagtag-class>  
  20.     <body-content>JSPbody-content>  
  21.   
  22.     <attribute>  
  23.         <description>  
  24.             block name  
  25.         description>  
  26.         <name>namename>  
  27.         <required>truerequired>  
  28.         <rtexprvalue>truertexprvalue>  
  29.     attribute>  
  30.   tag>  
  31.   
  32.   <tag>  
  33.     <description>  
  34.         override desc  
  35.     description>  
  36.     <name>overridename>  
  37.     <tag-class>cn.org.rapid_framework.web.tags.OverrideTagtag-class>  
  38.     <body-content>JSPbody-content>  
  39.   
  40.     <attribute>  
  41.         <description>  
  42.             override name, must be equals block name for override  
  43.         description>  
  44.         <name>namename>  
  45.         <required>truerequired>  
  46.         <rtexprvalue>truertexprvalue>  
  47.     attribute>  
  48.   tag>  
  49.   
  50. taglib>  
这里主要有两个tag:  block 和override

block:  有个name属性,如果使用的页面修改了name在pageContent中的内容值,则使用重新定义的内容,否则不改变。

override: 会将标签中的内容保存为pageContent中的name对应的一个变量,名称为:__jsp_override__name
       代码如下:

[java]  view plain  copy
  1. package cn.org.rapid_framework.web.tags;  
  2.   
  3. import java.io.IOException;  
  4.   
  5. import javax.servlet.jsp.JspException;  
  6. import javax.servlet.jsp.tagext.TagSupport;  
  7. /** 
  8.  *  
  9.  * @author badqiu 
  10.  * 
  11.  */  
  12. public class BlockTag extends TagSupport{  
  13.   
  14.     private static final long serialVersionUID = -8246166191638588615L;  
  15.       
  16.     private String name;  
  17.       
  18.     public void setName(String name) {  
  19.         this.name = name;  
  20.     }  
  21.   
  22.     /** 
  23.      * @return EVAL_BODY_INCLUDE or EVAL_BODY_BUFFERED or SKIP_BODY 
  24.      */  
  25.     @Override  
  26.     public int doStartTag() throws JspException {  
  27.         return getOverriedContent() == null ? EVAL_BODY_INCLUDE : SKIP_BODY;  
  28.     }  
  29.   
  30.     /** 
  31.      * @return EVAL_PAGE or SKIP_PAGE 
  32.      */  
  33.     @Override  
  34.     public int doEndTag() throws JspException {  
  35.         String overriedContent = getOverriedContent();  
  36.         if(overriedContent == null) {  
  37.             return EVAL_PAGE;  
  38.         }  
  39.           
  40.         try {  
  41.             pageContext.getOut().write(overriedContent);  
  42.         } catch (IOException e) {  
  43.             throw new JspException("write overridedContent occer IOException,block name:"+name,e);  
  44.         }  
  45.         return EVAL_PAGE;  
  46.     }  
  47.       
  48.     private String getOverriedContent() {  
  49.         String varName = Utils.getOverrideVariableName(name);  
  50.         return (String)pageContext.getRequest().getAttribute(varName);  
  51.     }  
  52. }  
[java]  view plain  copy
  1. package cn.org.rapid_framework.web.tags;  
  2.   
  3. import javax.servlet.jsp.JspException;  
  4. import javax.servlet.jsp.tagext.BodyContent;  
  5. import javax.servlet.jsp.tagext.BodyTagSupport;  
  6. /** 
  7.  * @author badqiu 
  8.  */  
  9. public class OverrideTag extends BodyTagSupport{  
  10.     private static final long serialVersionUID = -8379959647039117369L;  
  11.       
  12.     private String name;  
  13.       
  14.     public void setName(String name) {  
  15.         this.name = name;  
  16.     }  
  17.   
  18.     @Override  
  19.     public int doStartTag() throws JspException {  
  20.         return isOverrided() ? SKIP_BODY : EVAL_BODY_BUFFERED;  
  21.     }  
  22.   
  23.     @Override  
  24.     public int doEndTag() throws JspException {  
  25.         if(isOverrided()) {  
  26.             return EVAL_PAGE;  
  27.         }  
  28.         BodyContent b = getBodyContent();  
  29. //      System.out.println("Override.content:"+b.getString());  
  30.         String varName = Utils.getOverrideVariableName(name);  
  31.   
  32.         pageContext.getRequest().setAttribute(varName, b.getString());  
  33.         return EVAL_PAGE;  
  34.     }  
  35.   
  36.     private boolean isOverrided() {  
  37.         String varName = Utils.getOverrideVariableName(name);  
  38.         return pageContext.getRequest().getAttribute(varName) != null;  
  39.     }  
  40.       
  41. }  

[java]  view plain  copy
  1. package cn.org.rapid_framework.web.tags;  
  2.   
  3. /** 
  4.  * @author badqiu 
  5.  */  
  6. class Utils {  
  7.       
  8.     public static String BLOCK = "__jsp_override__";  
  9.       
  10.     static String getOverrideVariableName(String name) {  
  11.         return BLOCK + name;  
  12.     }  
  13.       
  14.       
  15. }  

你可能感兴趣的:(Jsp)