Java中操作Xml使用方法備忘錄(Hutool工具類(lèi)XmlUtil、XStream)
1. Hutool中XmlUtil的使用簡(jiǎn)介
# 說(shuō)明1: XmlUtil只是w3c dom的簡(jiǎn)單工具化封裝,減少操作dom的難度,
# 如果項(xiàng)目對(duì)XML依賴(lài)較大,依舊推薦Dom4j框架
# 說(shuō)明2:JDK已經(jīng)封裝有XML解析和構(gòu)建工具:w3c dom
# Hutool中XmlUtil簡(jiǎn)化XML的創(chuàng)建、讀、寫(xiě)
1. 讀取XML
讀取XML分為兩個(gè)方法:XmlUtil.readXML 讀取XML文件
XmlUtil.parseXml 解析XML字符串為Document對(duì)象
2. 寫(xiě)XML
XmlUtil.toStr 將XML文檔轉(zhuǎn)換為String
XmlUtil.toFile 將XML文檔寫(xiě)入到文件
3. 創(chuàng)建XML
XmlUtil.createXml 創(chuàng)建XML文檔, 創(chuàng)建的XML默認(rèn)是utf8編碼,
修改編碼的過(guò)程是在toStr和toFile方法里,既XML在轉(zhuǎn)為文本的時(shí)候才定義編碼。4. XML讀取操作
通過(guò)以下工具方法,可以完成基本的節(jié)點(diǎn)讀取操作。
XmlUtil.cleanInvalid 除XML文本中的無(wú)效字符
XmlUtil.getElements 根據(jù)節(jié)點(diǎn)名獲得子節(jié)點(diǎn)列表
XmlUtil.getElement 根據(jù)節(jié)點(diǎn)名獲得第一個(gè)子節(jié)點(diǎn)
XmlUtil.elementText 根據(jù)節(jié)點(diǎn)名獲得第一個(gè)子節(jié)點(diǎn)
XmlUtil.transElements 將NodeList轉(zhuǎn)換為Element列表
5. XML與對(duì)象轉(zhuǎn)換
writeObjectAsXml 將可序列化的對(duì)象轉(zhuǎn)換為XML寫(xiě)入文件,已經(jīng)存在的文件將被覆蓋。
readObjectFromXml 從XML中讀取對(duì)象。
注意 這兩個(gè)方法嚴(yán)重依賴(lài)JDK的XMLEncoder和XMLDecoder,
生成和解析必須成對(duì)存在(遵循固定格式),普通的XML轉(zhuǎn)Bean會(huì)報(bào)錯(cuò)。6. Xpath操作
createXPath 創(chuàng)建XPath
getByXPath 通過(guò)XPath方式讀取XML節(jié)點(diǎn)等信息
2. Hutool中XmlUtil快速讀取Xml字符串某個(gè)節(jié)點(diǎn)值 [簡(jiǎn)單取值時(shí),推薦使用]
2-1 Hutool工具包Maven依賴(lài)和測(cè)試Xml字符串如下
<!-- 引入Hutool的Maven依賴(lài) --> <dependency> <groupId>cn.hutool</groupId> <artifactId>hutool-all</artifactId> <version>5.8.16</version> </dependency>
<!-- 下方測(cè)試用的Xml字符串 --> <?xml version="1.0" encoding="utf-8"?> <returnsms> <returnstatus>Success(成功)</returnstatus> <message>ok</message> <remainpoint>1490</remainpoint> <taskID>885</taskID> <successCounts>1</successCounts> </returnsms>
2-2 讀取Xml中的節(jié)點(diǎn)的值
Document docResult=XmlUtil.readXML(xmlFile); // 結(jié)果為“ok” Object value = XmlUtil.getByXPath("http://returnsms/message", docResult, XPathConstants.STRING); // 說(shuō)明:Element對(duì)象目前僅能支持一層一層的向下解析,所以請(qǐng)不要跳級(jí)去做查詢(xún), // 否則會(huì)報(bào)null。如果想直接獲取到某個(gè)標(biāo)簽的文本,在有準(zhǔn)確定位的情況下 // 可以直接寫(xiě)出路徑獲取, // 但是如果該層級(jí)存在相同的標(biāo)簽則只獲取第一個(gè)標(biāo)簽的數(shù)據(jù)。 String xmlData="xml字符串"; Document document= XmlUtil.parseXml(xmlData); //獲得XML文檔根節(jié)點(diǎn) Element elementG=XmlUtil.getRootElement(document); //通過(guò)固定路徑獲取到數(shù)據(jù) Object bString = XmlUtil.getByXPath("http://root/base/message/event_no", document, XPathConstants.STRING); System.out.println("event_no元素節(jié)點(diǎn)值:"+bString);
3. Hutool中XmlUtil詳細(xì)操作示例
3-1 Xml示例字符串如下
<forms version="2.1"> <formExport> <summary id="1132755668421070367" name="formmain_0031"/> <definitions> <column id="field0001" type="0" name="field1" length="255"/> <column id="field0002" type="0" name="field2" length="256"/> </definitions> <values> <column name="field1"> <value> 建行一世 </value> </column> <column name="field2"> <value> 中國(guó)人民 </value> </column> </values> <subForms/> </formExport> </forms>
3-2 查詢(xún)標(biāo)簽內(nèi)的屬性
// 例: 獲取<definitions>標(biāo)簽中第一個(gè)標(biāo)簽<column >屬性length的值 String xmlData="上面規(guī)定的xml字符串"; // 測(cè)試時(shí)自己替換下 Document document= XmlUtil.parseXml(xmlData); //獲得XML文檔根節(jié)點(diǎn) Element elementG=XmlUtil.getRootElement(document); //打印節(jié)點(diǎn)名稱(chēng) System.out.println(elementG.getTagName()); //獲取下層節(jié)點(diǎn)(該方法默認(rèn)取第一個(gè)) Element elementZ=XmlUtil.getElement(elementG,"formExport"); System.out.println(elementZ.getTagName()); //獲取下層節(jié)點(diǎn)(該方法默認(rèn)取第一個(gè)) Element elementZ1=XmlUtil.getElement(elementZ,"definitions"); System.out.println(elementZ1.getTagName()); //獲取下層節(jié)點(diǎn)(該方法默認(rèn)取第一個(gè)) Element elementZ2=XmlUtil.getElement(elementZ1,"column"); System.out.println(elementZ2.getTagName()); //讀取屬性length System.out.println(elementZ2.getAttribute("length"));
3-3 查詢(xún)一對(duì)標(biāo)簽中的文本
// 例:獲取<values>標(biāo)簽中第一個(gè)標(biāo)簽<column>下的<value>所包含的文本,可直接看最后一行 // =======以下內(nèi)容同3-2,內(nèi)容開(kāi)始======================================== String xmlData="上面規(guī)定的xml字符串"; Document document= XmlUtil.parseXml(xmlData); //獲得XML文檔根節(jié)點(diǎn) Element elementG=XmlUtil.getRootElement(document); //獲取下層節(jié)點(diǎn)(該方法默認(rèn)取第一個(gè)) Element elementZ=XmlUtil.getElement(elementG,"formExport"); //獲取下層節(jié)點(diǎn)(該方法默認(rèn)取第一個(gè)) Element elementZ_1=XmlUtil.getElement(elementZ,"values"); //獲取下層節(jié)點(diǎn)(該方法默認(rèn)取第一個(gè)) Element elementZ_2=XmlUtil.getElement(elementZ_1,"column"); // =======以上內(nèi)容同3-2,內(nèi)容結(jié)束======================================== //獲取到所有子標(biāo)簽 // Value返回的時(shí)NodeList,遍歷獲取即可 NodeList nodeList=elementZ_2.getElementsByTagName("value"); for (int i = 0; i <nodeList.getLength() ; i++) { //打印標(biāo)簽的文本 System.out.println(nodeList.item(i).getTextContent()); }
3-4 查詢(xún)Xml后,再新增一個(gè)標(biāo)簽并賦值
// 例:給<values>標(biāo)簽中第一個(gè)標(biāo)簽<column>下再度添加一個(gè)<value>標(biāo)簽,所包含的文本為:從零開(kāi)始 // =======以下內(nèi)容同3-2,內(nèi)容開(kāi)始======================================== String xmlData="上面規(guī)定的xml字符串"; Document document= XmlUtil.parseXml(xmlData); //獲得XML文檔根節(jié)點(diǎn) Element elementG=XmlUtil.getRootElement(document); //獲取下層節(jié)點(diǎn)(該方法默認(rèn)取第一個(gè)) Element elementZ=XmlUtil.getElement(elementG,"formExport"); //獲取下層節(jié)點(diǎn)(該方法默認(rèn)取第一個(gè)) Element elementZ_1=XmlUtil.getElement(elementZ,"values"); //獲取下層節(jié)點(diǎn)(該方法默認(rèn)取第一個(gè)) Element elementZ_2=XmlUtil.getElement(elementZ_1,"column"); // =======以上內(nèi)容同3-2,內(nèi)容結(jié)束======================================== //創(chuàng)建一個(gè)標(biāo)簽 Element elementItem = document.createElement("value"); //賦值 elementItem.setTextContent("從零開(kāi)始"); //放到某個(gè)標(biāo)簽下面 elementZ_2.appendChild(elementItem); //獲取到所有子標(biāo)簽 NodeList nodeList=elementZ_2.getElementsByTagName("value"); for (int i = 0; i <nodeList.getLength() ; i++) { //打印標(biāo)簽的文本 System.out.println(nodeList.item(i).getTextContent()); } System.out.println(XmlUtil.toStr(document)); // 打印的結(jié)果: 在<value>建行一世</value>后,新增了一個(gè)<value>從零開(kāi)始</value>
3-5 修改一個(gè)標(biāo)簽數(shù)據(jù)
// 例:給<values>標(biāo)簽中第一個(gè)標(biāo)簽<column>下的第一個(gè)<value>標(biāo)簽修改成:張三豐 // =======以下內(nèi)容同3-2,內(nèi)容開(kāi)始======================================== String xmlData="上面規(guī)定的xml字符串"; Document document= XmlUtil.parseXml(xmlData); //獲得XML文檔根節(jié)點(diǎn) Element elementG=XmlUtil.getRootElement(document); //獲取下層節(jié)點(diǎn)(該方法默認(rèn)取第一個(gè)) Element elementZ=XmlUtil.getElement(elementG,"formExport"); //獲取下層節(jié)點(diǎn)(該方法默認(rèn)取第一個(gè)) Element elementZ_1=XmlUtil.getElement(elementZ,"values"); //獲取下層節(jié)點(diǎn)(該方法默認(rèn)取第一個(gè)) Element elementZ_2=XmlUtil.getElement(elementZ_1,"column"); // =======以上內(nèi)容同3-2,內(nèi)容結(jié)束======================================== //獲取到所有子標(biāo)簽 NodeList nodeList=elementZ_2.getElementsByTagName("value"); //第一次打印 for (int i = 0; i <nodeList.getLength() ; i++) { //打印標(biāo)簽的文本 System.out.println(nodeList.item(i).getTextContent()); } //修改 for (int i = 0; i <nodeList.getLength() ; i++) { // ******************* 這里進(jìn)行修改 ******************** nodeList.item(i).setTextContent("張三豐"); } //第二次打印 for (int i = 0; i <nodeList.getLength() ; i++) { //打印標(biāo)簽的文本 System.out.println(nodeList.item(i).getTextContent()); } // 打印輸出結(jié)果: // 第一次打印輸出為: 建行一世 // 第二次打印輸出為: 張三豐
4 依賴(lài)Hutool再次封裝的工具類(lèi)XmlUtil,實(shí)現(xiàn)xml-map、map-xml、xml-json功能
// 作用:
// 1.xml轉(zhuǎn)map
// 2.xml轉(zhuǎn)json
// 3.map轉(zhuǎn)xml
4-1 需要添加的依賴(lài)
<dependency> <groupId>cn.hutool</groupId> <artifactId>hutool-all</artifactId> <version>5.7.15</version> </dependency> <dependency> <groupId>org.dom4j</groupId> <artifactId>dom4j</artifactId> <version>2.1.3</version> </dependency>
4-2 工具類(lèi)XmlUtil代碼
4-2-1 用到的一個(gè)枚舉XmlSort如下:
import java.util.HashMap; import java.util.LinkedHashMap; /** * xml解析順序是否有序 * @author ASen */ public enum XmlSort{ /** * 有序 */ SORT(LinkedHashMap.class,"有序"), /** * 無(wú)序 */ NO_SORT(HashMap.class,"無(wú)序"); /** * 創(chuàng)建的map字節(jié)碼對(duì)象 */ private final Class<?> mapClass; /** * 順序名稱(chēng) */ private final String message ; XmlSort(Class<?> mapClass, String message) { this.mapClass = mapClass; this.message = message; } public Class<?> getMapClass() { return mapClass; } public String getMessage() { return message; } }
4-2-2 XmlUtil.java如下
package com.asen.demo.util; import cn.hutool.core.lang.Assert; import cn.hutool.core.util.ObjectUtil; import cn.hutool.json.JSONUtil; import com.asen.demo.constant.XmlSort; import org.dom4j.Attribute; import org.dom4j.Document; import org.dom4j.DocumentException; import org.dom4j.Element; import org.dom4j.io.SAXReader; import org.dom4j.tree.DefaultDocument; import org.dom4j.tree.DefaultElement; import java.io.File; import java.util.ArrayList; import java.util.Iterator; import java.util.List; import java.util.Map; /** * xml解析幫組類(lèi) * @author asen * @date 2022/1/10 15:17 */ public class XmlUtil { /** * 標(biāo)簽屬性 */ private final static String TAG_ATTR = "attr"; /** * 創(chuàng)建的map類(lèi)型 */ private XmlSort xmlSort = XmlSort.NO_SORT; /** * map to xml * @param map map對(duì)象 * @return xml 字符串 */ public String mapToXml(Map<String,Object> map) { if(map.size() != 1){ throw new RuntimeException("map根節(jié)點(diǎn)長(zhǎng)度不為1"); } String key = ""; for (String str : map.keySet()) { key = str ; } // 創(chuàng)建根節(jié)點(diǎn) Element rootElement = new DefaultElement(key); Document document = new DefaultDocument(rootElement); Element node = document.getRootElement(); Object obj = map.get(key); // 斷言 Assert.isAssignable(Map.class,obj.getClass()); mapNodes(node,(Map<String, Object>)obj); return document.asXML(); } /** * 父類(lèi)節(jié)點(diǎn)已經(jīng)創(chuàng)建, map 包含父類(lèi) * @param node node * @param map map */ public void mapNodes(Element node, Map<String, Object> map) { map.forEach((k,v)->{ Object obj = map.get(k); // 給當(dāng)前父類(lèi)添加屬性 if(TAG_ATTR.equals(k)){ Assert.isAssignable(Map.class,obj.getClass()); Map<String,Object> tagMap = (Map<String,Object>) obj; tagMap.forEach((tagKey,tagValue)->{ node.addAttribute(tagKey, (String) tagValue); }); return ; } if(obj instanceof Map){ Element newElement = node.addElement(k); // map 處理 Map<String,Object> childMap = (Map<String,Object>) obj; mapNodes(newElement,childMap); }else if (obj instanceof String){ Element newElement = node.addElement(k); newElement.setText((String) v); } else if (obj instanceof List) { List<Map<String, Object>> list = (List<Map<String, Object>>) obj; list.forEach(itemMap->{ Element newElement = node.addElement(k); mapNodes(newElement,itemMap); }); } }); } /** * 讀取xml文件,返回json字符串 * * @param fileName 文件路徑 * @return json字符串 * @throws DocumentException 異常 */ public String xmlToJson(String fileName) throws DocumentException { Map<String, Object> xmlMap = xmlToMap(fileName); return JSONUtil.toJsonStr(xmlMap); } /** * 讀取xml文件,返回map對(duì)象 * * @param fileName 文件路徑 * @return map對(duì)象 * @throws DocumentException 異常 */ public Map<String, Object> xmlToMap(String fileName) throws DocumentException { // 創(chuàng)建saxReader對(duì)象 SAXReader reader = new SAXReader(); // 通過(guò)read方法讀取一個(gè)文件 轉(zhuǎn)換成Document對(duì)象 Document document = reader.read(new File(fileName)); //獲取根節(jié)點(diǎn)元素對(duì)象 Element node = document.getRootElement(); //遍歷所有的元素節(jié)點(diǎn) Map<String, Object> map = getNewMap(); // 處理節(jié)點(diǎn) listNodes(node, map); return map; } /** * 遍歷當(dāng)前節(jié)點(diǎn)元素下面的所有(元素的)子節(jié)點(diǎn) * * @param node node */ public void listNodes(Element node, Map<String, Object> map) { Map<String, Object> xiaoMap = getNewMap(); String nodeKey = node.getName(); // 獲取當(dāng)前節(jié)點(diǎn)的所有屬性節(jié)點(diǎn) List<Attribute> list = node.attributes(); // 遍歷屬性節(jié)點(diǎn) Map<String, Object> attrMap = getNewMap(); for (Attribute attr : list) { attrMap.put(attr.getName(), attr.getValue()); } if (ObjectUtil.isNotEmpty(attrMap)) { xiaoMap.put(TAG_ATTR, attrMap); } // 當(dāng)前節(jié)點(diǎn)下面子節(jié)點(diǎn)迭代器 Iterator<Element> it = node.elementIterator(); if (!("".equals(node.getTextTrim())) || !it.hasNext()) { map.put(nodeKey, node.getTextTrim()); }else{ // 不為空 if (ObjectUtil.isEmpty(map.get(nodeKey))) { map.put(nodeKey, xiaoMap); } else { List<Map<String, Object>> childList = null; // 獲取原來(lái)的 Object obj = map.get(nodeKey); if (obj instanceof Iterable) { // 非第一個(gè) childList = (List<Map<String, Object>>) obj; childList.add(xiaoMap); } else if (obj instanceof Map) { // 第一個(gè) Map<String, Object> childMap = (Map<String, Object>) obj; childList = new ArrayList<>(); childList.add(childMap); childList.add(xiaoMap); } // 添加新的 map.put(nodeKey, childList); } } // 遍歷 while (it.hasNext()) { // 獲取某個(gè)子節(jié)點(diǎn)對(duì)象 Element e = it.next(); // 對(duì)子節(jié)點(diǎn)進(jìn)行遍歷 listNodes(e, xiaoMap); } } /** * 獲取一個(gè)新的map對(duì)象 * * @return map對(duì)象 */ private Map<String, Object> getNewMap() { Object obj = null; try { obj = xmlSort.getMapClass().newInstance(); if (obj instanceof Map) { return (Map<String, Object>) obj; } } catch (InstantiationException | IllegalAccessException e) { e.printStackTrace(); } return null; } /** * 設(shè)置是否排序 * * @param xmlSort 是否排序?qū)ο? */ public void setXmlSort(XmlSort xmlSort) { this.xmlSort = xmlSort; } }
5 JavaBean與Xml互轉(zhuǎn)_使用XStream實(shí)現(xiàn),很實(shí)用 [強(qiáng)烈推薦使用]
說(shuō)明:
相對(duì)于JAXB,XStream更簡(jiǎn)潔一些。
常用注解:
- @XStreamAlias:定義xml節(jié)點(diǎn)名
- @XStreamAsAttribute:把字段節(jié)點(diǎn)設(shè)置成屬性
5-1 引入XStream依賴(lài)
<dependency> <groupId>com.thoughtworks.xstream</groupId> <artifactId>xstream</artifactId> <version>1.4.19</version> </dependency>
5-2 工具類(lèi)XStreamXmlBeanUtil
import com.thoughtworks.xstream.XStream; /** * XStream 實(shí)現(xiàn)bean與xml之間相互轉(zhuǎn)換 */ public class XStreamXmlBeanUtil { /** * JavaBean轉(zhuǎn)XML * @param bean - JavaBean * @return - XML */ public static String toXml(Object bean) { return initXStream(bean.getClass()).toXML(bean); } /** * XML轉(zhuǎn)JavaBean * @param xml - XML * @param beanClazz - JavaBean Class * @param <T> * @return - JavaBean */ @SuppressWarnings("unchecked") public static <T> T fromXml(String xml, Class<T> beanClazz) { return (T) initXStream(beanClazz).fromXML(xml); } private static XStream initXStream(Class<?> beanClazz) { XStream x = new XStream(); x.registerConverter(new DateConverter("yyyy-MM-dd HH:mm:ss", null,TimeZone.getTimeZone("GMT+8"))); //不使用默認(rèn)的類(lèi)加載器,需要手動(dòng)設(shè)置類(lèi)加載器 x.setClassLoader(beanClazz.getClassLoader()); x.processAnnotations(beanClazz); x.allowTypesByRegExp(new String[]{".*"}); // 開(kāi)起注解功能 x.autodetectAnnotations(true); // 忽律未知字段 x.ignoreUnknownElements(); return x; } }
5-3 使用實(shí)例
import com.thoughtworks.xstream.annotations.XStreamAlias; import lombok.AllArgsConstructor; import lombok.Data; import lombok.NoArgsConstructor; public class Test { public static void main(String[] args) { // 1. 普通bean與Xml互轉(zhuǎn) User user = new User("貂蟬", 18, "女"); System.out.println("============普通bean轉(zhuǎn)Xml==============="); String xml = XStreamXmlBeanUtil.toXml(user); System.out.println(xml); System.out.println("============Xml轉(zhuǎn)普通bean==============="); System.out.println(XStreamXmlBeanUtil.fromXml(xml, User.class)); // 2. 繼承bean與Xml互轉(zhuǎn) Child child = new Child("吃糖葫蘆"); child.setName("葫蘆娃"); child.setAge(2); child.setGender("男"); child.setHobby("打游戲"); System.out.println("============繼承bean轉(zhuǎn)Xml==============="); xml = XStreamXmlBeanUtil.toXml(child); System.out.println(xml); System.out.println("============Xml轉(zhuǎn)繼承bean===="); // 生成的Xml僅有Child的屬性hobby,但轉(zhuǎn)后后的Child對(duì)象,父屬性都是有值的; System.out.println(XStreamXmlBeanUtil.fromXml(xml, Child.class)); System.out.println("============Xml轉(zhuǎn)繼承bean,測(cè)試轉(zhuǎn)換后,父屬性、自身屬性是否有值===="); Child c2 = XStreamXmlBeanUtil.fromXml(xml, Child.class); System.out.println( "11111==" + c2.getName() + c2.getGender() + c2.getHobby()); // 輸出內(nèi)容如下: // ============普通bean轉(zhuǎn)Xml=============== // <Women> // <name>貂蟬</name> // <age>18</age> // <gender>女</gender> // </Women> // ============Xml轉(zhuǎn)普通bean=============== // XmlTest.User(name=貂蟬, age=18, gender=女) // ============繼承bean轉(zhuǎn)Xml=============== // <User> // <name>葫蘆娃</name> // <age>2</age> // <gender>男</gender> // <hobby>打游戲</hobby> // </User> // ============Xml轉(zhuǎn)繼承bean==== // XmlTest.Child(hobby=打游戲) // 11111==葫蘆娃男打游戲 } } @Data @NoArgsConstructor @AllArgsConstructor @XStreamAlias("Women") class User { private String name; private int age; private String gender; } @NoArgsConstructor @AllArgsConstructor @Data @XStreamAlias("User") class Child extends User { private String hobby; }
5-4 關(guān)于XStream更詳細(xì)的使用,如設(shè)置別名、設(shè)置屬性、隱藏集合根節(jié)點(diǎn)等,請(qǐng)參考如下博文
總結(jié)
到此這篇關(guān)于Java中操作Xml使用方法備忘錄的文章就介紹到這了,更多相關(guān)Java操作Xml使用內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
解決Mybatis 大數(shù)據(jù)量的批量insert問(wèn)題
這篇文章主要介紹了解決Mybatis 大數(shù)據(jù)量的批量insert問(wèn)題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧2021-01-01淺談java中math類(lèi)中三種取整函數(shù)的區(qū)別
下面小編就為大家?guī)?lái)一篇淺談java中math類(lèi)中三種取整函數(shù)的區(qū)別。小編覺(jué)得挺不錯(cuò)的,現(xiàn)在就分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧2016-11-11Java線程池ThreadPoolExecutor原理及使用實(shí)例
這篇文章主要介紹了Java線程池ThreadPoolExecutor原理及使用實(shí)例,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下2020-05-05在java中使用SPI創(chuàng)建可擴(kuò)展的應(yīng)用程序操作
這篇文章主要介紹了在java中使用SPI創(chuàng)建可擴(kuò)展的應(yīng)用程序操作,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧2020-09-09Spring Boot通過(guò)Junit實(shí)現(xiàn)單元測(cè)試過(guò)程解析
這篇文章主要介紹了Spring Boot通過(guò)Junit實(shí)現(xiàn)單元測(cè)試過(guò)程解析,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下2020-01-01Java 實(shí)現(xiàn)完整功能的學(xué)生管理系統(tǒng)實(shí)例
讀萬(wàn)卷書(shū)不如行萬(wàn)里路,只學(xué)書(shū)上的理論是遠(yuǎn)遠(yuǎn)不夠的,只有在實(shí)戰(zhàn)中才能獲得能力的提升,本篇文章手把手帶你用Java實(shí)現(xiàn)一個(gè)完整版學(xué)生管理系統(tǒng),大家可以在過(guò)程中查缺補(bǔ)漏,提升水平2021-11-11Java ArrayList add(int index, E element)和set(int index, E el
今天小編就為大家分享一篇關(guān)于Java ArrayList add(int index, E element)和set(int index, E element)兩個(gè)方法的說(shuō)明,小編覺(jué)得內(nèi)容挺不錯(cuò)的,現(xiàn)在分享給大家,具有很好的參考價(jià)值,需要的朋友一起跟隨小編來(lái)看看吧2018-10-10Java控制結(jié)構(gòu)知識(shí)點(diǎn)詳解
在本篇文章里小編給大家分享的是關(guān)于Java控制結(jié)構(gòu)知識(shí)點(diǎn)詳解,有需要的朋友們可以參考下。2019-10-10