这个通用的推送做了很久了,来早就想把它的思路整理一下。终于,想做下来整理的时候很快又发现不知道该怎么说了。
还是硬着头皮往下写吧。
那就先说说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 代码
- <source id="1" name="website" isTranstion="false" isMuTheard="true" futrueid="ID">
首先 需要定义相应的对象
java 代码
- ublic class SourceConfig extends AbstractSendConfig {
- private static final long serialVersionUID = 3334769084824491180L;
- private boolean isTranstion;
- private boolean isMuTheard;
- private long interval = 0;
- private String futrueid;
-
- public boolean getIsMuTheard() {
- return isMuTheard;
- }
-
- public void setIsMuTheard(boolean isMuTheard) {
- this.isMuTheard = isMuTheard;
- }
-
- public boolean getIsTranstion() {
- return isTranstion;
- }
-
- public void setIsTranstion(boolean isTranstion) {
- this.isTranstion = isTranstion;
- }
-
- public String getFutrueid() {
- return futrueid;
- }
-
- public void setFutrueid(String futrueid) {
- this.futrueid = futrueid;
- }
-
- public long getInterval() {
- return interval;
- }
- public void setInterval(long interval) {
- this.interval = interval;
- }
- }
第二步就是建立相应的map
xml 代码
- <!---->xml version="1.0" encoding="UTF-8"?>
- <!---->
- "http://castor.org/mapping.dtd">
- <mapping>
- <class name="com.ninetowns.spider.sender.SourceConfig" auto-complete="true">
- <field name="id">
- <bind-xml name="id" node="attribute"/>
- field>
- <field name="name">
- <bind-xml name="name" node="attribute"/>
- field>
- <field name="futrueid">
- <bind-xml name="futrueid" node="attribute"/>
- field>
- <field name="isTranstion">
- <bind-xml name="isTranstion" node="attribute"/>
- field>
- <field name="isMuTheard">
- <bind-xml name="isMuTheard" node="attribute"/>
- field>
- <field name="interval">
- <bind-xml name="interval" node="attribute"/>
- field>
- class>
- mapping>
第三部 解组(Unmarshalling)
java 代码
- public class Xml2ObjectUtil {
- public static synchronized Object xml2Object(Class objClass,
- String mapFile, String xmlFile) throws Exception {
- if (objClass == null || xmlFile == null)
- return null;
- URL mapping = null;
- if (mapFile != null && !mapFile.trim().equals(""))
- mapping = objClass.getClassLoader().getResource(mapFile);
- InputStream in = Xml2ObjectUtil.class.getClassLoader()
- .getResourceAsStream(xmlFile);
- return xml2Object(objClass, mapping, in);
- }
-
-
- public static synchronized Object xml2Object(Class objClass, URL mapping,
- InputStream input) throws Exception {
- if (objClass == null || input == null)
- return null;
- if (mapping == null)
- mapping = getDefaultMap(objClass);
-
- ClassDescriptorResolver resolver = getResolver(mapping);
-
- Unmarshaller unmarshaller = new Unmarshaller();
- unmarshaller.setWhitespacePreserve(false);
- unmarshaller.setResolver((XMLClassDescriptorResolver) resolver);
-
- InputStreamReader reader = new InputStreamReader(input);
- return unmarshaller.unmarshal(reader);
- }
- }
最后就是调用了
java 代码
- SourceConfig config = (SourceConfig ) Xml2ObjectUtil.xml2Object(
- SourceConfig.class, “map文件”, “xml文件”);
ok 这样就搞定了一个简单应用。castor还可以支持对象的聚合,还能支持一些基本数据类型同时还可以帮你做验证。castor本身也是给予dom方式访问xml的,它只是简化了我们编写程序的复杂度。