日常吐槽:
好久都沒怎么分享自已了...... ╮(╯▽╰)╭,最近有個需求,需要把 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