而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
沒有留言:
張貼留言