`
Clayz
  • 浏览: 297636 次
  • 性别: Icon_minigender_1
  • 来自: 东京
社区版块
存档分类
最新评论

JSP模板应用指南

    博客分类:
  • Java
阅读更多
Window 工具包提供了一种典型的布局机制,比如说在一个容器中确定部件元素的位置。在AWT 和 Swing都有布局管理器,而在VisualWorks Smalltalk中有wrapper。本文将介绍一种JSP模板机制,它允许布局被封装和重新利用。JSP模板最小化了布局改变所造成的影响,这里我们 将鼓励大家采用封装模块化设计。

尽管 Web开发工具的改进非常迅速,但是它们仍然落后于图形用户界面(GUI)工具包(Swing 和 VisualWorks Smalltalk)。例如,在传统的GUI工具包中提供了布局管理器,在一个窗体或另一个窗体中,允许布局运算被封装和重新利用。本文介绍的这种JSP 模板机制,就象布局管理器一样,可以封装布局,所以它能够被重新利用而不只是复制使用。

由于在布局的发展过程中出现了许多的变化,而对功能的封装是非常重要的一步,它能够被自如修改而做到对其他应用的影响最小。

JSP没有提供对封装布局的直接支持,所以具有统一格式的网页通常可以复制布局代码;例如,在图1中,显示了一个网页,它包含了标题、页脚、工具条以及页面的主要内容。

在图1中显示的网页布局将以HTML表格标签来执行:

例1.包含内容:
xml 代码
 
  1. < html > < head > < title > JSPtemplates </ title > </ head >   
  2. < body   background = 'graphics/background.jpg' >   
  3. < table >   
  4. < tr   valign = 'top' > < td > < %@include  file = 'sidebar.html' % > </ td >   
  5. < td > < table >   
  6. < tr > < td > < %@include  file = 'header.html' % > </ td > </ tr >   
  7. < tr > < td > < %@include  file = 'introduction.html' % > </ td > </ tr >   
  8. < tr > < td > < %@include  file = 'footer.html' % > </ td > </ tr >   
  9. </ table >   
  10. </ td >   
  11. </ tr >   
  12. </ table >   
  13. </ body > </ html >   

在上面的例子中,包括了JSP include 命令,它允许页面内容改变——通过改变包含的文件——无须修改网页自身。不过,由于布局是很难被编码的,布局改变需要对网页进行修改。如果一个网站有多个 相同格式的页面,那么一般情况下甚至简单布局的改变也涉及到整个页面的修改。

为了减少布局改变所造成的影响,我们需要一种仅仅只包含布局的机制;采用这种机制,布局和内容都可以在不修改文件的情况下分开进行修改。这种机制就是JSP模板。

使用模板

模板是一种JSP文件,它包含了参数化了的内容。这里所讨论的模板使用的是一套定制化标签来执行的:template:get,template: put和template:insert。template:get 标签访问参数化的内容,就象在例 2.a中的一样,它将和图 1一样的格式来生成网页。

例 2.a.一个模板
xml 代码
 
  1. < %@taglib  uri = '/WEB-INF/tlds/template.tld'   prefix = 'template'  % >   
  2. < html > < head > < title > < template:get   name = 'title' /> </ title > </ head >   
  3. < body   background = 'graphics/background.jpg' >   
  4. < table >   
  5. < tr   valign = 'top' > < td > < template:get   name = 'sidebar' /> </ td >   
  6. < td > < table >   
  7. < tr > < td > < template:get   name = 'header' /> </ td > </ tr >   
  8. < tr > < td > < template:get   name = 'content' /> </ td > </ tr >   
  9. < tr > < td > < template:get   name = 'footer' /> </ td > </ tr >   
  10. </ table >   
  11. </ td >   
  12. </ tr >   
  13. </ table >   
  14. </ body > </ html >   

例 2.a几乎与例1完全一样,不过在例2.a中我们使用了template:get 取代了例1中的include 命令.让我们来分析一下template:get 如何运行。

template:get 使用了一个专门的名字(在请求的范围内)来对一个Java Bean进行修改。Bean包含了URI (统一资源标志符,网页的一个组件,它包含在template:get中)。例如,在例 2.a的模板列表中,template:get 获得了一个URI——header.html——从一个名为header 的Bean中(在请求的范围内)。接着在template:get 中包含了header.html。

template:put 把Bean放到请求的范围内(此范围将在后面被template:get修改)。 模板包含在template:insert中。 例 2.b中举例说明了put 和 insert 标签的用法:

例 2.b. 从例2.a中使用模板
xml 代码
 
  1. < %@taglib  uri = '/WEB-INF/tlds/template.tld'   prefix = 'template'  % >   
  2. < template:inserttemplate template:inserttemplate = '/articleTemplate.jsp' >   
  3. < template:put   name = 'title'   content = 'Templates'   direct = 'true' />   
  4. < template:put   name = 'header'   content = '/header.html'   />   
  5. < template:put   name = 'sidebar'   content = '/sidebar.jsp'   />   
  6. < template:put   name = 'content'   content = '/introduction.html' />   
  7. < template:put   name = 'footer'   content = '/footer.html'   />   
  8. </ template:  insert >   

在insert 开头标签指定了被包含的模板,在这个例子里,模板在例2.a中。每一个put 标签在请求范围内存储了一个Bean,而在insert 结尾标签包含了模板。模板接着象上面所描述的那样访问Bean。

direct 的属性能够为template:put指定;如果direct 设置为true, 和标签相关联的内容将不包含在template: get中。

一个网站包含了多页相同格式的页面,这样就可以使用一个模板,比如在例 2.a中列出了一个模板,在许多的JSP网页(例2.b)中,都用到了这个模板。

使用模板的另一个好处是可以进行模块化设计。例如,例2.b中列出的JSP 文件中包含了header.html,让我们再来看下面的例2.c。

例2.c. header.html
xml 代码
 
  1. < table >   
  2. < tr >   
  3. < td > < img   src = 'graphics/java.jpg' /> </ td >   
  4. < td > < img   src = 'graphics/templates.jpg' /> </ td >   
  5. </ tr >   
  6. </ table > < hr >   

由于header.html 是被包含的内容,所以它不必在需要显示标头的页面中复制其代码。而且,尽管header.html 是一个HTML文件,但是在文件中并没有使用一般的起始HTML标签(比如<html>或<body>),因为这些标签都将被模 板定义。由于在模板中包含了header.html,这些标签在header.html就可以不必再使用了。

注意:JSP提供了 两种方式来包含内容:静态方式,使用include命令;动态方式,使用include action。include命令包含了目标页面的引用源,这和C语言中的#include和Java中的import相似。include action 包含了在运行时间内目标所产生的响应。

与JSP include action一样,模板包含有动态内容。所以,尽管在例1和例2.b中的JSP网页在功能上是一致的,但是前面包含的静态内容被后面动态的包含了。

可选内容

所有的模板内容都是可选的,模板的内容可以很容易的在更多的网页中使用。例如,在图 2.a和图 2.B中显示了两个页面——登录和清单——它们使用的是同一个模板。两个页面中都包含一个标头、页脚和主要内容。清单页面中有一个编辑Panel (这是登陆页面所缺乏的)用来改变清单。

下面,你会发现模板将被登录和清单页面共用:
xml 代码
 
  1. < %@taglib  uri = 'template.tld'   prefix = 'template'  % >   
  2. ……  
  3. < table   width = '670' >   
  4. < tr > < td   width = '60' > </ td >   
  5. < td > < template:get   name = 'header' /> </ td > </ tr >   
  6. < tr > < td   width = '60' > </ td >   
  7. < td > < template:get   name = 'main-content' /> </ td > </ tr >   
  8. < tr > < td   width = '60' > </ td >   
  9. < td > < template:get   name = 'editPanel' /> </ td > </ tr >   
  10. < tr > < td   width = '60' > </ td >   
  11. < td > < template:get   name = 'footer' /> </ td > </ tr >   
  12. </ table >   
  13. ……  

清单页面使用了上面的模板以及专门用于编辑Panel的内容:
xml 代码
 
  1. < %@taglib  uri = 'template.tld'   prefix = 'template'  % >   
  2. < %@taglib  uri = 'security.tld'   prefix = 'security'  % >   
  3. < template:inserttemplate template:inserttemplate = '/template.jsp' >   
  4. ……  
  5.   
  6. < template:put   name = 'editPanel'   content = '/editPanelContent.jsp' />   
  7. ……  
  8. </ template:insert >   

与上面相对照,登录页面没有专门用于编辑Panel的内容:
xml 代码
 
  1. < %@taglib  uri = 'template.tld'   prefix = 'template'  % >   
  2. < template:inserttemplate template:inserttemplate = '/template.jsp' >   
  3. < template:put   name = 'title'   content = 'Login'   direct = 'true' />   
  4. < template:put   name = 'header'   content = '/header.jsp' />   
  5. < template:put   name = 'main-content'   content = '/login.jsp' />   
  6. < template:put   name = 'footer'   content = '/footer.jsp' />   
  7. </ template:insert >   

由于登录页面中没有专门用于编辑Panel的内容,所以它没有包括。

基于Role的内容

Web应用程序常常会基于不同的用户生成不同的内容。 例如,相同的 JSP模板,只有当用户为管理员的时候才出现编辑Panel,下面是得出的两个不同的页面(如图3.a和3.b.)

在图3.a和3.b中的模板使用了template:get的 role 属性:
xml 代码
 
  1. < %@taglib  uri = 'template.tld'   prefix = 'template'  % >   
  2. ......  
  3. < table >   
  4. ......  
  5. < td > < template:get   name = 'editPanel'   role = 'curator' /> </ td > </ tr >   
  6. ......  
  7. </ table >   
  8. ......  

get 标签仅仅在用户的Role 与Role属性相匹配的时候才包含内容。让我们来看看标签handler是如何使用Role属性的:
java 代码
 
  1. public   class  GettagextendstagSupport {  
  2. private  String name =  null , role =  null ;  
  3. ......  
  4. public   void  setRole(String role) {  this .role = role; }  
  5. ......  
  6. public   int  doStartTag()  throws  JspException {  
  7. ......  
  8. if (param !=  null ) {  
  9. if (roleIsValid()) {  
  10. // include or print content ......   
  11. }  
  12. }  
  13. ......  
  14. }  
  15.   
  16. private   boolean  roleIsValid() {  
  17. return  role ==  null  ||  // valid if role isn't set   
  18. ((javax.Servlet.http.HttpServletRequest)  
  19. pageContext.getRequest()).isUserInRole(role);  
  20. }  


执行模板

这里所讨论的模板将在三种定制标签下执行:

Template: insert

Template: put

Template: get

insert 标签中包含一个模板,但是在包含之前,put 标签存储有一些信息——name, URI和Boolean 值(用来指定将内容是包含还是直接显示)——关于模板所包含的内容。在template:get中包含(或显示)了指定的内容,随后将访问这些信息。

template:put 把Bean 存储在请求区域(但并不直接存储),因为如果两个模板使用了相同的内容名,一个嵌套模板就将覆盖封装模板中的内容。

为了保证每一个模板能够只存取它自己的信息,template:insert 保留了一个hashtable堆栈。每一个insert 开始标签建立一个 hashtable并把它放入堆栈。封装的put 标签建立bean并把它们保存到最近建立的hashtable中。随后,在被包含模板中的 get 标签访问hashtable中的bean。图 4 显示了堆栈是如何被保留的。

在图 4中每一个模板访问正确的页脚、footer.html 和footer_2.html。如果 bean被直接存储在请求区域,图 4中的step 5将覆盖在step 2中指定的footer bean。

模板标签执行

接下来我们将分析三个模板标签的执行: insert, put和get。我们先从图 5开始。这个图表说明了当一个模板被使用时,insert和put标签事件的执行顺序。

如果一个模板堆栈已经不存在,insert 开始标签就会建立一个并把它放置到请求区域。随后一个hashtable也被建立并放到堆栈中。

每一个 put 开始标签建立一个PageParameter bean,并存储在由封装的insert标签建立的hashtable中。

插入 end 标签包含了这个模板。这个模板使用get标签来访问由put标签建立的bean。在模板被处理以后,由insert 开始标签建立的hashtable就从堆栈中清除。

模板标签列表

标签handler很简单。在例 3.a中列出了Insert标签类——标签handler。

例 3.a. InsertTag.java
java 代码
 
  1. packagetags.templates;  
  2. import  java.util.Hashtable;  
  3. import  java.util.Stack;  
  4. import  javax.servlet.jsp.JspException;  
  5. import  javax.servlet.jsp.PageContext;  
  6. import  javax.servlet.jsp.tagext.TagSupport;  
  7. public   class  InserttagextendstagSupport {  
  8.   
  9. private  Stringtemplate;  
  10. private  Stack stack;  
  11. // setter method fortemplate 属性   
  12. public   void  setTemplate(Stringtemplate) {  
  13. this .template =template;  
  14. }  
  15.   
  16. public   int  doStartTag()  throws  JspException {  
  17. stack = getStack(); // obtain a reference to thetemplate stack   
  18. stack.push(new  Hashtable());  // push new hashtable onto stack   
  19. return  EVAL_BODY_INCLUDE;  // pass tagbody through unchanged   
  20. }  
  21.   
  22. public   int  doEndTag()  throws  JspException {  
  23. try  {  
  24. pageContext.include(template); // includetemplate   
  25. }  
  26.   
  27. catch (Exception ex) {  // IOException or ServletException   
  28. throw   new  JspException(ex.getMessage());  // recast exception   
  29. }  
  30.   
  31. stack.pop(); // pop hashtable off stack   
  32. return  EVAL_PAGE;  // evaluate the rest of the page after the tag   
  33. }  
  34.   
  35. // taghandlers should always implement release() because   
  36. // handlers can be reused by the JSP container   
  37.   
  38. public   void  release() {  
  39. template = null ;  
  40. stack = null ;  
  41. }  
  42.   
  43. public  Stack getStack() {  
  44. // try to get stack from request scope   
  45. Stack s = (Stack)pageContext.get属性(  
  46. "template-stack" ,  
  47. PageContext.REQUEST_SCOPE);  
  48. // if the stack's not present, create a new one和   
  49. // put it into request scope   
  50. if (s ==  null ) {  
  51. s = new  Stack();  
  52. pageContext.set属性("template-stack" , s,  
  53. PageContext.REQUEST_SCOPE);  
  54. }  
  55. return  s;  
  56. }  
  57. }  

例 3.b 列出了 Put标签类和标签handler:

例 3.b. PutTag.java
java 代码
 
  1. packagetags.templates;  
  2. import  java.util.Hashtable;  
  3. import  java.util.Stack;  
  4. import  javax.servlet.jsp.JspException;  
  5. import  javax.servlet.jsp.tagext.TagSupport;  
  6. import  beans.templates.PageParameter;  
  7. public   class  PuttagextendstagSupport {  
  8. private  String name, content, direct= "false" ;  
  9. // setter methods for Put tag attributes   
  10. public   void  setName(String s) { name = s; }  
  11. public   void  setContent(String s) {content = s; }  
  12. public   void  setDirect(String s) { direct = s; }  
  13. public   int  doStartTag()  throws  JspException {  
  14. // obtain a reference to enclosing insert tag   
  15. Inserttagparent = (InsertTag)getAncestor("tags.templates.InsertTag" );  
  16. // puttags must be enclosed in an insert tag   
  17. if (parent ==  null )  
  18. throw   new  JspException( "PutTag.doStartTag(): "  +  "No Inserttagancestor" );  
  19. // gettemplate stack from insert tag   
  20. Stacktemplate_stack = parent.getStack();  
  21. //template stack should never be null   
  22. if (template_stack ==  null )  
  23. throw   new  JspException( "PutTag: notemplate stack" );  
  24. // peek at hashtable on the stack   
  25. Hashtable params = (Hashtable)template_stack.peek();  
  26. // hashtable should never be null either   
  27. if (params ==  null )  
  28. throw   new  JspException( "PutTag: no hashtable" );  
  29. // put a new PageParameter in the hashtable   
  30. params.put(name, new  PageParameter(content, direct));  
  31. return  SKIP_BODY;  // not interested in tagbody, if present   
  32. }  
  33.   
  34. // taghandlers should always implement release() because   
  35. // handlers can be reused by the JSP container   
  36. public   void  release() {  
  37. name = content = direct = null ;  
  38. }  
  39.   
  40. // convenience method for finding ancestor names with   
  41. // a specific class name   
  42. privatetagSupport getAncestor(String className) throws  JspException {  
  43. Class klass = null // can't name variable "class"   
  44. try  {  
  45. klass = Class.forName(className);  
  46. }  
  47. catch (ClassNotFoundException ex) {  
  48. throw   new  JspException(ex.getMessage());  
  49. }  
  50. return  (TagSupport)findAncestorWithClass( this , klass);  
  51. }  
  52. }  

PutTag.doStarttag建立了一个 PageParameter bean – 在例 3.c中列出——然后存储到请求区域。

例 3.c. PageParameter.java
java 代码
 
  1. package  beans.templates;  
  2. public   class  PageParameter {  
  3. private  String content, direct;  
  4. public   void  setContent(String s) {content = s; }  
  5. public   void  setDirect(String s) { direct = s; }  
  6. public  String getContent() {  return  content;}  
  7. public   boolean  isDirect() { 
分享到:
评论

相关推荐

    Myeclipse10中修改JSP模板的路径方法

    在使用Myeclipse10进行Web开发时,有时会遇到需要自定义JSP页面模板的情况。默认情况下,Myeclipse内置了一些JSP模板,这些模板通常位于安装目录下的特定位置。然而,在某些场景下,开发者可能希望修改这些模板或者...

    Jsp综合实验模板

    通过这些模板,学习者可以了解到JSP的基本结构,包括`&lt;jsp:include&gt;`、`&lt;jsp:forward&gt;`、`&lt;jsp:useBean&gt;`等指令,以及如何使用脚本元素(scriptlets)编写Java代码来控制页面逻辑。同时,他们还能掌握如何处理请求...

    velocity模板使用指南中文版

    Velocity 模板使用指南中文版 Velocity 是一种流行的模板引擎,广泛应用于Java 和 .Net 平台。它提供了一个灵活、可扩展的模板语言,能够根据需要生成动态内容。本文档是 Velocity 模板使用指南中文版,旨在帮助...

    servlet和jsp学习指南

    - JSP是一种易于使用的模板技术,其文件扩展名通常为.jsp,可以看作是Servlet的一种简化形式,它允许开发者直接在HTML页面中嵌入Java代码。 - 学习JSP页面的结构,包括指令、脚本元素、动作元素和标准动作。 - ...

    JSP2 编程指南:从初学者到专家

    JSP2鼓励使用EL来减少脚本元素,以提高页面的可维护性。 ### JSP2的标签库 JSP2支持自定义标签库,使得开发人员能够创建可重用的组件,这些组件可以像HTML标签一样在页面上使用。例如,Struts2和JSF框架都提供了...

    JSP模板应用指南(上)

    本文将介绍一种JSP模板机制,它允许布局被封装和重新利用。JSP模板最小化了布局改变所造成的影响,这里我们将鼓励大家采用封装模块化设计。 尽管 Web开发工具的改进非常迅速,但是它们仍然落后于图形用户界面(GUI)...

    JSP模板应用指南(下)

    执行模板 这里所讨论的模板将在三种定制标签下... template:put 把Bean 存储在请求区域(但并不直接存储),因为如果两个模板使用了相同的内容名,一个嵌套模板就将覆盖封装模板中的内容。 为了保证每一个模板能够只

    JSP网站模板真正实现自已架设网站

    在构建Web应用时,JSP(JavaServer Pages)是一种广泛使用的服务器端脚本语言,它允许开发者使用HTML或XML语法中嵌入Java代码,从而动态生成网页内容。"JSP网站模板"则是一种预设计的网页布局和样式,用于简化和加速...

    Servlet JSP Spring MVC初学指南(alin书签).pdf

    10. **视图技术**:除了JSP,还可以使用FreeMarker、Thymeleaf等模板引擎作为视图。 在"Servlet JSP Spring MVC初学指南(alin书签).pdf"这本书中,你可能会找到这些知识点的详细讲解,通过整理目录书签,可以更好...

    Velocity 模板使用指南

    当Velocity应用于web开发时,界面设计人员可以和java程序开发人员同步开发一个遵循MVC架构的web站点,也就是说,页面设计人员可以只 关注页面的显示效果,而由java程序开发人员关注业务逻辑编码。Velocity将java...

    JSP2 编程指南:从初学者到专家.rar

    模板文本是JSP页面中的静态内容,而脚本元素包括声明、脚本片段和表达式,分别用于声明变量和方法,编写Java代码,以及直接输出值。 **8. JSP页面设计模式** 了解MVC(Model-View-Controller)设计模式,以及如何...

    JSP2 编程指南:从初学者到专家(CHM)

    - **内置Servlet API**:JSP2将Servlet API内置于JSP引擎中,开发者可以直接在JSP页面中使用Servlet API,无需额外导入。 **3. JSP生命周期** JSP页面经历三个主要阶段:翻译、编译和执行。在翻译阶段,JSP被转换为...

    jsp开发指南(从基础到小项目实践)

    本指南将涵盖从JSP的基本概念、语法特性,到实际项目开发中的应用和技巧,帮助读者全面理解和掌握JSP。 ### 一、JSP基本概念 1. **JSP页面结构**:JSP页面由静态内容(HTML、CSS、JavaScript)和动态元素(Java...

    jsp资料大集成包括了jsp的模版及一系列开发指南

    这份"jsp资料大集成"包含了JSP模板和一系列开发指南,旨在帮助初学者和经验丰富的开发者提升JSP技能。 首先,"04-Request-Headers-Chinese"这部分内容可能涉及到JSP中HTTP请求头的处理。在JSP中,可以通过内置对象`...

    JSP数据库编程指南

    本篇指南将深入探讨如何利用JSP进行数据库编程,帮助你构建数据驱动的Web应用。 1. **JSP基础** - **JSP语法**:JSP由HTML模板和Java代码片段组成,通过`&lt;% %&gt;`或`&lt;jsp:scriptlet&gt;`标签插入Java代码。 - **JSP...

    《JSP2 编程指南:从初学者到专家》

    JSP作为Java Web开发的重要组成部分,它允许开发者使用HTML或者XML模板语言来创建动态网页,同时结合Java代码处理服务器端逻辑。 首先,JSP的基础部分包括JSP页面结构、指令、动作元素和脚本元素。页面结构中,我们...

    java 开发指南_applet和jsp篇

    Java开发指南——Applet与JSP篇主要涵盖了两个核心概念:Java小应用程序(Applet)和Java服务器页面(JSP)。这两个技术都是Java在Web开发中的重要组成部分,它们各自有其独特的作用和应用场景。 首先,Java Applet...

    商店JSP模板

    8. **下载说明.txt**:可能提供了详细的安装和使用指南,帮助用户了解如何导入到MyEclipse这样的开发环境中,以及如何配置和运行项目。 9. **说明.htm**:可能是对模板功能和特点的简单介绍,包括预览效果、主要...

    JSP学习指南,适合所有人群

    **JSP(Java Server Pages)学习指南** JSP(Java Server Pages)是一种动态网页技术,由Sun Microsystems(现已被Oracle公司收购)开发,用于构建基于Java的Web应用程序。它的主要功能是在服务器端处理数据,生成...

Global site tag (gtag.js) - Google Analytics