使用jsp:include控制动态内容的方法
本文实例讲述了使用jsp:include控制动态内容的方法。分享给大家供大家参考,具体如下:
清单1.JSPinclude伪指令
<![CDATA[ <%@pagelanguage="java"contentType="text/html"%> <html> <head> <title>newInstance.com</title> <metahttp-equiv="Content-Type"content="text/html;charset=iso-8859-1"/> <linkhref="/styles/default.css"rel="stylesheet"type="text/css"/> </head> <body> <%@includefile="header.jsp"%> <%@includefile="navigation.jsp"%> <%@includefile="bookshelf.jsp"%> <%@includefile="/mt-blogs/index.jsp"%> <%@includefile="footer.jsp"%> </body> </html> ]]>
虽然include非常适于将静态内容并入Web页面,但对于动态内容却不尽如人意。我们在前一篇文章中在试图重新装入高速缓存文件时发现了这一问题。与大多数页眉文件及页脚文件不同,动态内容变化频繁,必须时刻更新。我们将首先扼要地重述一下include伪指令的局限性,然后我将向您演示如何用jsp:include标记来扩展JSP的包含能力。
高速缓存问题
JSPinclude伪指令的不足之处有一个是:它会导致Web浏览器高速缓存所有页面。在处理诸如页脚、版权声明或一组静态链接之类的静态组件时,这是有意义的。这些文件不会改变,因此没有理由让JSP解释器不断地重新轮询其中的数据。凡是可能的地方,都应该实现高速缓存,因为它改善了应用程序的性能。
但是,有时侯,进行高速缓存会得不偿失。如果提入的内容来自使用动态数据(如Weblog或数据库驱动的JSP文件)的程序,甚至如果所包含的内容是经常变化的HTML(如时间戳记),那么每当装入Web页面时,都需要显示这些文件或程序的最新版本。遗憾的是,JSPinclude伪指令并不具备这一功能。在测试和开发周期(请参阅侧栏“JSP测试和开发”)中,在浏览器中禁用高速缓存通常能够解决这一问题。但是,对于实际使用的应用程序而言,性能是任何设计决策过程中的一项重要因素,禁用高速缓存并不是一种可行的长远之计。更好的解决方案是使用jsp:include标记。
jsp:include标记
jsp:include只不过是一个不同于include的伪指令而已。jsp:include的优点在于:它总是会检查所含文件中的变化。过一会儿我们将研究这一新标记的工作方式。但首先看一下两种include各自的代码,以便能够看到二者之间的异同。
清单2显示了一个简单页面,它使用了原始的JSPinclude伪指令。
清单2.JSPinclude伪指令
<![CDATA[ <%@pagelanguage="java"contentType="text/html"%> <html> <head> <title>JSPincludeelementtest</title> </head> <body> ThiscontentisstaticallyinthemainJSPfile.<br/> <%@includefile="included.html"%> </body> </html> ]]>
清单3是同一个页面,只不过这里转成使用jsp:include标记。
清单3.转成使用jsp:include
<![CDATA[ <%@pagelanguage="java"contentType="text/html"%> <html> <head> <title>JSPincludeelementtest</title> </head> <body> ThiscontentisstaticallyinthemainJSPfile.<br/> <jsp:includepage="included.html"flush="true"/> </body> </html> ]]>
您应该注意这两种代码类型之间的两大区别。首先,jsp:include元素不使用属于include伪指令的%@语法。实际上,jsp前缀让JSP编译器知道:它应该寻找标准JSP标记集中的元素。其次,指定要包含的文件的属性从file变成了page。如果愿意,可以自己测试一下新标记的结果。只需更改上一篇文章(请参阅参考资料)中included.html文件的内容,然后重新装入浏览器页面,就会立即看到新内容。
jsp:include是如何工作的
如果您有点爱刨根问底,那么可能十分想知道jsp:include标记的行为为什么与include伪指令不同。道理其实十分简单:jsp:include包含的是所包含URI的响应,而不是URI本身。这意味着:对所指出的URI进行解释,因而包含的是生成的响应。如果页面是HTML,那么将得到一点也没有变化的HTML。但是,如果是Perl脚本、Javaservlet或者CGI程序,那么得到的将是从该程序解释而得的结果。虽然页面通常就是HTML,但实际程序恰好是达到目的的手段。而且,由于每次请求页面的时候都会进行解释,因此从来不会象使用include伪指令时那样高速缓存结果。虽然这只是很小的变动,但它却导致了您所见到的行为中的全部差异。
一种混合搭配的解决方案
include伪指令在某些网站上有其用武之地。例如,如果站点包含一些(如果有变化,也很少)几乎没有变化的页眉、页脚和导航文件,那么基本的include伪指令是这些组件的最佳选项。由于include伪指令采用了高速缓存,因此只需放入包含文件一次,其内容就会被高速缓存,其结果会是极大地提高了站点的性能。
然而,对于现在许多Web应用程序或站点而言,地毯式的高速缓存并不能解决问题。虽然页眉和页脚可能是静态的,但是不可能整个站点都是静态的。例如,从数据库提取导航链接是很常见的,并且许多基于JSP技术的站点还从其它站点或应用程序上的动态JSP页面提取内容。如果正在处理动态内容,那么需要采用jsp:include来处理该内容。
当然,最好的解决方案是经常把这两种方法混合搭配使用,将每种构造用到最恰当的地方。清单4是混合搭配包含解决方案的一个示例。
清单4.混合搭配解决方案
<![CDATA[ <%@pagelanguage="java"contentType="text/html"%> <html> <head> <title>newInstance.com</title> <metahttp-equiv="Content-Type"content="text/html;charset=iso-8859-1"/> <linkhref="/styles/default.css"rel="stylesheet"type="text/css"/> </head> <body> <jsp:includepage="header.jsp"flush="true"> <jsp:paramname="pageTitle"value="newInstance.com"/> <jsp:paramname="pageSlogan"value=""/></jsp:include> <%@includefile="/navigation.jsp"%> <jsp:includepage="bookshelf.jsp"flush="true"/> <jsp:includepage="/mt-blogs/index.jsp"flush="true"/> <%@includefile="/footer.jsp"%> </body> </html> ]]>
上面的代码显示了前面文章中的示例索引页面。导航链接和页脚是静态内容,一年最多更改一次。对于这些文件,我使用了include伪指令。内容窗格包含Weblog和“bookshelf”组件,它们是动态生成的。这两个组件需要一直更新,因此对它们,我使用了jsp:include标记。header.jsp文件有点奇怪。这个组件是从另一个本质上是静态的JSP页面提取的。但是,正如您将注意到的那样,它从包含页提取页“标语”,然后将它显示出来。要处理这一共享信息,我们必须向页眉文件传入参数。而要处理那些参数,就必须使用jsp:include元素。
希望本文所述对大家jsp程序设计有所帮助。