這個通用的推送做了很久了,來早就想把它的思路整理一下。終於,想做下來整理的時候很快又發現不知道該怎麼說了。
還是硬著頭皮往下寫吧。
那就先說說castor 吧。由於在我們的推送配置是相對比較復雜的,不管是自己通過DOM或者SAX的調用來實現回事相當麻煩的。比如說我們根據我們的配置xml , 需要定義一些對象如config,task,source。。。(都對應我們的XML)。那麼config下面是可以有不確定個數的task,task下又可以有不確定個數的source,而source下又可以有不確定個數source。這樣在在初始化的時候要做大量的對List的操作。一個字麻煩。
Castor是ExoLab Group下面的一個開放源代碼的項目,它主要實現的是O/R映射功能。它主要API和數據接口為:JDO-like, SQL, OQL, JDBC, LDAP, XML, DSML。它支持分布式目錄事務處理和時間;提供處理XML、Directory、XADirectory的類庫,提供從XML到Java類的轉換機制。其中最重要的就是其XML映射機制和其獨創的Castor JDO的機制了。我們就是使用了castor XML。
XML映射機制
組織(Marshalling)是為內存中的對象生成 XML 表示的過程。與 Java 序列化一樣,這種表示需要包含所有依賴的對象:我們的主對象引用的對象、那些對象引用的對象,等等。
解組(Unmarshalling)是與組織相反的過程,在內存中根據 XML 表示構建一個對象(和依賴的對象)。
映射(Mapping)是用於組織和解組的一套規則。 Castor 有內置的規則定義本文的這一部分所描述的缺省映射。
就以,我們的配置文件為例:
XML 代碼
<sourceid="1"name="website"isTranstion="false"isMuTheard="true"futrueid="ID">
首先 需要定義相應的對象
Java 代碼
ublicclassSourceConfigextendsAbstractSendConfig{
privatestaticfinallongserialVersionUID=3334769084824491180L;
privatebooleanisTranstion;
privatebooleanisMuTheard;
privatelonginterval=0;
privateStringfutrueid;
publicbooleangetIsMuTheard(){
returnisMuTheard;
}
publicvoidsetIsMuTheard(booleanisMuTheard){
this.isMuTheard=isMuTheard;
}
publicbooleangetIsTranstion(){
returnisTranstion;
}
publicvoidsetIsTranstion(booleanisTranstion){
this.isTranstion=isTranstion;
}
publicStringgetFutrueid(){
returnfutrueid;
}
publicvoidsetFutrueid(Stringfutrueid){
this.futrueid=futrueid;
}
publiclonggetInterval(){
returninterval;
}
publicvoidsetInterval(longinterval){
this.interval=interval;
}
}
第二步就是建立相應的map
XML 代碼
XMLversion="1.0"encoding="UTF-8"?>
"http://castor.org/mapping.dtd">
<mapping>
<classname="com.ninetowns.spider.sender.SourceConfig"auto-complete="true">
<fIEldname="id">
<bind-XMLname="id"node="attribute"/>
fIEld>
<fIEldname="name">
<bind-XMLname="name"node="attribute"/>
fIEld>
<fIEldname="futrueid">
<bind-XMLname="futrueid"node="attribute"/>
fIEld>
<fIEldname="isTranstion">
<bind-XMLname="isTranstion"node="attribute"/>
fIEld>
<fIEldname="isMuTheard">
<bind-XMLname="isMuTheard"node="attribute"/>
fIEld>
<fIEldname="interval">
<bind-XMLname="interval"node="attribute"/>
fIEld>
class>
mapping>
第三部 解組(Unmarshalling)
Java 代碼
publicclassXML2ObjectUtil{
publicstaticsynchronizedObjectXML2Object(ClassobjClass,
StringmapFile,StringXMLFile)throwsException{
if(objClass==null||XMLFile==null)
returnnull;
URLmapping=null;
if(mapFile!=null&&!mapFile.trim().equals(""))
mapping=objClass.getClassLoader().getResource(mapFile);
InputStreamin=XML2ObjectUtil.class.getClassLoader()
.getResourceAsStream(XMLFile);
returnXML2Object(objClass,mapping,in);
}
publicstaticsynchronizedObjectXML2Object(ClassobjClass,URLmapping,
InputStreaminput)throwsException{
if(objClass==null||input==null)
returnnull;
if(mapping==null)
mapping=getDefaultMap(objClass);
ClassDescriptorResolverresolver=getResolver(mapping);
Unmarshallerunmarshaller=newUnmarshaller();
unmarshaller.setWhitespacePreserve(false);
unmarshaller.setResolver((XMLClassDescriptorResolver)resolver);
InputStreamReaderreader=newInputStreamReader(input);
returnunmarshaller.unmarshal(reader);
}
}
最後就是調用了
Java 代碼
SourceConfigconfig=(SourceConfig)Xml2ObjectUtil.XML2Object(
SourceConfig.class,“map文件”,“XML文件”);
ok 這樣就搞定了一個簡單應用。castor還可以支持對象的聚合,還能支持一些基本數據類型同時還可以幫你做驗證。castor本身也是給予dom方式訪問XML的,它只是簡化了我們編寫程序的復雜度。