今天看了下JAVA序列化。還是一知半解。怎么也沒有弄明白,怎么序列化成XML文件。處入半解狀態。在網上找了很多,大部分是理論上的。沒有實際的例子。功夫不負有心人,終于找到了。做了下測試終于成功。忍不住記錄的下來。
JXmlSerializable 是一個利用java反射,通過調用對象中所有以get(不區分大小寫)開頭的方法除去getClass方法,生成xml格式,希望與大家分享一下
下面是一個parent對象,包含兩個child對象 生成的xml如下
Child類
package xmlTest;

import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.PrintWriter;
import java.lang.reflect.InvocationTargetException;

public class Child extends JXmlSerializable ...{

private String _name;
private String _sex;
private int age;


public void setAge(int num) ...{
age = num;
}


public int getAge() ...{
return age;
}


public void setName(String name) ...{
_name = name;
}


public void setSex(String sex) ...{
_sex = sex;
}


public String getName() ...{
return _name;
}


public String getSex() ...{
return _sex;
}

}



Parent類
package xmlTest;

import java.io.PrintWriter;
import java.lang.reflect.Array;
import java.util.*;


public class Parent extends JXmlSerializable ...{

private String _name;
private String _sex;
private LinkedList list = new LinkedList();
private Vector vec = new Vector();
int age;


public void setAge(int num) ...{
age = num;
}


public int getAge() ...{
return age;
}


public void setName(String name) ...{
_name = name;
}


public void setSex(String sex) ...{
_sex = sex;
}


public String getName() ...{
return _name;
}


public String getSex() ...{
return _sex;
}


public void addChild(Child child) ...{
list.add(child);
vec.add(child);
}


public Child[] getChild() ...{

Child[] aa = new Child[vec.size()];
// list.toArray(aa);
vec.toArray(aa);
return aa;
}


public static void main(String[] args) ...{
// TODO Auto-generated method stub

try ...{
Parent pat = new Parent();
pat.setName("jack");
pat.setSex("male");
Child child1 = new Child();
child1.setName("tom");
child1.setSex("male");
pat.addChild(child1);
Child child2 = new Child();
child2.setName("Marie");
child2.setSex("female");
pat.addChild(child2);
pat.getChild();
PrintWriter out = new PrintWriter("abc.xml");
pat.toXmlSerial(out,0);
out.flush();


} catch (Exception e) ...{
e.printStackTrace();
}

}
}
類 JXmlSerializable
package xmlTest;

import java.lang.reflect.Method;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Array;
import java.io.PrintWriter;
import java.io.IOException;

public class JXmlSerializable ...{

public void toXmlSerial(PrintWriter out, int num)
throws InvocationTargetException, IllegalAccessException,

IOException ...{
out.write("<?xml version="1.0"?> ");
String head = "";

for (int i = 0; i < num; i++) ...{
head += " ";
}
out.write(head + "<" + this.getClass().getName() + "> ");
Method[] methods = this.getClass().getMethods();

for (int i = 0; i < methods.length; i++) ...{
Class[] paras = methods[i].getParameterTypes();
String name = methods[i].getName();

if (paras == null || paras.length == 0) ...{
if ((name.substring(0, 3).toLowerCase().equals("get"))

&& !name.equals("getClass")) ...{
Object obj = methods[i].invoke(this, null);
getMethodXmlSerial(out, obj, methods[i], num);
}
}
}

out.write(head + "</" + this.getClass().getName() + "> ");

}

private void getMethodXmlSerial(PrintWriter out, Object obj, Method method,
int num) throws InvocationTargetException, IllegalAccessException,

IOException ...{
if (obj == null)
return;
String head = "";

for (int i = 0; i <= num; i++) ...{
head += " ";
}

if (obj.getClass().isArray()) ...{

for (int i = 0; i < Array.getLength(obj); i++) ...{
Object childobj = Array.get(obj, i);

if (childobj instanceof JXmlSerializable) ...{
((JXmlSerializable) childobj).toXmlSerial(out, num + 1);

} else ...{
getMethodXmlSerial(out, childobj, method, num);
}
}

} else ...{
out.write(head + " <" + method.getName().substring(3) + "> ");
out.write(obj.toString());
out.write(" </" + method.getName().substring(3) + "> ");
}

}
}
編譯出來還可以,能夠達到我的理想。
編譯結果是
<?xml version="1.0"?>
<xmlTest.Parent>
<Name> jack </Name>
<Age> 0 </Age>
<Sex> male </Sex>
<?xml version="1.0"?>
<xmlTest.Child>
<Name> tom </Name>
<Age> 0 </Age>
<Sex> male </Sex>
</xmlTest.Child>
<?xml version="1.0"?>
<xmlTest.Child>
<Name> Marie </Name>
<Age> 0 </Age>
<Sex> female </Sex>
</xmlTest.Child>
</xmlTest.Parent>
謝謝like199的分享。
今天看了看java.beans包,發現了兩個好東西,XMLEncoder和XMLDecoder。發現自己以前把從XML存取對象真是太費力氣啦。做了小工具類,以后可以用用了。
以下是引用片段:
package com.imct.util;
import java.beans.XMLDecoder;
import java.beans.XMLEncoder;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
/**
* <title>使用XML文件存取可序列化的對象的類</title>
* <description>提供保存和讀取的方法</description>
* @author 殷晉
* <copyright>清華大學汽車工程開發研究院@2005</copyright>
* @version 1.0
* 2005-8-5 16:44:49
*/
public class ObjectToXMLUtil
{
/**
* 把java的可序列化的對象(實現Serializable接口)序列化保存到XML文件里面,如果想一次保存多個可序列化對象請用集合進行封裝
* 保存時將會用現在的對象原來的XML文件內容
* @param obj 要序列化的可序列化的對象
* @param fileName 帶完全的保存路徑的文件名
* @throws FileNotFoundException 指定位置的文件不存在
* @throws IOException 輸出時發生異常
* @throws Exception 其他運行時異常
*/
public static void objectXmlEncoder(Object obj,String fileName)
throws FileNotFoundException,IOException,Exception
{
//創建輸出文件
File fo = new File(fileName);
//文件不存在,就創建該文件
if(!fo.exists())
{
//先創建文件的目錄
String path = fileName.substring(0,fileName.lastIndexOf('.'));
File pFile = new File(path);
pFile.mkdirs();
}
//創建文件輸出流
FileOutputStream fos = new FileOutputStream(fo);
//創建XML文件對象輸出類實例
XMLEncoder encoder = new XMLEncoder(fos);
//對象序列化輸出到XML文件
encoder.writeObject(obj);
encoder.flush();
//關閉序列化工具
encoder.close();
//關閉輸出流
fos.close();
}
/**
* 讀取由objSource指定的XML文件中的序列化保存的對象,返回的結果經過了List封裝
* @param objSource 帶全部文件路徑的文件全名
* @return 由XML文件里面保存的對象構成的List列表(可能是一個或者多個的序列化保存的對象)
* @throws FileNotFoundException 指定的對象讀取資源不存在
* @throws IOException 讀取發生錯誤
* @throws Exception 其他運行時異常發生
*/
public static List objectXmlDecoder(String objSource)
throws FileNotFoundException,IOException,Exception
{
List objList = new ArrayList();
File fin = new File(objSource);
FileInputStream fis = new FileInputStream(fin);
XMLDecoder decoder = new XMLDecoder(fis);
Object obj = null;
try
{
while( (obj = decoder.readObject()) != null)
{
objList.add(obj);
}
}
catch (Exception e)
{
// TODO Auto-generated catch block
}
fis.close();
decoder.close();
return objList;
}
} |
當然用Beans.instantiate也可以從文件中反序列化初對象