日常吐槽:
好久都没怎么分享自已了...... ╮(╯▽╰)╭,最近有个需求,需要把 bean对象 转成 xml 文件,然后 xml 文件 转成对象 ( 生成 与 解析 )
一开始感觉也是觉挺简单的,直接上百度、Google去搬运嘛,啊哈哈,我是一个勤劳的搬运工,料想啊...我得到的结果,都不是我想要的......
那怎么办捏...东拼西凑吧....还真让我搞出了我想要的效果...2333333,我的脑细胞啊....做的期间真的是超级烦....一不留神就会走进死胡同....(哎,说到底还是基础不够好)
不吐槽了,不吐槽了,开始正题,看看是不是也是你们需要的效果。
用到比较多的知识点:
反射
生成xml与解析xml所依赖 的jar 包:
jdom (我用的版本是 2.0.2滴)
开始上代码...说那么多...能干嘛...复制粘贴能运行就是 very very nice,giao,奥利给!
先上实体类:
User 实体
import java.util.List;
/**
* CREATE BY OUKELE
* CREATE TIME:2020/3/18 - 14:12
*/
public class User {
private String name;
private String sex;
private int age;
private List<Address> addressList;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getSex() {
return sex;
}
public void setSex(String sex) {
this.sex = sex;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public List<Address> getAddressList() {
return addressList;
}
public void setAddressList(List<Address> addressList) {
this.addressList = addressList;
}
@Override
public String toString() {
return "User{" +
"name='" + name + '\'' +
", sex='" + sex + '\'' +
", age=" + age +
", addressList=" + addressList +
'}';
}
}
Address 实体
import java.io.Serializable;
import java.util.List;
/**
* CREATE BY OUKELE
* CREATE TIME:2020/3/18 - 14:13
*/
public class Address implements Serializable {
private String column1;
private String column2;
private String column3;
private String column4;
private List<Item> itemList;
public String getColumn1() {
return column1;
}
public void setColumn1(String column1) {
this.column1 = column1;
}
public String getColumn2() {
return column2;
}
public void setColumn2(String column2) {
this.column2 = column2;
}
public String getColumn3() {
return column3;
}
public void setColumn3(String column3) {
this.column3 = column3;
}
public String getColumn4() {
return column4;
}
public void setColumn4(String column4) {
this.column4 = column4;
}
public List<Item> getItemList() {
return itemList;
}
public void setItemList(List<Item> itemList) {
this.itemList = itemList;
}
@Override
public String toString() {
return "Address{" +
"column1='" + column1 + '\'' +
", column2='" + column2 + '\'' +
", column3='" + column3 + '\'' +
", column4='" + column4 + '\'' +
", itemList=" + itemList +
'}';
}
}
Item 实体
import java.util.List;
/**
* CREATE BY OUKELE
* CREATE TIME:2020/3/19 - 18:55
*/
public class Item {
private String item1;
private String item2;
private String item3;
private String item4;
private List<Test> testList;
public String getItem1() {
return item1;
}
public void setItem1(String item1) {
this.item1 = item1;
}
public String getItem2() {
return item2;
}
public void setItem2(String item2) {
this.item2 = item2;
}
public String getItem3() {
return item3;
}
public void setItem3(String item3) {
this.item3 = item3;
}
public String getItem4() {
return item4;
}
public void setItem4(String item4) {
this.item4 = item4;
}
public List<Test> getTestList() {
return testList;
}
public void setTestList(List<Test> testList) {
this.testList = testList;
}
@Override
public String toString() {
return "Item{" +
"item1='" + item1 + '\'' +
", item2='" + item2 + '\'' +
", item3='" + item3 + '\'' +
", item4='" + item4 + '\'' +
", testList=" + testList +
'}';
}
}
这里为啥 都是 一个 实体里包含着一个 List<?> list 实体,因为这里是我的需求... 当然还有的啦,比如 User 实体 包含着一个 Address 实体 而不是 多个Address ....等等等
上 工具类(友情提示:部分注释没写...因为写着写着就懵了.....)
import org.jdom2.Document;
import org.jdom2.Element;
import org.jdom2.input.SAXBuilder;
import org.jdom2.output.Format;
import org.jdom2.output.XMLOutputter;
import java.io.*;
import java.lang.reflect.Field;
import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
/**
* CREATE BY OUKELE
* CREATE TIME:2020/3/17 - 9:15
*/
/**
*
* 1、实现 对象 转 xml
* 2、实现 xml 转对象
*/
public class XmlInterfaceUtils {
private XmlInterfaceUtils() {
}
/**
* 对象 转 xml
*
* @param object
* @return 返回一个生成xml的位置
*/
public static String convertToXml(Object object) {
if (object == null) {
return null;
}
Element root = null;
try {
Class<?> aClass = object.getClass();
// 根节点
root = new Element(aClass.getSimpleName());
for (Field declaredField : aClass.getDeclaredFields()) {
declaredField.setAccessible(true);
// 这个属性为 List 时
if (declaredField.getGenericType() instanceof ParameterizedType) {
Element child1 = new Element(declaredField.getName());
List<?> objList = (List<?>) declaredField.get(object);
if (objList != null) {
ListObjecToXml(objList, child1);
root.addContent(child1);
}
} else {
String fieldName = declaredField.getName();
Element child = new Element(fieldName);
child.setText(String.valueOf(declaredField.get(object)));
root.addContent(child);
}
}
} catch (Exception e) {
e.printStackTrace();
System.out.println("对象转换成XML出现异常:" + e.getMessage());
}
try {
// 将 根节点 加入 文档中
Document doc = new Document(root);
// 创建xml输出流操作类
XMLOutputter xmlOutput = new XMLOutputter();
// 格式化xml内容
xmlOutput.setFormat(Format.getPrettyFormat());
File directory = new File("src/main/resources");
String courseFile = directory.getCanonicalPath();
// 把xml输出到指定位置
File f = new File(courseFile + File.separator + "temp");
if (!f.exists()) {
f.mkdirs();
}
SimpleDateFormat format = new SimpleDateFormat("yyyyMMddHHssmm");
System.out.println(f.getAbsolutePath());
File file = new File(f.getAbsolutePath() + File.separator + object.getClass().getSimpleName() + format.format(new Date()) + ".xml");
xmlOutput.output(doc, new FileOutputStream(file));
System.out.println("生成完毕! " + file.getName() + "文件生成位置为:" + file.getAbsolutePath());
return file.getAbsolutePath();
} catch (Exception e) {
e.printStackTrace();
System.out.println("生成xml文件出现异常:" + e.getMessage());
}
return null;
}
// 处理 List<实体> objData
private static void ListObjecToXml(List<?> objData, Element element) throws Exception {
if (objData != null) {
for (int i = 0; i < objData.size(); i++) {
Field[] declaredFields = objData.get(i).getClass().getDeclaredFields();
Object obj = objData.get(i);
Element root = new Element(obj.getClass().getSimpleName());
for (Field declaredField : declaredFields) {
declaredField.setAccessible(true);
Element child = new Element(declaredField.getName());
if (declaredField.getGenericType() instanceof ParameterizedType) {
List<?> objList = (List<?>) declaredField.get(obj);
if (objList != null) {
ListObjecToXml(objList, child);
root.addContent(child);
}
} else {
child.setText(String.valueOf(declaredField.get(obj)));
root.addContent(child);
}
}
element.addContent(root);
}
}
}
/**
* xml 转 对象
*
* @param clazz
* @param xmlStr
* @return
* @throws Exception
*/
public static Object dataXmltoEntity(Class<?> clazz, String xmlStr) {
if (clazz == null) {
System.out.println("未设置对象的类型");
return null;
}
File file = new File(xmlStr);
if (!file.exists()) {
System.out.println("解析失败,找不到文件");
return null;
}
//创建Jdom2的解析器对象
SAXBuilder builder = new SAXBuilder();
Document document = null;
Element root = null;
Object obj = null;
try {
document = builder.build(file.getAbsoluteFile());
root = document.getRootElement();
if (!root.getName().equals(clazz.getSimpleName())) {
System.out.println("xml内容无法转成 " + clazz + "对象,请检查!");
return null;
}
// new出 当前最大的对象
obj = clazz.getConstructor().newInstance();
} catch (Exception e) {
e.printStackTrace();
System.out.println("无法进行xml解析,请检查!");
}
try {
List<Element> children = root.getChildren();
for (Element child : children) {
// 第二层的xml数据
List<Element> children1 = child.getChildren();
if (children1.isEmpty()) { // 处理第一层的xml数据
Field field = clazz.getDeclaredField(child.getName());
field.setAccessible(true);
if (field.getGenericType().getTypeName().equals("int")) {
field.set(obj, Integer.parseInt(child.getValue()));
} else {
field.set(obj, child.getValue());
}
} else { // 处理第二层的 xml 数据
mm(clazz, obj, child, children1);
}
}
} catch (Exception e) {
e.printStackTrace();
System.out.println("解析xml数据转换成实体出现异常:" + e.getMessage());
}
return obj;
}
private static void mm(Class<?> clazz, Object obj, Element child, List<Element> children1) throws Exception {
// 取到当前的 list 属性
Field field = clazz.getDeclaredField(child.getName());
field.setAccessible(true);
Class<?> genericClazz = null;
if (field.getType() == List.class) {
// 如果是List类型,得到其Generic的类型
Type genericType = field.getGenericType();
if (genericType != null) {
// 如果是泛型参数的类型
if (genericType instanceof ParameterizedType) {
ParameterizedType pt = (ParameterizedType) genericType;
//得到泛型里的class类型对象
genericClazz = (Class<?>) pt.getActualTypeArguments()[0];
}
}
}
if (genericClazz != null) {
List list = new ArrayList();
// list 中 包含的对象
for (Element element : children1) {
// 取出当前类的属性与值
List<Element> children2 = element.getChildren();
// new 出List中包含的对象
Object o = genericClazz.getConstructor().newInstance();
// 当前对象进行赋值
for (Element element1 : children2) {
if (element1.getChildren().isEmpty()) {
Field field1 = genericClazz.getDeclaredField(element1.getName());
field1.setAccessible(true);
field1.set(o, element1.getValue());
} else {
// 递归处理
mm(genericClazz, o, element1, element1.getChildren());
}
}
list.add(o);
}
field.set(obj, list);
}
}
}
测试案例:
生成 xml (简单对象)
@Test
/**
* 测试 一个对象属性进行转换成功xml 形式
*/
public void convertOneObjecToXml(){
User user = new User();
user.setAddressList(null);
user.setName("oukele");
user.setAge(21);
user.setSex("男");
XmlInterfaceUtils.convertToXml(user);
}
生成 xml (嵌套对象)
@Test
/**
* 测试 一个对象属性(包含一个List属性又包含一个List属性....)进行转换xml 形式
*/
public void convertManyObjecToXml1() {
User user = new User();
user.setSex("男");
user.setName("oukele");
user.setAge(20);
List<Address> list = new ArrayList<>();
Address address = new Address();
address.setColumn1("广州1");
address.setColumn2("广州2");
address.setColumn3("广州3");
address.setColumn4("广州4");
Address address1 = new Address();
address1.setColumn1("珠海1");
address1.setColumn2("珠海2");
address1.setColumn3("珠海3");
address1.setColumn4("珠海4");
list.add(address);
list.add(address1);
user.setAddressList(list);
List<Item> itemList = new ArrayList<>();
List<Item> itemList1 = new ArrayList<>();
Item item = new Item();
item.setItem1("ABQ");
item.setItem2("BRR");
item.setItem3("CZZ");
item.setItem4("DCC");
Item item1 = new Item();
item1.setItem1("EB");
item1.setItem2("FR");
item1.setItem3("GN");
item1.setItem4("HM");
itemList.add(item);
itemList.add(item1);
// itemList1.add(item);
itemList1.add(item1);
address.setItemList(itemList);
address1.setItemList(itemList1);
List<com.zhhy.hy2000interface.entity.Test> testList = new ArrayList<>();
com.zhhy.hy2000interface.entity.Test test = new com.zhhy.hy2000interface.entity.Test();
test.setTest1("测试1");
test.setTest2("测试1");
testList.add(test);
item.setTestList(testList);
XmlInterfaceUtils.convertToXml(user);
}
解析 XML (解析对象)
@Test
public void convertXmlToObject(){
User o = (User) XmlInterfaceUtils.dataXmltoEntity(User.class, "H:\\User20200320134835.xml");
System.out.println(o.toString());
}
解析结果:
User{name='oukele', sex='男', age=20, addressList=[Address{column1='广州1', column2='广州2', column3='广州3', column4='广州4', itemList=[Item{item1='ABQ', item2='BRR', item3='CZZ', item4='DCC', testList=[Test{test1='测试1', test2='测试1'}]}, Item{item1='EB', item2='FR', item3='GN', item4='HM', testList=null}]}, Address{column1='珠海1', column2='珠海2', column3='珠海3', column4='珠海4', itemList=[Item{item1='EB', item2='FR', item3='GN', item4='HM', testList=null}]}]}
结尾:利用反射进行赋值的时候,目前只处理了 int 类型的等...
意思就是说.....还有很多彩蛋.......等着复制的人踩中....23333