而Betwixt,只需要編寫beans,而不需要關注XML schemas,並且提供了比較簡單的命名規範(使用getter,setter,adder方法)。
在網路上有看到一編文章在比較Betwixt & Xstream 的不同處,Betwixt 在解析XML時是使用SAX, 而Xstream是使用DOM,Xstream使用上似乎比Betwixt來的方便一些,個人在使用Betwixt時碰到一些設定會讓Betwixt抓不到相對應的bean。另外一個是Jdk 6裡面帶的StAx,有興趣的可以看看, Introduction to StAX
Feature | StAX | SAX | DOM | TrAX |
---|---|---|---|---|
API Type | Pull, streaming | Push, streaming | In memory tree | XSLT Rule |
Ease of Use | High | Medium | High | Medium |
XPath Capability | No | No | Yes | Yes |
CPU and Memory Efficiency | Good | Good | Varies | Varies |
Forward Only | Yes | Yes | No | No |
Read XML | Yes | Yes | Yes | Yes |
Write XML | Yes | No | Yes | Yes |
Create, Read, Update, Delete | No | No | Yes | No |
首先要下載Betwixt, 可以在 這邊 找到
首先要將Bean轉成XML,先看看最後轉出來的XML長什麼樣子
<?xml version='1.0' encoding='UTF-8' ?> <MailRootBean> <versionCheckObject> <version>1.0</version> </versionCheckObject> <mailInfoObject> <attachList> <attachementObject> <attachementDataStream>cGFja2FnZSBjb20uZ2ZhY3Rvci5lbWFpbGRpc2NvdmVyeS51dGlsczsNCg0KaW1wb3J0IGphdmEudXRpbC5BcnJheXM7DQoNCmltcG9ydCBqYXZheC5hbm5vdGF0aW9uLlBvc3RDb25zdHJ1Y3Q7DQoNCmltcG9ydCBvcmcuYXBhY2hlLmNvbW1vbnMubG9nZ2luZy5Mb2c7DQppbXBvcnQgb3JnLmFzcGVjdGoubGFuZy5Qcm9jZWVkaW5nSm9pblBvaW50Ow0KaW1wb3J0IG9yZy5hc3BlY3RqLmxhbmcuYW5ub3RhdGlvbi5Bcm91bmQ7DQppbXBvcnQgb3JnLmFzcGVjdGoubGFuZy5hbm5vdGF0aW9uLkFzcGVjdDsNCmltcG9ydCBvcmcuYXNwZWN0ai5sYW5nLmFubm90YXRpb24uUG9pbnRjdXQ7DQppbXBvcnQgb3JnLnNwcmluZ2ZyYW1ld29yay51dGlsLkFzc2VydDsNCmltcG9ydCBvcmcuc3ByaW5nZnJhbWV3b3JrLnV0aWwuU3RvcFdhdGNoOw0KDQoNCkBBc3BlY3QNCnB1YmxpYyBjbGFzcyBQcm9jZXNzVGltZUxvZ2dlciB7DQoJcHJpdmF0ZSBTdHJpbmcgYmVmb3JlTWVzc2FnZTsNCglwcml2YXRlIFN0cmluZyBhZnRlck1lc3NhZ2U7DQoJcHJpdmF0ZSBzdGF0aWMgZmluYWwgTG9nIGxvZ2dlciA9IE15VXRpbHMuZ2V0TG9nKCk7IA0KCQ0KCUBQb2ludGN1dCgiZXhlY3V0aW9uKCogY29tLmdmYWN0b3IuZW1haWxkaXNjb3Zlcnkuc2VydmljZS4qLiooLi4pKSIpDQoJcHJpdmF0ZSB2b2lkIHRlc3RCZWFuRXhlY3V0aW9uKCkgeyB9DQogDQoJDQoJQFBvaW50Y3V0KCJleGVjdXRpb24oKiBjb20uZ2ZhY3Rvci5lbWFpbGRpc2NvdmVyeS5kYW8uaW1wbC4qLiooLi4pKSIpDQoJcHJpdmF0ZSB2b2lkIGRhb0V4ZWN1dGlvbigpIHsgfQ0KCQ0KCUBBcm91bmQoImRhb0V4ZWN1dGlvbigpIikNCglwdWJsaWMgT2JqZWN0IGRvUHJvY2VzcyhQcm9jZWVkaW5nSm9pblBvaW50IHBqcCkgdGhyb3dzIFRocm93YWJsZSB7DQoJCVN0cmluZyBjbGFzc05hbWUgPSBwanAuZ2V0VGFyZ2V0KCkuZ2V0Q2xhc3MoKS5nZXROYW1lKCk7DQoJCVN0cmluZyBtZXRob2QgPSBwanAuZ2V0U2lnbmF0dXJlKCkuZ2V0TmFtZSgpOw0KCQlsb2dnZXIuaW5mbyhTdHJpbmcuZm9ybWF0KHRoaXMuYmVmb3JlTWVzc2FnZSxjbGFzc05hbWUsIG1ldGhvZCxBcnJheXMudG9TdHJpbmcocGpwLmdldEFyZ3MoKSkpKTsNCgkJDQoJCVN0b3BXYXRjaCB3YXRjaCA9IG5ldyBTdG9wV2F0Y2goKTsNCgkJd2F0Y2guc3RhcnQoKTsNCgkJT2JqZWN0IHJlc3VsdCA9IHBqcC5wcm9jZWVkKCk7DQoJCXdhdGNoLnN0b3AoKTsNCgkJDQoJCWxvZ2dlci5pbmZvKFN0cmluZy5mb3JtYXQodGhpcy5hZnRlck1lc3NhZ2UsbWV0aG9kLGNsYXNzTmFtZSwgQXJyYXlzLnRvU3RyaW5nKHBqcC5nZXRBcmdzKCkpKSk7DQoJCVN0cmluZyBsb2cgPSBjbGFzc05hbWUgKyAiIFJ1biAiICsgbWV0aG9kICsgIm1ldGhvZCBjb21wbGV0ZSBpbiAiKyB3YXRjaC5nZXRUb3RhbFRpbWVNaWxsaXMoKSArICIgbXMiOw0KCQlsb2dnZXIuaW5mbyhsb2cpOw0KCQlyZXR1cm4gcmVzdWx0Ow0KLy8JCS8vIERvIHdoYXQgeW91IHdhbnQgd2l0aCB0aGUgam9pbiBwb2ludCBhcmd1bWVudHMNCi8vCQlmb3IgKCBPYmplY3Qgb2JqZWN0IDogam9pblBvaW50LmdldEFyZ3MoKSkgew0KLy8JCQkNCi8vCQkJbG9nZ2VyLmluZm8oIioqKioqKiBBT1Agb2JqZWN0ID0iICsgb2JqZWN0KTsNCi8vCQl9DQovLwkJcmV0dXJuIGpvaW5Qb2ludDsNCgkJDQoJfQ0KCQ0KCUBQb3N0Q29uc3RydWN0DQoJcHVibGljIHZvaWQgaW5pdGlhbGl6ZSgpIHsNCgkgICAgQXNzZXJ0Lm5vdE51bGwodGhpcy5iZWZvcmVNZXNzYWdlLA0KCSAgICAgICAgIlRoZSBbYmVmb3JlTWVzc2FnZV0gcHJvcGVydHkgb2YgWyIgKyBnZXRDbGFzcygpLmdldE5hbWUoKSArDQoJICAgICAgICAiXSBtdXN0IGJlIHNldC4iKTsNCgkgICAgQXNzZXJ0Lm5vdE51bGwodGhpcy5hZnRlck1lc3NhZ2UsDQoJICAgICAgICAiVGhlIFthZnRlck1lc3NhZ2VdIHByb3BlcnR5IG9mIFsiICsgZ2V0Q2xhc3MoKS5nZXROYW1lKCkgKw0KCSAgICAgICAgIl0gbXVzdCBiZSBzZXQuIik7DQoJfQ0KCXB1YmxpYyB2b2lkIHNldEJlZm9yZU1lc3NhZ2UoU3RyaW5nIGJlZm9yZU1lc3NhZ2UpIHsNCgkgICAgdGhpcy5iZWZvcmVNZXNzYWdlID0gYmVmb3JlTWVzc2FnZTsNCgl9DQoJcHVibGljIHZvaWQgc2V0QWZ0ZXJNZXNzYWdlKFN0cmluZyBhZnRlck1lc3NhZ2UpIHsNCgkgICAgdGhpcy5hZnRlck1lc3NhZ2UgPSBhZnRlck1lc3NhZ2U7DQoJfQ0KfQ0K</attachementDataStream> <attachmentContentType>text/plain; name="ProcessTimeLogger.java"</attachmentContentType> <attachmentFileName>ProcessTimeLogger.java</attachmentFileName> </attachementObject> <attachementObject> <attachementDataStream>cGFja2FnZSBjb20uZ2ZhY3Rvci5lbWFpbGRpc2NvdmVyeS51dGlsczsNCg0KaW1wb3J0IHN0YXRpYyBjb20uZ2ZhY3Rvci5lbWFpbGRpc2NvdmVyeS51dGlscy5UcmFuc2FjdGlvbkluZGljYXRpbmdVdGlsLmdldFRyYW5zYWN0aW9uU3RhdHVzOw0KDQppbXBvcnQgb3JnLmFwYWNoZS5sb2c0ai5zcGkuRmlsdGVyOw0KaW1wb3J0IG9yZy5hcGFjaGUubG9nNGouc3BpLkxvZ2dpbmdFdmVudDsNCg0KcHVibGljIGNsYXNzIFRyYW5zYWN0aW9uSW5kaWNhdGluZ0ZpbHRlciBleHRlbmRzIEZpbHRlciB7DQogICAgQE92ZXJyaWRlDQogICAgcHVibGljIGludCBkZWNpZGUoTG9nZ2luZ0V2ZW50IGxvZ2dpbmdFdmVudCkgew0KICAgICAgICBsb2dnaW5nRXZlbnQuc2V0UHJvcGVydHkoInhhTmFtZSIsIGdldFRyYW5zYWN0aW9uU3RhdHVzKHRydWUpICk7DQogICAgICAgIGxvZ2dpbmdFdmVudC5zZXRQcm9wZXJ0eSgieGFTdGF0dXMiLCBnZXRUcmFuc2FjdGlvblN0YXR1cyhmYWxzZSkgKTsNCiAgICAgICAgcmV0dXJuIEZpbHRlci5ORVVUUkFMOw0KICAgIH0gIA0KfQ0K</attachementDataStream> <attachmentContentType>text/plain; name="TransactionIndicatingFilter.java"</attachmentContentType> <attachmentFileName>TransactionIndicatingFilter.java</attachmentFileName> </attachementObject> <attachementObject> <attachementDataStream>cGFja2FnZSBjb20uZ2ZhY3Rvci5lbWFpbGRpc2NvdmVyeS51dGlsczsNCg0KcHVibGljIGNsYXNzIFRyYW5zYWN0aW9uSW5kaWNhdGluZ1V0aWwgew0KCXByaXZhdGUgZmluYWwgc3RhdGljIFN0cmluZyBUU01fQ0xBU1NOQU1FID0gIm9yZy5zcHJpbmdmcmFtZXdvcmsudHJhbnNhY3Rpb24uc3VwcG9ydC5UcmFuc2FjdGlvblN5bmNocm9uaXphdGlvbk1hbmFnZXIiOw0KDQoJcHVibGljIHN0YXRpYyBTdHJpbmcgZ2V0VHJhbnNhY3Rpb25TdGF0dXMoYm9vbGVhbiB2ZXJib3NlKSB7DQoJCVN0cmluZyBzdGF0dXMgPSBudWxsOw0KDQoJCXRyeSB7DQoJCQlDbGFzc0xvYWRlciBjb250ZXh0Q2xhc3NMb2FkZXIgPSBUaHJlYWQuY3VycmVudFRocmVhZCgpLmdldENvbnRleHRDbGFzc0xvYWRlcigpOw0KCQkJDQoJCQlpZiAoY29udGV4dENsYXNzTG9hZGVyICE9IG51bGwpIHsNCgkJCQlDbGFzcyB0c21DbGFzcyA9IGNvbnRleHRDbGFzc0xvYWRlci5sb2FkQ2xhc3MoVFNNX0NMQVNTTkFNRSk7DQoJCQkJQm9vbGVhbiBpc0FjdGl2ZSA9IChCb29sZWFuKSB0c21DbGFzcy5nZXRNZXRob2QoImlzQWN0dWFsVHJhbnNhY3Rpb25BY3RpdmUiLCBudWxsKS5pbnZva2UobnVsbCwgbnVsbCk7DQoJCQkJDQoJCQkJaWYgKCF2ZXJib3NlKSB7DQoJCQkJCXN0YXR1cyA9IChpc0FjdGl2ZSkgPyAiWytdICIgOiAiWy1dICI7DQoJCQkJfSBlbHNlIHsNCgkJCQkJU3RyaW5nIHRyYW5zYWN0aW9uTmFtZSA9IChTdHJpbmcpIHRzbUNsYXNzLmdldE1ldGhvZCgiZ2V0Q3VycmVudFRyYW5zYWN0aW9uTmFtZSIsIG51bGwpLmludm9rZShudWxsLG51bGwpOw0KCQkJCQkNCgkJCQkJc3RhdHVzID0gKGlzQWN0aXZlKSA/ICJbIiArIHRyYW5zYWN0aW9uTmFtZSArICJdICIgOiAiW25vIHRyYW5zYWN0aW9uXSAiOw0KCQkJCX0NCgkJCX0gZWxzZSB7DQoJCQkJc3RhdHVzID0gKHZlcmJvc2UpID8gIltjY2wgdW5hdmFpbGFibGVdICIgOiAiW3ggXSI7DQoJCQl9DQoJCX0gY2F0Y2ggKEV4Y2VwdGlvbiBlKSB7DQoJCQlzdGF0dXMgPSAodmVyYm9zZSkgPyAiW3NwcmluZyB1bmF2YWlsYWJsZV0gIiA6ICJbeCBdIjsNCgkJfQ0KCQlyZXR1cm4gc3RhdHVzOw0KCX0NCn0NCg==</attachementDataStream> <attachmentContentType>text/plain; name="TransactionIndicatingUtil.java"</attachmentContentType> <attachmentFileName>TransactionIndicatingUtil.java</attachmentFileName> </attachementObject> </attachList> <bccRecipipent/> <body>testests</body> <bodyContentType>text/plain; charset=UTF-8; format=flowed</bodyContentType> <ccRecipipent/> <mailId><4DE4AC51.9060806@mydomain.james></mailId> <sender>admin@mydomain.james</sender> <subject>testes</subject> <toRecipipent>test@mydomain.james</toRecipipent> </mailInfoObject> </MailRootBean>
這邊總供是分成3個Bean, Root的MailRootBean, 在root裡面包含2個區塊,versionCheckObject,mailInfoObject, 寫入的時候會將直接透過write寫入, 但是讀取的時候會以MailRootBean為mapping, code如下
MailInfoObject.java
package com.mypackage.MailXmlObject; import java.util.ArrayList; public class MailInfoObject { private String mailId; private String sender; private String ToRecipipent; private String CcRecipipent; private String BccRecipipent; private String Subject; private String BodyContentType; private String body; private ArrayList<AttachementObject> attachList = new ArrayList<AttachementObject>(); public String getSender() { return sender; } public void setSender(String sender) { this.sender = sender; } public String getToRecipipent() { return ToRecipipent; } public void setToRecipipent(String toRecipipent) { ToRecipipent = toRecipipent; } public String getCcRecipipent() { return CcRecipipent; } public void setCcRecipipent(String ccRecipipent) { CcRecipipent = ccRecipipent; } public String getBccRecipipent() { return BccRecipipent; } public void setBccRecipipent(String bccRecipipent) { BccRecipipent = bccRecipipent; } public String getSubject() { return Subject; } public void setSubject(String subject) { Subject = subject; } public String getBodyContentType() { return BodyContentType; } public void setBodyContentType(String bodyContentType) { BodyContentType = bodyContentType; } public String getBody() { return body; } public void setBody(String body) { this.body = body; } public ArrayList<AttachementObject> getAttachList() { return attachList; } public void setAttachList(ArrayList<AttachementObject> attachList) { this.attachList = attachList; } public void addAttachementObject(AttachementObject attachementObject) { attachList.add(attachementObject); } public String getMailId() { return mailId; } public void setMailId(String mailId) { this.mailId = mailId; } @Override public String toString(){ StringBuilder resultBuilder = new StringBuilder(); resultBuilder.append("mailId : " this.getMailId() "\n"); resultBuilder.append("sender : " this.getSender() "\n"); resultBuilder.append("ToRecipipent : " this.getToRecipipent() "\n"); resultBuilder.append("CcRecipipent : " this.getCcRecipipent() "\n"); resultBuilder.append("BccRecipipent : " this.getBccRecipipent() "\n"); resultBuilder.append("Subject : " this.getSubject() "\n"); resultBuilder.append("BodyContentType : " this.getBodyContentType() "\n"); resultBuilder.append("body : " this.getBody() "\n"); resultBuilder.append("attachList : " attachList "\n"); if(attachList != null){ resultBuilder.append("attachList size =" attachList.size() "\n"); for (int i = 0; i < attachList.size(); i ) { resultBuilder.append(attachList.get(i).toString() "\n"); } } return resultBuilder.toString(); } }
AttachementObject.java
package com.mypackage.MailXmlObject; public class AttachementObject { private String attachmentContentType; private String attachmentFileName; private String attachementDataStream; public String getAttachmentContentType() { return attachmentContentType; } public void setAttachmentContentType(String attachmentContentType) { this.attachmentContentType = attachmentContentType; } public String getAttachmentFileName() { return attachmentFileName; } public void setAttachmentFileName(String attachmentFileName) { this.attachmentFileName = attachmentFileName; } public String getAttachementDataStream() { return attachementDataStream; } public void setAttachementDataStream(String attachementDataStream) { this.attachementDataStream = attachementDataStream; } @Override public String toString(){ StringBuilder resultBuilder = new StringBuilder(); resultBuilder.append("attachmentFileName : " this.getAttachmentFileName() "\n"); resultBuilder.append("attachmentContentType : " this.getAttachmentContentType() "\n"); resultBuilder.append("attachementDataStream : " this.getAttachementDataStream() "\n"); return resultBuilder.toString(); } }
versionChkObj.java
package com.mypackage.MailXmlObject; public class VersionCheckObject { private String version; public String getVersion() { return version; } public void setVersion(String version) { this.version = version; } }
BetwixtXmlBuilder.java
/** * */ package com.mypackage.xmlbuilder; import java.beans.IntrospectionException; import java.io.BufferedWriter; import java.io.File; import java.io.FileWriter; import java.io.IOException; import java.io.StringReader; import java.io.StringWriter; import org.apache.commons.betwixt.io.BeanReader; import org.apache.commons.betwixt.io.BeanWriter; import org.dom4j.Document; import org.dom4j.DocumentException; import org.dom4j.io.SAXReader; import org.xml.sax.SAXException; import com.mypackage.MailXmlObject.MailInfoObject; import com.mypackage.MailXmlObject.MailRootBean; import com.mypackage.MailXmlObject.VersionCheckObject; /** * @author momo * */ public class BetwixtXmlBuilder extends AbstractXmlBuilder { MailInfoObject mailobject; VersionCheckObject versionChkObj; public BetwixtXmlBuilder(){ } public BetwixtXmlBuilder(MailInfoObject mailobj,VersionCheckObject verchkobj){ this.mailobject = mailobj; this.versionChkObj = verchkobj; } /* (non-Javadoc) * @see com.mypackage.xmlbuilder.AbstractXmlBuilder#builderXml() */ @Override public void builderXml() { try{ String fileName = this.defaultFilePath this.mailobject.getMailId() ".xml"; fileName = fileName.replaceAll("<", ""); fileName = fileName.replaceAll(">", ""); StringWriter outputWriter = new StringWriter(); outputWriter.write("<?xml version='1.0' encoding='UTF-8' ?>\n"); outputWriter.write("<MailRootBean>\n"); BeanWriter beanWriter = new BeanWriter(outputWriter); beanWriter.getXMLIntrospector().getConfiguration().setAttributesForPrimitives(false); beanWriter.getBindingConfiguration().setMapIDs(false); beanWriter.enablePrettyPrint( ); beanWriter.write("versionCheckObject",this.versionChkObj ); beanWriter.write("mailInfoObject",this.mailobject ); //write to files outputWriter.write("</MailRootBean>\n"); BufferedWriter out = new BufferedWriter(new FileWriter(fileName)); out.write(outputWriter.toString()); out.close(); beanWriter.close(); outputWriter.close(); }catch(Exception ex){ } } }這邊會先建立一個StringWriter, 先寫入XML version tag, 跟root tag, 然後再透過BeanWriter的constructor 傳入一個StringWriter 物件, 然後設定setAttributesForPrimitives 為false , setAttributesForPrimitives設定為false 的差異如下,
setAttributesForPrimitives = true
<root> <age>21</age> </root>setAttributesForPrimitives = false
<root age="21"/>
setMapIDs 設成false , 代表不自動生成ID,
然後再透過beanwrite將2個bean寫入,
beanWriter.write("versionCheckObject",this.versionChkObj ); beanWriter.write("mailInfoObject",this.mailobject );這會將versionChkObj bean 寫入到xml , tag 為versionCheckObject, 另一個為mailInfoObject,
這樣就能簡單的把Bean轉入成 XML ,
讀取XML並且轉回成Bean物件, 如果有看到上面的MailInfoObject.java 的話可以注意到有一個method
public void addAttachementObject(AttachementObject attachementObject) { attachList.add(attachementObject); }這個method如果你是用eclipse 生成bean的getter&setter的話,要手動加上這段, 主要是因為在mailInfoObject 的XML tag裡面包含了Attachement file , 而Attachement 的格式如下
<attachList> <attachementObject> <attachementDataStream>cGFja2FnZSBjb20uZ2ZhY3Rvci5lbWFpbGRpc2NvdmVyeS51dGlsczsNCg0KaW1wb3J0IGphdmEudXRpbC5BcnJheXM7DQoNCmltcG9ydCBqYXZheC5hbm5vdGF0aW9uLlBvc3RDb25zdHJ1Y3Q7DQoNCmltcG9ydCBvcmcuYXBhY2hlLmNvbW1vbnMubG9nZ2luZy5Mb2c7DQppbXBvcnQgb3JnLmFzcGVjdGoubGFuZy5Qcm9jZWVkaW5nSm9pblBvaW50Ow0KaW1wb3J0IG9yZy5hc3BlY3RqLmxhbmcuYW5ub3RhdGlvbi5Bcm91bmQ7DQppbXBvcnQgb3JnLmFzcGVjdGoubGFuZy5hbm5vdGF0aW9uLkFzcGVjdDsNCmltcG9ydCBvcmcuYXNwZWN0ai5sYW5nLmFubm90YXRpb24uUG9pbnRjdXQ7DQppbXBvcnQgb3JnLnNwcmluZ2ZyYW1ld29yay51dGlsLkFzc2VydDsNCmltcG9ydCBvcmcuc3ByaW5nZnJhbWV3b3JrLnV0aWwuU3RvcFdhdGNoOw0KDQoNCkBBc3BlY3QNCnB1YmxpYyBjbGFzcyBQcm9jZXNzVGltZUxvZ2dlciB7DQoJcHJpdmF0ZSBTdHJpbmcgYmVmb3JlTWVzc2FnZTsNCglwcml2YXRlIFN0cmluZyBhZnRlck1lc3NhZ2U7DQoJcHJpdmF0ZSBzdGF0aWMgZmluYWwgTG9nIGxvZ2dlciA9IE15VXRpbHMuZ2V0TG9nKCk7IA0KCQ0KCUBQb2ludGN1dCgiZXhlY3V0aW9uKCogY29tLmdmYWN0b3IuZW1haWxkaXNjb3Zlcnkuc2VydmljZS4qLiooLi4pKSIpDQoJcHJpdmF0ZSB2b2lkIHRlc3RCZWFuRXhlY3V0aW9uKCkgeyB9DQogDQoJDQoJQFBvaW50Y3V0KCJleGVjdXRpb24oKiBjb20uZ2ZhY3Rvci5lbWFpbGRpc2NvdmVyeS5kYW8uaW1wbC4qLiooLi4pKSIpDQoJcHJpdmF0ZSB2b2lkIGRhb0V4ZWN1dGlvbigpIHsgfQ0KCQ0KCUBBcm91bmQoImRhb0V4ZWN1dGlvbigpIikNCglwdWJsaWMgT2JqZWN0IGRvUHJvY2VzcyhQcm9jZWVkaW5nSm9pblBvaW50IHBqcCkgdGhyb3dzIFRocm93YWJsZSB7DQoJCVN0cmluZyBjbGFzc05hbWUgPSBwanAuZ2V0VGFyZ2V0KCkuZ2V0Q2xhc3MoKS5nZXROYW1lKCk7DQoJCVN0cmluZyBtZXRob2QgPSBwanAuZ2V0U2lnbmF0dXJlKCkuZ2V0TmFtZSgpOw0KCQlsb2dnZXIuaW5mbyhTdHJpbmcuZm9ybWF0KHRoaXMuYmVmb3JlTWVzc2FnZSxjbGFzc05hbWUsIG1ldGhvZCxBcnJheXMudG9TdHJpbmcocGpwLmdldEFyZ3MoKSkpKTsNCgkJDQoJCVN0b3BXYXRjaCB3YXRjaCA9IG5ldyBTdG9wV2F0Y2goKTsNCgkJd2F0Y2guc3RhcnQoKTsNCgkJT2JqZWN0IHJlc3VsdCA9IHBqcC5wcm9jZWVkKCk7DQoJCXdhdGNoLnN0b3AoKTsNCgkJDQoJCWxvZ2dlci5pbmZvKFN0cmluZy5mb3JtYXQodGhpcy5hZnRlck1lc3NhZ2UsbWV0aG9kLGNsYXNzTmFtZSwgQXJyYXlzLnRvU3RyaW5nKHBqcC5nZXRBcmdzKCkpKSk7DQoJCVN0cmluZyBsb2cgPSBjbGFzc05hbWUgKyAiIFJ1biAiICsgbWV0aG9kICsgIm1ldGhvZCBjb21wbGV0ZSBpbiAiKyB3YXRjaC5nZXRUb3RhbFRpbWVNaWxsaXMoKSArICIgbXMiOw0KCQlsb2dnZXIuaW5mbyhsb2cpOw0KCQlyZXR1cm4gcmVzdWx0Ow0KLy8JCS8vIERvIHdoYXQgeW91IHdhbnQgd2l0aCB0aGUgam9pbiBwb2ludCBhcmd1bWVudHMNCi8vCQlmb3IgKCBPYmplY3Qgb2JqZWN0IDogam9pblBvaW50LmdldEFyZ3MoKSkgew0KLy8JCQkNCi8vCQkJbG9nZ2VyLmluZm8oIioqKioqKiBBT1Agb2JqZWN0ID0iICsgb2JqZWN0KTsNCi8vCQl9DQovLwkJcmV0dXJuIGpvaW5Qb2ludDsNCgkJDQoJfQ0KCQ0KCUBQb3N0Q29uc3RydWN0DQoJcHVibGljIHZvaWQgaW5pdGlhbGl6ZSgpIHsNCgkgICAgQXNzZXJ0Lm5vdE51bGwodGhpcy5iZWZvcmVNZXNzYWdlLA0KCSAgICAgICAgIlRoZSBbYmVmb3JlTWVzc2FnZV0gcHJvcGVydHkgb2YgWyIgKyBnZXRDbGFzcygpLmdldE5hbWUoKSArDQoJICAgICAgICAiXSBtdXN0IGJlIHNldC4iKTsNCgkgICAgQXNzZXJ0Lm5vdE51bGwodGhpcy5hZnRlck1lc3NhZ2UsDQoJICAgICAgICAiVGhlIFthZnRlck1lc3NhZ2VdIHByb3BlcnR5IG9mIFsiICsgZ2V0Q2xhc3MoKS5nZXROYW1lKCkgKw0KCSAgICAgICAgIl0gbXVzdCBiZSBzZXQuIik7DQoJfQ0KCXB1YmxpYyB2b2lkIHNldEJlZm9yZU1lc3NhZ2UoU3RyaW5nIGJlZm9yZU1lc3NhZ2UpIHsNCgkgICAgdGhpcy5iZWZvcmVNZXNzYWdlID0gYmVmb3JlTWVzc2FnZTsNCgl9DQoJcHVibGljIHZvaWQgc2V0QWZ0ZXJNZXNzYWdlKFN0cmluZyBhZnRlck1lc3NhZ2UpIHsNCgkgICAgdGhpcy5hZnRlck1lc3NhZ2UgPSBhZnRlck1lc3NhZ2U7DQoJfQ0KfQ0K</attachementDataStream> <attachmentContentType>text/plain; name="ProcessTimeLogger.java"</attachmentContentType> <attachmentFileName>ProcessTimeLogger.java</attachmentFileName> </attachementObject> <attachementObject> <attachementDataStream>cGFja2FnZSBjb20uZ2ZhY3Rvci5lbWFpbGRpc2NvdmVyeS51dGlsczsNCg0KaW1wb3J0IHN0YXRpYyBjb20uZ2ZhY3Rvci5lbWFpbGRpc2NvdmVyeS51dGlscy5UcmFuc2FjdGlvbkluZGljYXRpbmdVdGlsLmdldFRyYW5zYWN0aW9uU3RhdHVzOw0KDQppbXBvcnQgb3JnLmFwYWNoZS5sb2c0ai5zcGkuRmlsdGVyOw0KaW1wb3J0IG9yZy5hcGFjaGUubG9nNGouc3BpLkxvZ2dpbmdFdmVudDsNCg0KcHVibGljIGNsYXNzIFRyYW5zYWN0aW9uSW5kaWNhdGluZ0ZpbHRlciBleHRlbmRzIEZpbHRlciB7DQogICAgQE92ZXJyaWRlDQogICAgcHVibGljIGludCBkZWNpZGUoTG9nZ2luZ0V2ZW50IGxvZ2dpbmdFdmVudCkgew0KICAgICAgICBsb2dnaW5nRXZlbnQuc2V0UHJvcGVydHkoInhhTmFtZSIsIGdldFRyYW5zYWN0aW9uU3RhdHVzKHRydWUpICk7DQogICAgICAgIGxvZ2dpbmdFdmVudC5zZXRQcm9wZXJ0eSgieGFTdGF0dXMiLCBnZXRUcmFuc2FjdGlvblN0YXR1cyhmYWxzZSkgKTsNCiAgICAgICAgcmV0dXJuIEZpbHRlci5ORVVUUkFMOw0KICAgIH0gIA0KfQ0K</attachementDataStream> <attachmentContentType>text/plain; name="TransactionIndicatingFilter.java"</attachmentContentType> <attachmentFileName>TransactionIndicatingFilter.java</attachmentFileName> </attachementObject> <attachementObject> <attachementDataStream>cGFja2FnZSBjb20uZ2ZhY3Rvci5lbWFpbGRpc2NvdmVyeS51dGlsczsNCg0KcHVibGljIGNsYXNzIFRyYW5zYWN0aW9uSW5kaWNhdGluZ1V0aWwgew0KCXByaXZhdGUgZmluYWwgc3RhdGljIFN0cmluZyBUU01fQ0xBU1NOQU1FID0gIm9yZy5zcHJpbmdmcmFtZXdvcmsudHJhbnNhY3Rpb24uc3VwcG9ydC5UcmFuc2FjdGlvblN5bmNocm9uaXphdGlvbk1hbmFnZXIiOw0KDQoJcHVibGljIHN0YXRpYyBTdHJpbmcgZ2V0VHJhbnNhY3Rpb25TdGF0dXMoYm9vbGVhbiB2ZXJib3NlKSB7DQoJCVN0cmluZyBzdGF0dXMgPSBudWxsOw0KDQoJCXRyeSB7DQoJCQlDbGFzc0xvYWRlciBjb250ZXh0Q2xhc3NMb2FkZXIgPSBUaHJlYWQuY3VycmVudFRocmVhZCgpLmdldENvbnRleHRDbGFzc0xvYWRlcigpOw0KCQkJDQoJCQlpZiAoY29udGV4dENsYXNzTG9hZGVyICE9IG51bGwpIHsNCgkJCQlDbGFzcyB0c21DbGFzcyA9IGNvbnRleHRDbGFzc0xvYWRlci5sb2FkQ2xhc3MoVFNNX0NMQVNTTkFNRSk7DQoJCQkJQm9vbGVhbiBpc0FjdGl2ZSA9IChCb29sZWFuKSB0c21DbGFzcy5nZXRNZXRob2QoImlzQWN0dWFsVHJhbnNhY3Rpb25BY3RpdmUiLCBudWxsKS5pbnZva2UobnVsbCwgbnVsbCk7DQoJCQkJDQoJCQkJaWYgKCF2ZXJib3NlKSB7DQoJCQkJCXN0YXR1cyA9IChpc0FjdGl2ZSkgPyAiWytdICIgOiAiWy1dICI7DQoJCQkJfSBlbHNlIHsNCgkJCQkJU3RyaW5nIHRyYW5zYWN0aW9uTmFtZSA9IChTdHJpbmcpIHRzbUNsYXNzLmdldE1ldGhvZCgiZ2V0Q3VycmVudFRyYW5zYWN0aW9uTmFtZSIsIG51bGwpLmludm9rZShudWxsLG51bGwpOw0KCQkJCQkNCgkJCQkJc3RhdHVzID0gKGlzQWN0aXZlKSA/ICJbIiArIHRyYW5zYWN0aW9uTmFtZSArICJdICIgOiAiW25vIHRyYW5zYWN0aW9uXSAiOw0KCQkJCX0NCgkJCX0gZWxzZSB7DQoJCQkJc3RhdHVzID0gKHZlcmJvc2UpID8gIltjY2wgdW5hdmFpbGFibGVdICIgOiAiW3ggXSI7DQoJCQl9DQoJCX0gY2F0Y2ggKEV4Y2VwdGlvbiBlKSB7DQoJCQlzdGF0dXMgPSAodmVyYm9zZSkgPyAiW3NwcmluZyB1bmF2YWlsYWJsZV0gIiA6ICJbeCBdIjsNCgkJfQ0KCQlyZXR1cm4gc3RhdHVzOw0KCX0NCn0NCg==</attachementDataStream> <attachmentContentType>text/plain; name="TransactionIndicatingUtil.java"</attachmentContentType> <attachmentFileName>TransactionIndicatingUtil.java</attachmentFileName> </attachementObject> </attachList>這樣代表我們的mailInfoObject bean裡面包含的不單純是一個屬性,而是一個Collection類別,這邊是ArrayList
讀取XML to Bean的code
File f = new File("C:/james-server-container-spring-3.0-M2/Mail-XML/4DE4AC51.9060806@mydomain.james.xml"); BeanReader reader = new BeanReader(); reader.getXMLIntrospector().getConfiguration().setAttributesForPrimitives(false); reader.getBindingConfiguration().setMapIDs(false); reader.registerBeanClass("MailRootBean", MailRootBean.class); MailRootBean mailrootBean = (MailRootBean)reader.parse(f);// System.out.println("mailrootBean = " mailrootBean); System.out.println("mailrootbean.getVersionCheckObject = " mailrootBean.getVersionCheckObject().getVersion()); MailInfoObject obj = mailrootBean.getMailInfoObject(); System.out.println(obj);
沒問題的話這個在輸出的時候只有versionCheckObject會有值, 而mailInfoObject無法取到相關的值,因為他為null, 這主要是因為還缺少了一個.betwixt 的檔, 檔名跟bean name一樣, 如下
<?xml version='1.0'?> <info> <element name='mailInfoObject'> <element name='attachList'> <element name='attachementObject' property='attachList' updater='addAttachementObject'/> </element> <addDefaults/> </element> </info>
這邊的info tag為root, 代表這個bean開始的root block , 然後裡面的element name 為mailInfoObject, 在element name為mailInfoObject的下面有一個element 叫attachList, 而這個attachList裡面的屬性是attachementObject , property 為attachList(getAttachList), update則是要對這個list裡面的物件透過addAttachementObject來增加。
如無意外,bean將可以從xml讀取出來
Reference:
Betwixt Getting Started
Betwixt and List/ArrayList
沒有留言:
張貼留言