日常吐槽:
好久都没怎么分享自已了...... ╮(╯▽╰)╭,最近有个需求,需要把 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
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· Manus的开源复刻OpenManus初探
· .NET Core 中如何实现缓存的预热?
· 三行代码完成国际化适配,妙~啊~
· 阿里巴巴 QwQ-32B真的超越了 DeepSeek R-1吗?