序列化为XML

时间:2023-03-08 22:43:32
今天看了下JAVA序列化。还是一知半解。怎么也没有弄明白,怎么序列化成XML文件。处入半解状态。在网上找了很多,大部分是理论上的。没有实际的例子。功夫不负有心人,终于找到了。做了下测试终于成功。忍不住记录的下来。

JXmlSerializable   是一个利用java反射,通过调用对象中所有以get(不区分大小写)开头的方法除去getClass方法,生成xml格式,希望与大家分享一下   
  下面是一个parent对象,包含两个child对象  生成的xml如下

Child类

序列化为XMLpackage xmlTest;
序列化为XML
序列化为XMLimport java.io.FileNotFoundException;
序列化为XMLimport java.io.IOException;
序列化为XMLimport java.io.PrintWriter;
序列化为XMLimport java.lang.reflect.InvocationTargetException;
序列化为XMLpublic class Child extends JXmlSerializable {
序列化为XML
序列化为XML private String _name;
序列化为XML private String _sex;
序列化为XML private int age;
序列化为XML
序列化为XML public void setAge(int num) {
序列化为XML  age = num;
序列化为XML }
序列化为XML
序列化为XML public int getAge() {
序列化为XML  return age;
序列化为XML }
序列化为XML
序列化为XML public void setName(String name) {
序列化为XML  _name = name;
序列化为XML }
序列化为XML
序列化为XML public void setSex(String sex) {
序列化为XML  _sex = sex;
序列化为XML }
序列化为XML
序列化为XML public String getName() {
序列化为XML  return _name;
序列化为XML }
序列化为XML
序列化为XML public String getSex() {
序列化为XML  return _sex;
序列化为XML }
序列化为XML
序列化为XML}
序列化为XML
序列化为XML
序列化为XML

Parent类

序列化为XMLpackage xmlTest;
序列化为XML
序列化为XMLimport java.io.PrintWriter;
序列化为XMLimport java.lang.reflect.Array;
序列化为XMLimport java.util.*;
序列化为XML
序列化为XMLpublic class Parent extends JXmlSerializable {
序列化为XML
序列化为XML    private String _name;
序列化为XML    private String _sex;
序列化为XML    private LinkedList list = new LinkedList();
序列化为XML    private Vector vec = new Vector();
序列化为XML    int age;
序列化为XML
序列化为XML    public void setAge(int num) {
序列化为XML        age = num;
序列化为XML    }
序列化为XML
序列化为XML    public int getAge() {
序列化为XML        return age;
序列化为XML    }
序列化为XML
序列化为XML    public void setName(String name) {
序列化为XML        _name = name;
序列化为XML    }
序列化为XML
序列化为XML    public void setSex(String sex) {
序列化为XML        _sex = sex;
序列化为XML    }
序列化为XML
序列化为XML    public String getName() {
序列化为XML        return _name;
序列化为XML    }
序列化为XML
序列化为XML    public String getSex() {
序列化为XML        return _sex;
序列化为XML    }
序列化为XML
序列化为XML    public void addChild(Child child) {
序列化为XML        list.add(child);
序列化为XML        vec.add(child);
序列化为XML    }
序列化为XML
序列化为XML    public Child[] getChild() {
序列化为XML
序列化为XML        Child[] aa = new Child[vec.size()];
序列化为XML        // list.toArray(aa);
序列化为XML        vec.toArray(aa);
序列化为XML        return aa;
序列化为XML    }
序列化为XML
序列化为XML    public static void main(String[] args) {
序列化为XML        // TODO Auto-generated method stub
序列化为XML        try {
序列化为XML            Parent pat = new Parent();
序列化为XML            pat.setName("jack");
序列化为XML            pat.setSex("male");
序列化为XML            Child child1 = new Child();
序列化为XML            child1.setName("tom");
序列化为XML            child1.setSex("male");
序列化为XML            pat.addChild(child1);
序列化为XML            Child child2 = new Child();
序列化为XML            child2.setName("Marie");
序列化为XML            child2.setSex("female");
序列化为XML            pat.addChild(child2);
序列化为XML            pat.getChild();
序列化为XML            PrintWriter out = new PrintWriter("abc.xml");
序列化为XML            pat.toXmlSerial(out,0);
序列化为XML            out.flush();
序列化为XML
序列化为XML        } catch (Exception e) {
序列化为XML            e.printStackTrace();
序列化为XML        }
序列化为XML
序列化为XML    }
序列化为XML}

类 JXmlSerializable

序列化为XMLpackage xmlTest;
序列化为XML
序列化为XMLimport java.lang.reflect.Method;
序列化为XMLimport java.lang.reflect.InvocationTargetException;
序列化为XMLimport java.lang.reflect.Array;
序列化为XMLimport java.io.PrintWriter;
序列化为XMLimport java.io.IOException;
序列化为XMLpublic class JXmlSerializable {
序列化为XML
序列化为XML    public void toXmlSerial(PrintWriter out, int num)
序列化为XML            throws InvocationTargetException, IllegalAccessException,
序列化为XML            IOException {
序列化为XML        out.write("<?xml version="1.0"?> ");
序列化为XML        String head = "";
序列化为XML        for (int i = 0; i < num; i++) {
序列化为XML            head += " ";
序列化为XML        }
序列化为XML        out.write(head + "<" + this.getClass().getName() + "> ");
序列化为XML        Method[] methods = this.getClass().getMethods();
序列化为XML        for (int i = 0; i < methods.length; i++) {
序列化为XML            Class[] paras = methods[i].getParameterTypes();
序列化为XML            String name = methods[i].getName();
序列化为XML            if (paras == null || paras.length == 0) {
序列化为XML                if ((name.substring(0, 3).toLowerCase().equals("get"))
序列化为XML                        && !name.equals("getClass")) {
序列化为XML                    Object obj = methods[i].invoke(this, null);
序列化为XML                    getMethodXmlSerial(out, obj, methods[i], num);
序列化为XML                }
序列化为XML            }
序列化为XML        }
序列化为XML
序列化为XML        out.write(head + "</" + this.getClass().getName() + "> ");
序列化为XML
序列化为XML    }
序列化为XML
序列化为XML    private void getMethodXmlSerial(PrintWriter out, Object obj, Method method,
序列化为XML            int num) throws InvocationTargetException, IllegalAccessException,
序列化为XML            IOException {
序列化为XML        if (obj == null)
序列化为XML            return;
序列化为XML        String head = "";
序列化为XML        for (int i = 0; i <= num; i++) {
序列化为XML            head += " ";
序列化为XML        }
序列化为XML        if (obj.getClass().isArray()) {
序列化为XML            for (int i = 0; i < Array.getLength(obj); i++) {
序列化为XML                Object childobj = Array.get(obj, i);
序列化为XML                if (childobj instanceof JXmlSerializable) {
序列化为XML                    ((JXmlSerializable) childobj).toXmlSerial(out, num + 1);
序列化为XML                } else {
序列化为XML                    getMethodXmlSerial(out, childobj, method, num);
序列化为XML                }
序列化为XML            }
序列化为XML        } else {
序列化为XML            out.write(head + "   <" + method.getName().substring(3) + ">   ");
序列化为XML            out.write(obj.toString());
序列化为XML            out.write("   </" + method.getName().substring(3) + ">    ");
序列化为XML        }
序列化为XML
序列化为XML    }
序列化为XML}

编译出来还可以,能够达到我的理想。

编译结果是

序列化为XML<?xml version="1.0"?>
序列化为XML<xmlTest.Parent>
序列化为XML       <Name>   jack   </Name>   
序列化为XML       <Age>   0   </Age>   
序列化为XML       <Sex>   male   </Sex>   
序列化为XML<?xml version="1.0"?>
序列化为XML    <xmlTest.Child>
序列化为XML           <Name>   tom   </Name>   
序列化为XML           <Age>   0   </Age>   
序列化为XML           <Sex>   male   </Sex>   
序列化为XML    </xmlTest.Child>
序列化为XML<?xml version="1.0"?>
序列化为XML    <xmlTest.Child>
序列化为XML           <Name>   Marie   </Name>   
序列化为XML           <Age>   0   </Age>   
序列化为XML           <Sex>   female   </Sex>   
序列化为XML    </xmlTest.Child>
序列化为XML</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也可以从文件中反序列化初对象