有许多页面的一部分或者这个页面是很少更新的,他们通常是由外部文件来生成这个部分。所以我们可以把这部分内容cache住,当有新的请求时,我们就response cache,这样可以减少服务器的负担,还可以提高性能。其中oscache已经可以实现页面的cache和页面部分cache。oscache使用jsp tags来实现局部cache的。拿到Tapestry中肯定是行不通的。在同事的提醒下,想到写这个Tapestry的cache组件来达到重用的目的。
说干就干,先在头脑中想好要怎样使用cache(页面上的布局)。ok。 我想好了。
//Cache body, which is the content you want to cache.
这里有2个参数,updateCondition 当为true时,我们就绕过cache, cacheProvider 我把他定义为一个接口,这样用户可以把cache存在任何地方。而且提供这样的一个接口,用户可以更好的操作cache。先看看jwc对cache组件的定义。
<!---->
"-//Apache Software Foundation//Tapestry Specification 4.0//EN"
"http://jakarta.apache.org/tapestry/dtd/Tapestry_4_0.dtd">
<component-specification allow-body="yes" allow-informal-parameters="no" class="com.live.spaces.dengyin2000.tapestry.tfancomponents.components.Cache">
<description>
Cache component, this component can inclue any content as its body, and cache its body.
This is useful in rarely updated content.
</description>
<parameter name="updateCondition" required="no" default-value="false">
<description>
The flag that need to refresh cache, it would casue tapestry render not use the cache.
</description>
</parameter>
<parameter name="cacheProvider" required="yes">
<description>
You need to provider an cache provider to store its body content. for some simply use.
Please see @com.live.spaces.dengyin2000.tapestry.tfancomponents.components.SimpleHtmlSourceCacheProvider
</description>
</parameter>
</component-specification>
下面的是ICacheProvider接口
public interface ICacheProvider {
/**
*
* @param cacheKey
* @param cacheContent
*/
public void storeCache(String cacheKey, String cacheContent);
/**
*
* @param cacheKey
* @return
*/
public String getCacheContent(String cacheKey);
/**
* This method provider to user, so that user can controll cache manaully.
* @param cacheKey
*/
public void removeCache(String cacheKey);
/**
* This method provider to user, so that user can controll cache manaully.
* Clear all caches
*
*/
public void reset();
}
ok。 再来看看Cache组件的代码。
public abstract class Cache extends AbstractComponent {
protected static final Log logger = LogFactory.getLog(Cache.class);
public abstract boolean getUpdateCondition();
public abstract ICacheProvider getCacheProvider();
@Override
protected void renderComponent(IMarkupWriter writer, IRequestCycle cycle) {
if (getUpdateCondition()){
renderComponentWithCache(writer, cycle);
}else{
if (getCacheProvider().getCacheContent(this.getIdPath()) != null){
//response cache html content.
writer.printRaw(getCacheProvider().getCacheContent(this.getIdPath()));
}else{
renderComponentWithCache(writer, cycle);
}
}
}
private void renderComponentWithCache(IMarkupWriter writer, IRequestCycle cycle) {
logger.debug("We need to refresh cache now.");
CacheWriterWrapper cacheWrapper =new CacheWriterWrapper();
super.renderBody(buildCacheMarkupWriter(cacheWrapper.getPrintWriter(), writer), cycle);
String cacheContent = cacheWrapper.getCacheContent();
logger.debug("fetched cache content, ready to put it into cache.");
getCacheProvider().storeCache(this.getIdPath(), cacheContent);
// response html content.
writer.printRaw(cacheContent);
}
private IMarkupWriter buildCacheMarkupWriter(PrintWriter writer, IMarkupWriter sourceWriter){
return this.getPage().getRequestCycle().getInfrastructure().getMarkupWriterSource().newMarkupWriter(writer, new ContentType(sourceWriter.getContentType()));
}
class CacheWriterWrapper{
private StringWriter sw;
private PrintWriter pw;
public CacheWriterWrapper() {
sw = new StringWriter();
pw = new PrintWriter(sw);
}
public String getCacheContent(){
return sw.getBuffer().toString();
}
public PrintWriter getPrintWriter(){
return pw;
}
}
}
主要是得到cache组件body的内容,然后把body的内容cache住,下次的话就response Cache的内容。 其实也是满简单的。
我自己还写了一个简单CacheProvider。
public class SimpleHtmlSourceCacheProvider implements ICacheProvider {
private Map<string, string=""> cache = new HashMap<string, string="">();
public String getCacheContent(String cacheKey) {
return cache.get(cacheKey);
}
public void storeCache(String cacheKey, String cacheContent) {
cache.put(cacheKey, cacheContent);
}
public void removeCache(String cacheKey) {
cache.remove(cacheKey);
}
public void reset() {
cache.clear();
}
}
在使用中你可以把CacheProvider放到Global或者Visit对象中。注意要使用同一个CacheProvider。
我在google code host上面建了一个probject地址是http://code.google.com/p/tfancomponents/ 有兴趣的同学可以看看, 这是一个maven项目。
分享到:
相关推荐
在 Tapestry 5 框架中,自定义组件是扩展其功能的关键方式,它允许开发者根据特定需求创建个性化和可重用的 UI 元素。Tapestry 5 是一个强大的 Java Web 应用程序开发框架,它强调组件化、模块化以及声明式编程模型...
在本篇文章中,我们将深入探讨Tapestry的页面编辑组件,以及如何利用这些组件创建交互式的用户界面,包括文本框、单选框、多选框和下拉框。 首先,让我们理解什么是Tapestry页面编辑组件。在Tapestry中,组件是可...
本文将深入探讨Tapestry 4.02版本中对ExtJS的GridPanel组件进行封装的相关知识点。 首先,Tapestry是一个基于Java的开源Web应用框架,它提供了组件化开发的方式,使得开发者可以构建出结构清晰、可维护性强的大型...
介绍Tapestry组件的使用和功能。内容还行,使用初学者入门。
Tapestry是一款强大的Java Web应用程序框架,由Apache软件基金会维护,它提供了一种基于组件的模型来构建动态、数据驱动的Web应用。本教程将帮助初学者了解Tapestry的基本概念,带你逐步入门并掌握其核心组件的使用...
tapestry部分组件绑定参数的列表!
Tapestry是一款强大的Java Web应用程序框架,由Apache软件基金会维护,它强调了组件化、模块化和可重用性,使得开发复杂的Web应用变得更加简单。本文将深入介绍Tapestry 4的相关知识点。 1. **组件化编程**: ...
Tapestry的组件化设计使得开发人员可以快速构建动态、响应式的用户界面,如在描述中提到的`form`组件和`table`组件。`form`组件用于处理用户输入,创建表单并进行验证,而`table`组件则用于展示数据,支持分页和排序...
2. **组件实例化**:根据页面和组件定义,Tapestry 创建必要的组件实例。 3. **状态管理**:Tapestry 自动处理组件状态的保存和恢复,确保在多个请求间保持一致性。 4. **渲染**:Tapestry 将组件渲染成HTML响应,...
Tapestry是一个基于Java的Web应用框架,它采用了面向组件的开发方式,这使得它与其他如Structs、WebWork、SpringMVC等采用传统面向元素开发方式的框架有所不同。面向组件的开发模式旨在克服面向元素开发中的局限性,...
1. **Tapestry Core**: 这是Tapestry框架的基础部分,包含了核心组件、服务容器(Tapestry IoC)和页面生命周期管理。通过源码分析,我们可以理解其如何实现页面组件的渲染、事件处理和依赖注入。 2. **Tapestry ...
Tapestry API提供了`Component`接口和相关的实现类,例如`Page`和`ComponentTemplate`,用于构建这些组件。 2. **MVC架构** 在Tapestry中,模型、视图和控制器的概念得到了清晰的体现。`Model`代表数据和业务逻辑...
Tapestry是一个基于Java的全栈Web应用程序框架,它的设计目的是为了简化Web应用开发,提供组件化和高度交互性的页面。Tapestry并不是一个应用服务器,而是一个可以在应用服务器中运行的框架,用于构建动态、复杂的...
1. **页面和组件的生命周期**:每个Tapestry 3应用由一系列页面组成,页面又包含多个组件。Tapestry管理这些页面和组件的创建、初始化、渲染和销毁过程。 2. **模板和元数据**:Tapestry使用HTML模板定义页面布局,...
Tapestry是一个强大的Java web应用程序框架,由Apache软件基金会维护,它允许开发者通过组合可重用的组件来构建动态、数据驱动的Web页面。Tapestry 3.0是该框架的一个早期版本,尽管现在可能已被更现代的版本如...
5) **配置URL映射**:Tapestry4通过元数据来处理URL到页面和组件的映射。在模块配置文件中定义这些元数据。 6) **运行和测试**:配置好项目后,使用Eclipse或MyEclipse的内置服务器启动应用,然后通过浏览器访问你...
Tapestry4.1.2 版本基于Servlet技术,构建在request-response模式之上,它将复杂的HTTP交互隐藏在幕后,使得开发者能够专注于业务逻辑和用户界面的创建。这种抽象让开发人员可以像构建桌面应用一样,通过组合可重用...
2)Tapestry 各种核心组件的使用 3)自带验证,自定义验证,验证码的生成 4)Tree组件的使用,Grid的各种使用(修改样式,排序,隔行换色等等),Loop组件的使用 5)集合Spring4.0.5实现的增删改查 等等 如果你是新...
Tapestry采用了一种独特的模板机制,即Tapestry Markup Language(TML),它是Tapestry的核心技术之一,用于描述HTML页面和组件。 TML与传统的JSP、ASP或PHP等模板语言不同,它是一个声明式的组件模型,允许开发者...
不同于JSP,Tapestry采用组件对象模型,提供了一种构建高度动态、交互性强的Web页面的方式。Tapestry的核心在于将Web应用分解为可重用的组件,每个组件都有明确的功能,负责生成和处理HTML请求。 **Tapestry工作...