在Tapestry内部,URL的encode主要包含了3部分的内容。首先就是Page,就是链接应该指向的.page文件。第二部分就是链接本身所需要带的参数,即事件回调时需要传入的值。第三部分是持久参数,也就是通过@Persist定义的参数。
1. Page
a) 说明:当你使用的是DirectLink时,Page的将是你当前所在的页面。而如果你使用的是ServiceLink时,情况将会稍微负责一点。
当创建ServiceLink时,这将触发对应的IEngineService的getLink()被调用。在getLink()内部,IEngineService可以添加一些特定于该服务的参数,或者对参数进行预处理。
具体ILink的创建由LinkFactory的constructLink()完成,constructLink()定义了整个URL Encode的框架。包括对链接的参数和对@Persist参数进行编码。以及生成最终的URL。
b) 流程图
c) LinkFactory.constructLink()
public ILink constructLink(IEngineService service, boolean post, Map parameters,
boolean stateful){
finalizeParameters(service, parameters);
IEngine engine = _requestCycle.getEngine();
ServiceEncoding serviceEncoding = createServiceEncoding(parameters);
if (stateful)
_persistenceStrategySource.addParametersForPersistentProperties(serviceEncoding, post);
String fullServletPath = _contextPath + serviceEncoding.getServletPath();
return new EngineServiceLink(_requestCycle, fullServletPath, engine.getOutputEncoding(),
_codec, _request, parameters, stateful);
}
注:finalizeParameters()会调用LinkFactory的squeezeServiceParameters()方法,该方法用于处理链接的参数。
d) DataSqueezer.squeeze()
public String squeeze(Object data){
SqueezeAdaptor adaptor;
if (data == null)
return NULL_PREFIX;
adaptor = (SqueezeAdaptor) _adaptors.getStrategy(data.getClass());
return adaptor.squeeze(this, data);
}
注:通过hivemoudle.xml我们可以向DataSqueezer注册自己的SqueezeAdaptor。默认情况下Tapestry只提供
了对基本类型的处理。而如果你需要处理数据库中的对象,那么一个更合理的解决方案是提供自己的Adaptor。
DataSqueezer使用StrategyRegistry管理所有注册了的Adaptor,在查找时他主要使用的是类匹配,即比
较当前传入的类与SqueezeAdaptor声明的支持类进行比较。如果当前的类不是基本类,那么他的超类,超接口
将会顺次被比较。假定我们传入的类C具有如下的类层次。
class C extends B implements IA
class B implements IB
interface IA extends IAA
那么他的匹配队列将是[C,B,IA,IB,IAA]
e) PropertyPersistenStrategySource.addParameterForPersistentProperties()
public void addParametersForPersistentProperties(ServiceEncoding encoding, boolean post){
Iterator i = _strategies.values().iterator();
while (i.hasNext()){
PropertyPersistenceStrategy s = (PropertyPersistenceStrategy) i.next();
s.addParametersForPersistentProperties(encoding, post);
}
}
注:PropertyPersistenStrategySource会遍历所有已注册的PropertyPersistenceStrategy,通知他们往URL里
面添加内容。Tapestry定义了多种持久化策略,例如当使用Session来存储持久数据时,他并不需要在URL当中增
加数据,而当使用@Persist(“client”)时,他将会把参数添加到URL当中。
2. Link Parameter
a) 说明:SqueezeAdaptor是基于Strategy模式的,用于将对象转换为字符串的接口。通过继承该接口,可以对链接参数的转换进行定制。
3. Persist Data
a) 说明:当我们使用@Persist声明某个属性需要持久时,Tapestry将会生成用于操作该属性的字节码。当我们使用属性的set方法更新该属性的值时,Tapestry将会调用对应的PropertyPersistenceStrategy的store()方法。这样,在随后的addParametersForPersistentProperties()调用时,这些修改将能够被保存到URL或者Session当中。