XStream定制转换
XStream在实现Java、xml之间转换非常的出色。但也有一些问题需要解决:Java到XML,默认转换过去就使用Java成员属性的名字作为xml Element名,反过来亦如此。但这些都是不是实际中我们所要的结果。
为此,我又研读了XStream的文档,终于解决了这个问题,下面是测试代码。
package test;
import java.util.ArrayList;
import java.util.List;
/**
* Created by IntelliJ IDEA.
* User: leizhimin
* Date: 2008-5-21 10:48:43
* Note: 主体信息
*/
public class MainBody {
private int id;
private String name;
private List investorList =
new ArrayList();
public MainBody( int id, String name, List investorList) {
this.id = id;
this.name = name;
this.investorList = investorList;
}
public String toString() {
return "MainBody{" +
"id=" + id +
", name='" + name + '\'' +
", investorList=" + investorList +
'}';
}
}
import java.util.ArrayList;
import java.util.List;
/**
* Created by IntelliJ IDEA.
* User: leizhimin
* Date: 2008-5-21 10:48:43
* Note: 主体信息
*/
public class MainBody {
private int id;
private String name;
private List
public MainBody( int id, String name, List
this.id = id;
this.name = name;
this.investorList = investorList;
}
public String toString() {
return "MainBody{" +
"id=" + id +
", name='" + name + '\'' +
", investorList=" + investorList +
'}';
}
}
package test;
/**
* Created by IntelliJ IDEA.
* User: leizhimin
* Date: 2008-5-21 10:51:08
* Note: 投资人
*/
public class Investor {
private int id;
private String name;
private int age;
public Investor( int id, String name) {
this.id = id;
this.name = name;
}
public Investor( int id, String name, int age) {
this.id = id;
this.name = name;
this.age = age;
}
public String toString() {
return "Investor{" +
"id=" + id +
", name='" + name + '\'' +
", age='" + age + '\'' +
'}';
}
}
/**
* Created by IntelliJ IDEA.
* User: leizhimin
* Date: 2008-5-21 10:51:08
* Note: 投资人
*/
public class Investor {
private int id;
private String name;
private int age;
public Investor( int id, String name) {
this.id = id;
this.name = name;
}
public Investor( int id, String name, int age) {
this.id = id;
this.name = name;
this.age = age;
}
public String toString() {
return "Investor{" +
"id=" + id +
", name='" + name + '\'' +
", age='" + age + '\'' +
'}';
}
}
package test;
import com.thoughtworks.xstream.XStream;
import java.util.List;
import java.util.ArrayList;
/**
* Created by IntelliJ IDEA.
* User: leizhimin
* Date: 2008-5-21 10:54:05
* Note: 测试
*/
public class TestConvert {
public static void main(String args[]) {
test();
}
public static void test() {
System.out.println( "----------test()----------");
Investor investor1 = new Investor(1, "gaici");
Investor investor2 = new Investor(2, "hahhah", 33);
List investorList =
new ArrayList();
investorList.add(investor1);
investorList.add(investor2);
MainBody mainBody = new MainBody(1000, "微软", investorList);
XStream xStream = new XStream();
/************** 别名定义 Object -> xml ***************/
//没有做任何别名定义直接转换
outXML(1, xStream, mainBody);
//类别名
xStream.alias( "MainBody", test.MainBody. class);
xStream.alias( "Investor", test.Investor. class);
outXML(2, xStream, mainBody);
//列表节点别名
xStream.aliasField( "Investor-List", MainBody. class, "investorList");
outXML(3, xStream, mainBody);
//一般属性节点别名
xStream.aliasField( "ztbs", test.MainBody. class, "id");
xStream.aliasField( "gdbs", test.Investor. class, "id");
outXML(4, xStream, mainBody);
//将name成员作为属性添加到Investor对应xml节点里
// xStream.aliasAttribute(Investor.class,"name","GDXM");
xStream.useAttributeFor(Investor. class, "name");
outXML(5, xStream, mainBody);
xStream.aliasAttribute(Investor. class, "age", "NL");
xStream.useAttributeFor(Investor. class, "age");
outXML(6, xStream, mainBody);
/***********************xml -> Object*************************/
String newxml = "\n" +
"1000 \n" +
"微软 \n" +
"\n" +
"\n" +
"1 \n" +
" \n" +
"\n" +
"2 \n" +
" \n" +
" \n" +
"";
MainBody m = (MainBody) xStream.fromXML(newxml);
System.out.println( "将最后一次所得的xml结果转换为Java对象输出:");
System.out.println(m);
}
public static void outXML( int index, XStream xStream, MainBody m) {
String xml = xStream.toXML(m);
System.out.println( ">>>>>>>>>>第" + index + "次输出XML:");
System.out.println(xml + "\n");
}
}
import com.thoughtworks.xstream.XStream;
import java.util.List;
import java.util.ArrayList;
/**
* Created by IntelliJ IDEA.
* User: leizhimin
* Date: 2008-5-21 10:54:05
* Note: 测试
*/
public class TestConvert {
public static void main(String args[]) {
test();
}
public static void test() {
System.out.println( "----------test()----------");
Investor investor1 = new Investor(1, "gaici");
Investor investor2 = new Investor(2, "hahhah", 33);
List
investorList.add(investor1);
investorList.add(investor2);
MainBody mainBody = new MainBody(1000, "微软", investorList);
XStream xStream = new XStream();
/************** 别名定义 Object -> xml ***************/
//没有做任何别名定义直接转换
outXML(1, xStream, mainBody);
//类别名
xStream.alias( "MainBody", test.MainBody. class);
xStream.alias( "Investor", test.Investor. class);
outXML(2, xStream, mainBody);
//列表节点别名
xStream.aliasField( "Investor-List", MainBody. class, "investorList");
outXML(3, xStream, mainBody);
//一般属性节点别名
xStream.aliasField( "ztbs", test.MainBody. class, "id");
xStream.aliasField( "gdbs", test.Investor. class, "id");
outXML(4, xStream, mainBody);
//将name成员作为属性添加到Investor对应xml节点里
// xStream.aliasAttribute(Investor.class,"name","GDXM");
xStream.useAttributeFor(Investor. class, "name");
outXML(5, xStream, mainBody);
xStream.aliasAttribute(Investor. class, "age", "NL");
xStream.useAttributeFor(Investor. class, "age");
outXML(6, xStream, mainBody);
/***********************xml -> Object*************************/
String newxml = "
"
"
"
"
"
"
"
"
"
" \n" +
"";
MainBody m = (MainBody) xStream.fromXML(newxml);
System.out.println( "将最后一次所得的xml结果转换为Java对象输出:");
System.out.println(m);
}
public static void outXML( int index, XStream xStream, MainBody m) {
String xml = xStream.toXML(m);
System.out.println( ">>>>>>>>>>第" + index + "次输出XML:");
System.out.println(xml + "\n");
}
}
运行结果:
----------test()----------
>>>>>>>>>>第1次输出XML:
< test.MainBody >
< id >1000 id >
< name >微软 name >
< investorList >
< test.Investor >
< id >1 id >
< name >gaici name >
< age >0 age >
test.Investor >
< test.Investor >
< id >2 id >
< name >hahhah name >
< age >33 age >
test.Investor >
investorList >
test.MainBody >
>>>>>>>>>>第2次输出XML:
< MainBody >
< id >1000 id >
< name >微软 name >
< investorList >
< Investor >
< id >1 id >
< name >gaici name >
< age >0 age >
Investor >
< Investor >
< id >2 id >
< name >hahhah name >
< age >33 age >
Investor >
investorList >
MainBody >
>>>>>>>>>>第3次输出XML:
< MainBody >
< id >1000 id >
< name >微软 name >
< Investor-List >
< Investor >
< id >1 id >
< name >gaici name >
< age >0 age >
Investor >
< Investor >
< id >2 id >
< name >hahhah name >
< age >33 age >
Investor >
Investor-List >
MainBody >
>>>>>>>>>>第4次输出XML:
< MainBody >
< ztbs >1000 ztbs >
< name >微软 name >
< Investor-List >
< Investor >
< gdbs >1 gdbs >
< name >gaici name >
< age >0 age >
Investor >
< Investor >
< gdbs >2 gdbs >
< name >hahhah name >
< age >33 age >
Investor >
Investor-List >
MainBody >
>>>>>>>>>>第5次输出XML:
< MainBody >
< ztbs >1000 ztbs >
< name >微软 name >
< Investor-List >
< Investor name ="gaici" >
< gdbs >1 gdbs >
< age >0 age >
Investor >
< Investor name ="hahhah" >
< gdbs >2 gdbs >
< age >33 age >
Investor >
Investor-List >
MainBody >
>>>>>>>>>>第6次输出XML:
< MainBody >
< ztbs >1000 ztbs >
< name >微软 name >
< Investor-List >
< Investor name ="gaici" NL ="0" >
< gdbs >1 gdbs >
Investor >
< Investor name ="hahhah" NL ="33" >
< gdbs >2 gdbs >
Investor >
Investor-List >
MainBody >
将最后一次所得的xml结果转换为Java对象输出:
MainBody{id=1000, name='微软', investorList=[Investor{id=1, name='gaici', age='0'}, Investor{id=2, name='hahhah', age='33'}]}
Process finished with exit code 0
>>>>>>>>>>第1次输出XML:
< test.MainBody >
< id >1000 id >
< name >微软 name >
< investorList >
< test.Investor >
< id >1 id >
< name >gaici name >
< age >0 age >
test.Investor >
< test.Investor >
< id >2 id >
< name >hahhah name >
< age >33 age >
test.Investor >
investorList >
test.MainBody >
>>>>>>>>>>第2次输出XML:
< MainBody >
< id >1000 id >
< name >微软 name >
< investorList >
< Investor >
< id >1 id >
< name >gaici name >
< age >0 age >
Investor >
< Investor >
< id >2 id >
< name >hahhah name >
< age >33 age >
Investor >
investorList >
MainBody >
>>>>>>>>>>第3次输出XML:
< MainBody >
< id >1000 id >
< name >微软 name >
< Investor-List >
< Investor >
< id >1 id >
< name >gaici name >
< age >0 age >
Investor >
< Investor >
< id >2 id >
< name >hahhah name >
< age >33 age >
Investor >
Investor-List >
MainBody >
>>>>>>>>>>第4次输出XML:
< MainBody >
< ztbs >1000 ztbs >
< name >微软 name >
< Investor-List >
< Investor >
< gdbs >1 gdbs >
< name >gaici name >
< age >0 age >
Investor >
< Investor >
< gdbs >2 gdbs >
< name >hahhah name >
< age >33 age >
Investor >
Investor-List >
MainBody >
>>>>>>>>>>第5次输出XML:
< MainBody >
< ztbs >1000 ztbs >
< name >微软 name >
< Investor-List >
< Investor name ="gaici" >
< gdbs >1 gdbs >
< age >0 age >
Investor >
< Investor name ="hahhah" >
< gdbs >2 gdbs >
< age >33 age >
Investor >
Investor-List >
MainBody >
>>>>>>>>>>第6次输出XML:
< MainBody >
< ztbs >1000 ztbs >
< name >微软 name >
< Investor-List >
< Investor name ="gaici" NL ="0" >
< gdbs >1 gdbs >
Investor >
< Investor name ="hahhah" NL ="33" >
< gdbs >2 gdbs >
Investor >
Investor-List >
MainBody >
将最后一次所得的xml结果转换为Java对象输出:
MainBody{id=1000, name='微软', investorList=[Investor{id=1, name='gaici', age='0'}, Investor{id=2, name='hahhah', age='33'}]}
Process finished with exit code 0
还有一个测试:
运行结果:
----------test()----------
MainBody{id=1000, name='微软', investorList=[Investor{id=1, name='gaici', age='0'}, Investor{id=2, name='hahhah', age='0'}]}
Investor{id=1, name='gaici', age='0'}
Investor{id=2, name='hahhah', age='0'}
Investor{id=2, name='hahhah', age='0'}
Process finished with exit code 0
MainBody{id=1000, name='微软', investorList=[Investor{id=1, name='gaici', age='0'}, Investor{id=2, name='hahhah', age='0'}]}
Investor{id=1, name='gaici', age='0'}
Investor{id=2, name='hahhah', age='0'}
Investor{id=2, name='hahhah', age='0'}
Process finished with exit code 0
说明:
1、XStream不要求Java类的属性必须有getter、setter方法,因此省略。
2、设置java成员属性别名
xStream.aliasField("Investor-List",MainBody.class,"investorList");
outXML(3,xStream,mainBody);
运行结果会产生:
3、将java成员映射为xml元素的一个属性
//将name成员作为属性添加到Investor对应xml节点里
xStream.useAttributeFor(Investor.class,"name");
运行结果会产生:
下面这两句是相关联的:
xStream.aliasAttribute(Investor.class,"name","GDXM");
xStream.useAttributeFor(Investor.class,"name");
意思是先为java成员定义个别名,然后在将别名应用于xml属性上。
运行结果会产生:
这些问题虽然解决了,但又发现了新的问题:xml转java时,当java中没有定义xml元素节点时,这时候会抛出异常。也许通过XStream本身的API可以解决,也许是XStream本身所不能处理的问题,时间有限,也没来得及深究。有知道的朋友,还望留言。
4、再进行xml到java 的转换过程中,XStream对象别名可以定义很多,涵盖的类的范围超过xml所能表达的范围,这个也没有关系,XStream还是会忠实地将xml还原为对象。但是如果xml范围大于XStream所涵盖类的范围,那么转换过程会出错。比如,要将一个Investor节点转换为ManiBody对象,肯定会出错。