简单实体类和xml文件的相互转换方法
程序员文章站
2022-03-21 11:05:25
最近写一个题目,要求将一组员工实体类转换成xml文件,或将xml文件转换成一组实体类。题目不难,但写完感觉可以利用泛型和反射将任意一个实体类和xml文件进行转换。于是今天下...
最近写一个题目,要求将一组员工实体类转换成xml文件,或将xml文件转换成一组实体类。题目不难,但写完感觉可以利用泛型和反射将任意一个实体类和xml文件进行转换。于是今天下午立马动手
试了下,做了个简单的模型,可以将简单的实体类和xml文件进行相互转换,但对实体类的属性类型有限制,目前只支持string, integer, double三种类型。但是后面可以扩展。
我的大概思路是这样的,只要能拿到实体类的类型信息,我就能拿到实体类的全部字段名称和类型,拼属性的set和get方法更是简单明了,这时候只需要通过方法的反射,将xml文件的数据读取出来给这个反射即可。
反过来只要给我一个任意对象,我就能通过反射拿到该对象所有字段的值,这时候在写xml文件即可。
具体代码如下:
package com.pcq.entity; import java.io.*; import java.lang.reflect.field; import java.lang.reflect.invocationtargetexception; import java.lang.reflect.method; import java.util.arraylist; import java.util.iterator; import java.util.list; import org.dom4j.document; import org.dom4j.documentexception; import org.dom4j.documenthelper; import org.dom4j.element; import org.dom4j.io.outputformat; import org.dom4j.io.saxreader; import org.dom4j.io.xmlwriter; public class xmlandentityutil { private static document document = documenthelper.createdocument(); /** * 判断是否是个xml文件,目前类里尚未使用该方法 * @param filepath * @return */ @suppresswarnings("unused") private static boolean isxmlfile(string filepath) { file file = new file(filepath); if(!file.exists() || filepath.indexof(".xml") > -1) { return false; } return true; } /** * 将一组对象数据转换成xml文件 * @param list * @param filepath 存放的文件路径 */ public static <t> void writexml(list<t> list, string filepath) { class<?> c = list.get(0).getclass(); string root = c.getsimplename().tolowercase() + "s"; element rootele = document.addelement(root); for(object obj : list) { try { element e = writexml(rootele, obj); document.setrootelement(e); writexml(document, filepath); } catch (nosuchmethodexception | securityexception | illegalaccessexception | illegalargumentexception | invocationtargetexception e) { e.printstacktrace(); } } } /** * 通过一个根节点来写对象的xml节点,这个方法不对外开放,主要给writexml(list<t> list, string filepath)提供服务 * @param root * @param object * @return * @throws nosuchmethodexception * @throws securityexception * @throws illegalaccessexception * @throws illegalargumentexception * @throws invocationtargetexception */ private static element writexml(element root, object object) throws nosuchmethodexception, securityexception, illegalaccessexception, illegalargumentexception, invocationtargetexception { class<?> c = object.getclass(); string classname = c.getsimplename().tolowercase(); element ele = root.addelement(classname); field[] fields = c.getdeclaredfields(); for(field f : fields) { string fieldname = f.getname(); string param = fieldname.substring(0, 1).touppercase() + fieldname.substring(1); element fieldelement = ele.addelement(fieldname); method m = c.getmethod("get" + param, null); string s = ""; if(m.invoke(object, null) != null) { s = m.invoke(object, null).tostring(); } fieldelement.settext(s); } return root; } /** * 默认使用utf-8 * @param c * @param filepath * @return * @throws unsupportedencodingexception * @throws filenotfoundexception */ public static <t> list<t> getentitys(class<t> c, string filepath) throws unsupportedencodingexception, filenotfoundexception { return getentitys(c, filepath, "utf-8"); } /** * 将一个xml文件转变成实体类 * @param c * @param filepath * @return * @throws filenotfoundexception * @throws unsupportedencodingexception */ public static <t> list<t> getentitys(class<t> c, string filepath, string encoding) throws unsupportedencodingexception, filenotfoundexception { file file = new file(filepath); string labelname = c.getsimplename().tolowercase(); saxreader reader = new saxreader(); list<t> list = null; try { inputstreamreader in = new inputstreamreader(new fileinputstream(file), encoding); document document = reader.read(in); element root = document.getrootelement(); list elements = root.elements(labelname); list = new arraylist<t>(); for(iterator<emp> it = elements.iterator(); it.hasnext();) { element e = (element)it.next(); t t = getentity(c, e); list.add(t); } } catch (documentexception e) { e.printstacktrace(); } catch (instantiationexception e1) { e1.printstacktrace(); } catch (illegalaccessexception e1) { e1.printstacktrace(); } catch (nosuchmethodexception e1) { e1.printstacktrace(); } catch (securityexception e1) { e1.printstacktrace(); } catch (illegalargumentexception e1) { e1.printstacktrace(); } catch (invocationtargetexception e1) { e1.printstacktrace(); } return list; } /** * 将一种类型 和对应的 xml元素节点传进来,返回该类型的对象,该方法不对外开放 * @param c 类类型 * @param ele 元素节点 * @return 该类型的对象 * @throws instantiationexception * @throws illegalaccessexception * @throws nosuchmethodexception * @throws securityexception * @throws illegalargumentexception * @throws invocationtargetexception */ @suppresswarnings("unchecked") private static <t> t getentity(class<t> c, element ele) throws instantiationexception, illegalaccessexception, nosuchmethodexception, securityexception, illegalargumentexception, invocationtargetexception { field[] fields = c.getdeclaredfields(); object object = c.newinstance();// for(field f : fields) { string type = f.gettype().tostring();//获得字段的类型 string fieldname = f.getname();//获得字段名称 string param = fieldname.substring(0, 1).touppercase() + fieldname.substring(1);//把字段的第一个字母变成大写 element e = ele.element(fieldname); if(type.indexof("integer") > -1) {//说明该字段是integer类型 integer i = null; if(e.gettexttrim() != null && !e.gettexttrim().equals("")) { i = integer.parseint(e.gettexttrim()); } method m = c.getmethod("set" + param, integer.class); m.invoke(object, i);//通过反射给该字段set值 } if(type.indexof("double") > -1) { //说明该字段是double类型 double d = null; if(e.gettexttrim() != null && !e.gettexttrim().equals("")) { d = double.parsedouble(e.gettexttrim()); } method m = c.getmethod("set" + param, double.class); m.invoke(object, d); } if(type.indexof("string") > -1) {//说明该字段是string类型 string s = null; if(e.gettexttrim() != null && !e.gettexttrim().equals("")) { s = e.gettexttrim(); } method m = c.getmethod("set" + param, string.class); m.invoke(object, s); } } return (t)object; } /** * 用来写xml文件 * @param doc document对象 * @param filepath 生成的文件路径 * @param encoding 写xml文件的编码 */ public static void writexml(document doc, string filepath, string encoding) { xmlwriter writer = null; outputformat format = outputformat.createprettyprint(); format.setencoding(encoding);// 指定xml编码 try { writer = new xmlwriter(new filewriter(filepath), format); writer.write(doc); } catch (ioexception e) { e.printstacktrace(); } finally { try { writer.close(); } catch (ioexception e) { e.printstacktrace(); } } } /** * 默认使用utf-8的格式写文件 * @param doc * @param filepath */ public static void writexml(document doc, string filepath) { writexml(doc, filepath, "utf-8"); } }
假如有个实体类是:
package com.pcq.entity; import java.io.serializable; public class emp implements serializable{ private integer id; private string name; private integer deptno; private integer age; private string gender; private integer bossid; private double salary; public integer getid() { return id; } public void setid(integer id) { this.id = id; } public string getname() { return name; } public void setname(string name) { this.name = name; } public integer getdeptno() { return deptno; } public void setdeptno(integer deptno) { this.deptno = deptno; } public integer getage() { return age; } public void setage(integer age) { this.age = age; } public string getgender() { return gender; } public void setgender(string gender) { this.gender = gender; } public integer getbossid() { return bossid; } public void setbossid(integer bossid) { this.bossid = bossid; } public double getsalary() { return salary; } public void setsalary(double salary) { this.salary = salary; } }
那么写出来的xml文件格式如下:
<?xml version="1.0" encoding="utf-8"?> <emps> <emp> <id>1</id> <name>张三</name> <deptno>50</deptno> <age>25</age> <gender>男</gender> <bossid>6</bossid> <salary>9000.0</salary> </emp> <emp> <id>2</id> <name>李四</name> <deptno>50</deptno> <age>22</age> <gender>女</gender> <bossid>6</bossid> <salary>8000.0</salary> </emp> </emps>
假如有个实体类如下:
package com.pcq.entity; public class student { private integer id; private string name; private integer age; private string gender; public integer getid() { return id; } public void setid(integer id) { this.id = id; } public string getname() { return name; } public void setname(string name) { this.name = name; } public integer getage() { return age; } public void setage(integer age) { this.age = age; } public string getgender() { return gender; } public void setgender(string gender) { this.gender = gender; } }
那么写出来的xml文件如下
<?xml version="1.0" encoding="utf-8"?> <students> <student> <id></id> <name>pcq</name> <age>18</age> <gender>男</gender> </student> </students>
读取也必须读这种格式的xml文件,才能转换成实体类,要求是实体类的类类型信息(class)必须要获得到。
另外这里的实体类的属性类型均是integer,string,double,可以看到工具类里只对这三种类型做了判断。而且可以预想的是,如果出现一对多的关系,即一个实体类拥有一组另一个类对象的引用,
那xml和实体类的相互转换要比上述的情况复杂的多。lz表示短时间内甚至长时间内也不一定能做的出来,欢迎同道高人指点。
以上这篇简单实体类和xml文件的相互转换方法就是小编分享给大家的全部内容了,希望能给大家一个参考,也希望大家多多支持。