简单实体类和xml文件的相互转换方法
最近写一个题目,要求将一组员工实体类转换成xml文件,或将xml文件转换成一组实体类。题目不难,但写完感觉可以利用泛型和反射将任意一个实体类和xml文件进行转换。于是今天下午立马动手
试了下,做了个简单的模型,可以将简单的实体类和xml文件进行相互转换,但对实体类的属性类型有限制,目前只支持String,Integer,Double三种类型。但是后面可以扩展。
我的大概思路是这样的,只要能拿到实体类的类型信息,我就能拿到实体类的全部字段名称和类型,拼属性的set和get方法更是简单明了,这时候只需要通过方法的反射,将xml文件的数据读取出来给这个反射即可。
反过来只要给我一个任意对象,我就能通过反射拿到该对象所有字段的值,这时候在写xml文件即可。
具体代码如下:
packagecom.pcq.entity;
importjava.io.*;
importjava.lang.reflect.Field;
importjava.lang.reflect.InvocationTargetException;
importjava.lang.reflect.Method;
importjava.util.ArrayList;
importjava.util.Iterator;
importjava.util.List;
importorg.dom4j.Document;
importorg.dom4j.DocumentException;
importorg.dom4j.DocumentHelper;
importorg.dom4j.Element;
importorg.dom4j.io.OutputFormat;
importorg.dom4j.io.SAXReader;
importorg.dom4j.io.XMLWriter;
publicclassXMLAndEntityUtil{
privatestaticDocumentdocument=DocumentHelper.createDocument();
/**
*判断是否是个xml文件,目前类里尚未使用该方法
*@paramfilePath
*@return
*/
@SuppressWarnings("unused")
privatestaticbooleanisXMLFile(StringfilePath){
Filefile=newFile(filePath);
if(!file.exists()||filePath.indexOf(".xml")>-1){
returnfalse;
}
returntrue;
}
/**
*将一组对象数据转换成XML文件
*@paramlist
*@paramfilePath存放的文件路径
*/
publicstaticvoidwriteXML(Listlist,StringfilePath){
Class>c=list.get(0).getClass();
Stringroot=c.getSimpleName().toLowerCase()+"s";
ElementrootEle=document.addElement(root);
for(Objectobj:list){
try{
Elemente=writeXml(rootEle,obj);
document.setRootElement(e);
writeXml(document,filePath);
}catch(NoSuchMethodException|SecurityException
|IllegalAccessException|IllegalArgumentException
|InvocationTargetExceptione){
e.printStackTrace();
}
}
}
/**
*通过一个根节点来写对象的xml节点,这个方法不对外开放,主要给writeXML(Listlist,StringfilePath)提供服务
*@paramroot
*@paramobject
*@return
*@throwsNoSuchMethodException
*@throwsSecurityException
*@throwsIllegalAccessException
*@throwsIllegalArgumentException
*@throwsInvocationTargetException
*/
privatestaticElementwriteXml(Elementroot,Objectobject)throwsNoSuchMethodException,SecurityException,IllegalAccessException,IllegalArgumentException,InvocationTargetException{
Class>c=object.getClass();
StringclassName=c.getSimpleName().toLowerCase();
Elementele=root.addElement(className);
Field[]fields=c.getDeclaredFields();
for(Fieldf:fields){
StringfieldName=f.getName();
Stringparam=fieldName.substring(0,1).toUpperCase()+fieldName.substring(1);
ElementfieldElement=ele.addElement(fieldName);
Methodm=c.getMethod("get"+param,null);
Strings="";
if(m.invoke(object,null)!=null){
s=m.invoke(object,null).toString();
}
fieldElement.setText(s);
}
returnroot;
}
/**
*默认使用utf-8
*@paramc
*@paramfilePath
*@return
*@throwsUnsupportedEncodingException
*@throwsFileNotFoundException
*/
publicstaticListgetEntitys(Classc,StringfilePath)throwsUnsupportedEncodingException,FileNotFoundException{
returngetEntitys(c,filePath,"utf-8");
}
/**
*将一个xml文件转变成实体类
*@paramc
*@paramfilePath
*@return
*@throwsFileNotFoundException
*@throwsUnsupportedEncodingException
*/
publicstaticListgetEntitys(Classc,StringfilePath,Stringencoding)throwsUnsupportedEncodingException,FileNotFoundException{
Filefile=newFile(filePath);
StringlabelName=c.getSimpleName().toLowerCase();
SAXReaderreader=newSAXReader();
Listlist=null;
try{
InputStreamReaderin=newInputStreamReader(newFileInputStream(file),encoding);
Documentdocument=reader.read(in);
Elementroot=document.getRootElement();
Listelements=root.elements(labelName);
list=newArrayList();
for(Iteratorit=elements.iterator();it.hasNext();){
Elemente=(Element)it.next();
Tt=getEntity(c,e);
list.add(t);
}
}catch(DocumentExceptione){
e.printStackTrace();
}catch(InstantiationExceptione1){
e1.printStackTrace();
}catch(IllegalAccessExceptione1){
e1.printStackTrace();
}catch(NoSuchMethodExceptione1){
e1.printStackTrace();
}catch(SecurityExceptione1){
e1.printStackTrace();
}catch(IllegalArgumentExceptione1){
e1.printStackTrace();
}catch(InvocationTargetExceptione1){
e1.printStackTrace();
}
returnlist;
}
/**
*将一种类型和对应的xml元素节点传进来,返回该类型的对象,该方法不对外开放
*@paramc类类型
*@paramele元素节点
*@return该类型的对象
*@throwsInstantiationException
*@throwsIllegalAccessException
*@throwsNoSuchMethodException
*@throwsSecurityException
*@throwsIllegalArgumentException
*@throwsInvocationTargetException
*/
@SuppressWarnings("unchecked")
privatestaticTgetEntity(Classc,Elementele)throwsInstantiationException,IllegalAccessException,NoSuchMethodException,SecurityException,IllegalArgumentException,InvocationTargetException{
Field[]fields=c.getDeclaredFields();
Objectobject=c.newInstance();//
for(Fieldf:fields){
Stringtype=f.getType().toString();//获得字段的类型
StringfieldName=f.getName();//获得字段名称
Stringparam=fieldName.substring(0,1).toUpperCase()+fieldName.substring(1);//把字段的第一个字母变成大写
Elemente=ele.element(fieldName);
if(type.indexOf("Integer")>-1){//说明该字段是Integer类型
Integeri=null;
if(e.getTextTrim()!=null&&!e.getTextTrim().equals("")){
i=Integer.parseInt(e.getTextTrim());
}
Methodm=c.getMethod("set"+param,Integer.class);
m.invoke(object,i);//通过反射给该字段set值
}
if(type.indexOf("Double")>-1){//说明该字段是Double类型
Doubled=null;
if(e.getTextTrim()!=null&&!e.getTextTrim().equals("")){
d=Double.parseDouble(e.getTextTrim());
}
Methodm=c.getMethod("set"+param,Double.class);
m.invoke(object,d);
}
if(type.indexOf("String")>-1){//说明该字段是String类型
Strings=null;
if(e.getTextTrim()!=null&&!e.getTextTrim().equals("")){
s=e.getTextTrim();
}
Methodm=c.getMethod("set"+param,String.class);
m.invoke(object,s);
}
}
return(T)object;
}
/**
*用来写xml文件
*@paramdocDocument对象
*@paramfilePath生成的文件路径
*@paramencoding写xml文件的编码
*/
publicstaticvoidwriteXml(Documentdoc,StringfilePath,Stringencoding){
XMLWriterwriter=null;
OutputFormatformat=OutputFormat.createPrettyPrint();
format.setEncoding(encoding);//指定XML编码
try{
writer=newXMLWriter(newFileWriter(filePath),format);
writer.write(doc);
}catch(IOExceptione){
e.printStackTrace();
}finally{
try{
writer.close();
}catch(IOExceptione){
e.printStackTrace();
}
}
}
/**
*默认使用utf-8的格式写文件
*@paramdoc
*@paramfilePath
*/
publicstaticvoidwriteXml(Documentdoc,StringfilePath){
writeXml(doc,filePath,"utf-8");
}
}
假如有个实体类是:
packagecom.pcq.entity;
importjava.io.Serializable;
publicclassEmpimplementsSerializable{
privateIntegerid;
privateStringname;
privateIntegerdeptNo;
privateIntegerage;
privateStringgender;
privateIntegerbossId;
privateDoublesalary;
publicIntegergetId(){
returnid;
}
publicvoidsetId(Integerid){
this.id=id;
}
publicStringgetName(){
returnname;
}
publicvoidsetName(Stringname){
this.name=name;
}
publicIntegergetDeptNo(){
returndeptNo;
}
publicvoidsetDeptNo(IntegerdeptNo){
this.deptNo=deptNo;
}
publicIntegergetAge(){
returnage;
}
publicvoidsetAge(Integerage){
this.age=age;
}
publicStringgetGender(){
returngender;
}
publicvoidsetGender(Stringgender){
this.gender=gender;
}
publicIntegergetBossId(){
returnbossId;
}
publicvoidsetBossId(IntegerbossId){
this.bossId=bossId;
}
publicDoublegetSalary(){
returnsalary;
}
publicvoidsetSalary(Doublesalary){
this.salary=salary;
}
}
那么写出来的xml文件格式如下:
1 张三 50 25 男 6 9000.0 2 李四 50 22 女 6 8000.0
假如有个实体类如下:
packagecom.pcq.entity;
publicclassStudent{
privateIntegerid;
privateStringname;
privateIntegerage;
privateStringgender;
publicIntegergetId(){
returnid;
}
publicvoidsetId(Integerid){
this.id=id;
}
publicStringgetName(){
returnname;
}
publicvoidsetName(Stringname){
this.name=name;
}
publicIntegergetAge(){
returnage;
}
publicvoidsetAge(Integerage){
this.age=age;
}
publicStringgetGender(){
returngender;
}
publicvoidsetGender(Stringgender){
this.gender=gender;
}
}
那么写出来的xml文件如下
pcq 18 男
读取也必须读这种格式的xml文件,才能转换成实体类,要求是实体类的类类型信息(Class)必须要获得到。
另外这里的实体类的属性类型均是Integer,String,Double,可以看到工具类里只对这三种类型做了判断。而且可以预想的是,如果出现一对多的关系,即一个实体类拥有一组另一个类对象的引用,
那xml和实体类的相互转换要比上述的情况复杂的多。lz表示短时间内甚至长时间内也不一定能做的出来,欢迎同道高人指点。
以上这篇简单实体类和xml文件的相互转换方法就是小编分享给大家的全部内容了,希望能给大家一个参考,也希望大家多多支持毛票票。