文章摘自: http://blog.csdn.net/javaman_chen/article/details/9351237
不得不說,人家總結的真好。。。
1.Tapestry架構的加載是通過Filter來完成的,需要在web.xml中加入以下配置:
[html]
<filter>
<filter-name>app</filter-name>
<filter-class>org.apache.tapestry5.TapestryFilter</filter-class>
</filter>
<filter-mapping>
<url-pattern>/*</url-pattern>
</filter-mapping>
2.這裡面,過濾器攔截了所有的URL,某些時候可能希望有一些URL不被攔截(比如Servlet的mapping-url)
這時候需要通過建構IgnoredPathsFilter服務,把不需要攔截的url添加到配置中去
在Module類中,添加以下方法:
[java]
public static void contributeIgnoredPathsFilter(Configuration<String> configuration){
configuration.add("/topic");//添加後/topic路徑不被Tapestry過濾器攔截
}
除了上述方式,還可以為應用程式單獨指定一個context
public void contributeApplicationDefaults(MappedConfiguration<String, String> configuration){
configuration.add(SymbolConstants.APPLICATION_FOLDER, "myApp");
同時修改filter的url
<url-pattern>/myApp/*</url-pattern>
這樣,便不會影響其他Filter和Servlet的使用
3.Tapestry遵循"約定大于配置"的開發原則,以contribute為字首的方法會自動被架構識别(比如上面的contributeIgnoredPathsFilter方法),除此之外還有其他一些約定:
以decorate開頭的方法使用裝飾器模式對現有Service進行包裝,并且加入新的功能
4.Tapestry和JQuery在功能上存在相容性的問題,如果想要兩個架構協作運作,需要引入tapestry5-jquery元件,
元件在Tapestry上做了一些JQuery的功能擴充,具體可參考:http://tapestry5-jquery.com/
maven依賴如下:
<dependency>
<groupId>org.got5</groupId>
<artifactId>tapestry5-jquery</artifactId>
<version>3.3.1</version>
</dependency>
<repository>
<id>devlab722-repo</id>
<url>http://nexus.devlab722.net/nexus/content/repositories/releases</url>
<snapshots>
<enabled>false</enabled>
</snapshots>
</repository>
<id>devlab722-snapshot-repo</id>
<url>http://nexus.devlab722.net/nexus/content/repositories/snapshots</url>
<releases>
</releases>
引入該架構後,jquery語句便可以被解析,是以無需在手動引入JQuery架構
5.Tapestry架構提供了面向元件的程式設計方法,其内部封裝了很多元件,參考:http://tapestry.apache.org/component-reference.html
Tree元件的使用
視圖:
<t:tree t:model="model" t:node="treeNode" t:value="topic">
<p:label>
<t:if test="treeNode.leaf">
<a id="${topic.href}" style="cursor:pointer">${treeNode.label}</a>
</t:if>
<t:if test="!treeNode.leaf">
${treeNode.label}
</p:label>
</t:tree>
控制器:
@Property
private TreeNode<Topic> treeNode;
private Topic topic;
public TreeModel<Topic> getModel(){
return new TopicTreeModel();
6.除了内置的元件之外,Tapestry還有一個比較特殊的元件:Layout布局元件,該元件是由開發人員來編寫的
元件功能:聲明界面的布局架構,供其他界面繼承使用
元件使用場景:界面之間存在共同的元素(菜單導航、版權資訊等),将這些共同的元素提取出來作為模版使用,功能類似于JSP的include标簽
<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:t="http://tapestry.apache.org/schema/tapestry_5_3.xsd"
xmlns:p="tapestry:parameter">
<head>
<meta http-equiv="content-type" content="text/html; charset=utf-8"/>
<title>${title}</title>
</head>
<body>
<div>header<div>
<t:body/><!--相當于java中的抽象方法,需要子界面去實作-->
<div>footer<div>
</body>
</html>
控制器:
public class Layout{
@Property
@Parameter(required = true, defaultPrefix = BindingConstants.LITERAL)
private String title;
7.元件的控制器類中經常會看到以@Parameter标注的屬性用來描述元件參數
如同功能函數需要方法參數一樣,元件也需要參數來決定其行為
如上面的Layout元件,其對外聲明了一個‘title‘參數,使用該元件時可通過t字首來指定title的值
<html t:type="layout" t:title="index page"
xmlns:t="http://tapestry.apache.org/schema/tapestry_5_3.xsd"
xmlns:j="tapestry-library:jquery">
<div>content<div>
同時也看到,由于使用了Layout元件,界面無需在處理header和footer資訊,隻需覆寫<t:body/>标簽中内容便可
元件在使用時,元件參數和類屬性是雙向綁定的,修改一方會級聯影響到另一方,比如這裡如果修改title屬性值界面會發生變化,反之亦然
@Parameter标簽對外提供了一些屬性,作用分别如下:
required:參數是否必須指定
autoconnect:将屬性值和Component的Id值綁定,如果類型一緻
value:指定預設值(可綁定屬性表達式)
cache:是否緩存參數值
defaultPrefix:預設綁定限制
8.在界面指定元件參數值時,隻能是String形式的表達式,而元件屬性可能是其他類型,是以需要進行語義轉換
Tapestry提供了幾種内置的轉換方法,通過字首的方式觸發
asset:查找資源檔案轉換成Asset對象
context:查找webapp根目錄下資源(<img
src="${context:images/icon.png}"/>)
literal:綁定字元串文本
message:加載properties檔案中對應的key值
prop:綁定屬性表達式(http://tapestry.apache.org/property-expressions.html)
var:綁定界面臨時變量(<li
t:type="loop" source="1..10"
value="var:index">${var:index}</li>)
9.在使用Layout元件時,或許會有個疑問。由于界面繼承了Layout模版,是以隻需要重寫<t:body/>标簽便可,但是如何才能引入額外的腳本和樣式呢?
平時寫界面,腳本都是在<head>裡引入的,而通過Tapestry開發界面,腳本和樣式的引入可在控制器類中進行聲明
@Import(stylesheet="context:styles/layout-default-latest.css", //引入CSS樣式
library={"context:javascripts/vendor/jquery.layout-latest.js","Layout.js"}) //引入js腳本,如不指定context字首則表示相對路徑
public class IndexPage{
......
10.Tapestry在界面端遵循的是面向元件的開發方法,通常将不同的元件按子產品進行劃分,打包放入到不同的jar中
主程式如何才能識别這些jar,并調用其封裝的元件?主要是通過manifest.mf配置檔案來完成的。
檔案中封裝了這樣一條中繼資料:Tapestry-Module-Classes:
com.yourcompany.services.yourModule
Module類是每個子產品的入口,主程式通過它來完成子產品的加載,為了将Module中的元件暴露出去供其他Module使用,需要在Module類中聲明如下方法:
public static void contributeComponentClassResolver(Configuration<LibraryMapping> configuration){
configuration.add(new LibraryMapping("moduleName", "com.yourcompany"));
自此,子產品中的元件便可被其他Module使用,通過如下聲明:
<html xmlns:t="http://tapestry.apache.org/schema/tapestry_5_1_0.xsd"
xmlns:m="tapestry-library:moduleName">
...
<m:yourComp/>
詳細參考:http://tapestry.apache.org/component-libraries.html