JSP 2.0下的动态内容缓存分析讲解
来源:matrix
编辑:若水
时间:2008-05-14
...</jc:cache>
JSP 变量易于使用,对于简单的Web apps,这是一个不错的内容缓存方案。然而,如果应用程序产生大量的动态内容,没有对缓存大小的控制无疑是一个问题。一种专用的缓存框架结构能够提供一个更加有力的方案,允许对缓存的监视,限制缓存大小,控制缓存策略,等等……
使用JSP 2.0表达式语言API
JSP容器(例如Tomcat)对应用EL API的JSP页面中的表达式予以赋值,并且可以被Java代码所使用。这允许在Web页面外应用JSP EL作开发,例如,对XML文件、基于文本的资源以及自定义脚本。当需要控制何时对Web页面中的表达式进行赋值或者书写与之相关的表达式时,EL API同样是有用的。例如,缓存页面片段可以包含自定义JSP表达式,并且当每一次缓存内容被输出时,EL API将用来给这些表达式赋值或者重新赋值。
文章提供了一个例子程序(参见文末资源部分),这个应用程序包含了一个Java类(JspUtils)和类中包含一个方法eval(),这个方法有三个参数:JSP表达式、表达式的期望类型和一个JSP context对象。Eval()方法从JSP context中取得ExpressionEvaluator并且调用evaluate()方法,通过表达式、表达式的期望类型、和一个从JSP congtext中获得的变量。JspUtils.eval()方法返回表达式的值。
package com.devsphere.articles.jspcache;
import javax.servlet.jsp.JspContext;
import javax.servlet.jsp.JspException;
import javax.servlet.jsp.PageContext;
import javax.servlet.jsp.el.ELException;
import javax.servlet.jsp.el.ExpressionEvaluator;
import java.io.IOException;public class JspUtils {
public static Object eval(
String expr, Class type, JspContext jspContext)
throws JspException {
try {
if (expr.indexOf("${") == -1)
return expr;
ExpressionEvaluator evaluator
= jspContext.getExpressionEvaluator();
return evaluator.evaluate(expr, type,
jspContext.getVariableResolver(), null);
} catch (ELException e) {
throw new JspException(e);
}
}
...}
注意:JspUtils.eval()主要封装了标准的ExpressionEvaluator。如果expr不包含${,JSP EL API不被调用,因为没有JSP表达式。
JSP标签库需要一个标签库描述符(TLD)文件来自定义标签的命名,它们的属性,以及操作该标签的Java类。jspcache.tld描述了两个自定义标签,<jc:cache>拥有两个属性:缓存页面片段的id和JSP scope—JSP页面总需要被储存的内容范围。<jc:dynamic>只有一个属性,即JSP表达式必须在每一次缓存片段被输出时被赋值。TLD文件将这两个自定义标签映射到CacheTag和DynamicTag类,如下所示:
<?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 web-jsptaglibrary_2_0.xsd"
version="2.0">
<tlib-version>1.0</tlib-version>
<short-name>jc</short-name>
<uri>http://devsphere.com/articles/jspcache</uri>
<tag>
<name>cache</name>
<tag-class>com.devsphere.articles.jspcache.CacheTag</tag-class>
<body-content>scriptless</body-content>
<attribute>
<name>id</name>
<required>true</required>
<rtexprvalue>true</rtexprvalue>
</attribute>
<attribute>
<name>scope</name>
<required>false</required>
<rtexprvalue>false</rtexprvalue>
</attribute>
</tag>
<tag>
<name>dynamic</name>
<tag-class>com.devsphere.articles.jspcache.DynamicTag</tag-class>
<body-content>empty</body-content>
<attribute>
<name>expr</name>
<required>true</required>
<rtexprvalue>false</rtexprvalue>
</attribute>
</tag></taglib>
TLD文件包含在Web应用描述符文件(web.xml)中,这五个文件同样包含一个初始参数指出cache是否可用。
<?xml version="1.0" encoding="ISO-8859-1"?><web-app 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 web-app_2_4.xsd"
version="2.4">
<context-param>
<param-name>com.devsphere.articles.jspcache.enabled</param-name>
<param-value>true</param-value>
</context-param>
<jsp-config>
<taglib>
<taglib-uri>http://devsphere.com/articles/jspcache</taglib-uri>
<taglib-location>/WEB-INF/jspcache.tld</taglib-location>
</taglib>
</jsp-config></web-app>
理解<jc:cache>的工作机理
JSP容器为JSP页面中的每一个<jc:cache>标签创建一个CacheTag实例,来对其处理。JSP容器负责调用setJsp()、setParent()和setJspBody()方法,这是CacheTag类从SimpleTagSupport继承而来。JSP容器同事还为所操作标签的每一个属性调用setter方法。SetId()和setScope()方法存储属性值到私有域,这个值已经用CacheTag()构造函数用缺省值初始化。
0
最新评论共有 0 位网友发表了评论
查看所有评论
发表评论
热点关注
相关文章


