简单实体类和xml文件的相互转换方法
- 作者: 孔子见两小儿便日_
- 来源: 51数据库
- 2021-08-10
最近写一个题目,要求将一组员工实体类转换成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文件的相互转换方法就是小编分享给大家的全部内容了,希望能给大家一个参考,也希望大家多多支持。
推荐阅读
