java中xml和對象之間的互相轉(zhuǎn)換方法
例子是把xml映射成bean成對象
<?xml version="1.0" encoding="UTF-8"?> <c c1="0"> <d d1="101280101" d2="重慶" d3="nanping" d4="南坪"/> <d d1="101280102" d2="重慶" d3="yubei" d4="渝北"/> <d d1="101280103" d2="重慶" d3="dadukou" d4="大渡口"/> </c>
第一種方法是使用 JAXB(Java Architecture for XML Binding) 實(shí)現(xiàn)XML與Bean的相互轉(zhuǎn)換
簡介
JAXB是一個業(yè)界的標(biāo)準(zhǔn),是一項可以根據(jù)XML Schema
產(chǎn)生Java
類的技術(shù)。該過程中,JAXB也提供了將XML實(shí)例文檔反向生成Java
對象樹的方法,并能將Java
對象樹的內(nèi)容重新寫到 XML
實(shí)例文檔。
Jaxb 2.0是JDK 1.6的組成部分。我們不需要下載第三方j(luò)ar包 即可做到輕松轉(zhuǎn)換。Jaxb2使用了JDK的新特性,如:Annotation
、GenericType
等,需要在即將轉(zhuǎn)換的JavaBean
中添加annotation
注解。
重要的使用有:
JAXBContext
類,是應(yīng)用的入口,用于管理XML/Java綁定信息。Marshaller
接口,將Java對象序列化為XML數(shù)據(jù)。Unmarshaller
接口,將XML數(shù)據(jù)反序列化為Java對象。@XmlType
,將Java類或枚舉類型映射到XML模式類型@XmlAccessorType(XmlAccessType.FIELD)
,控制字段或?qū)傩缘男蛄谢?code>FIELD表示JAXB
將自動綁定Java類中的每個非靜態(tài)的(static)、非瞬態(tài)的(由@XmlTransient
標(biāo) 注)字段到XML。其他值還有XmlAccessType
.PROPERTY
和XmlAccessType.NONE
。@XmlAccessorOrder
,控制JAXB 綁定類中屬性和字段的排序。@XmlJavaTypeAdapter
,使用定制的適配器(即擴(kuò)展抽象類XmlAdapter并覆蓋marshal()和unmarshal()方法),以序列化Java類為XML。@XmlElementWrapper
,對于數(shù)組或集合(即包含多個元素的成員變量),生成一個包裝該數(shù)組或集合的XML元素(稱為包裝器)。@XmlRootElement
,將Java類或枚舉類型映射到XML元素。@XmlElement
,將Java類的一個屬性映射到與屬性同名的一個XML元素。@XmlAttribute
,將Java類的一個屬性映射到與屬性同名的一個XML屬性。
city的bean
import lombok.Data; import javax.xml.bind.annotation.XmlAccessType; import javax.xml.bind.annotation.XmlAccessorType; import javax.xml.bind.annotation.XmlAttribute; import javax.xml.bind.annotation.XmlRootElement; @Data //根元素 @XmlRootElement(name = "d") //訪問類型,通過字段 @XmlAccessorType(XmlAccessType.FIELD) public class City { @XmlAttribute(name = "d1") private String cityId; @XmlAttribute(name = "d2") private String cityName; @XmlAttribute(name = "d3") private String cityCode; @XmlAttribute(name = "d4") private String area; }
CityList的bean
import lombok.Data; import javax.xml.bind.annotation.XmlAccessType; import javax.xml.bind.annotation.XmlAccessorType; import javax.xml.bind.annotation.XmlElement; import javax.xml.bind.annotation.XmlRootElement; import java.util.List; @Data @XmlRootElement(name = "c") @XmlAccessorType(XmlAccessType.FIELD) public class CityList { @XmlElement(name = "d") private List<City> cityList; }
需要指定bean中的屬性和xml的屬性一一對應(yīng)
需要有個工具類XmlBuilder,主要是將XML轉(zhuǎn)為指定的對象里面只需要一個方法
import com.thoughtworks.xstream.XStream; import javax.xml.bind.JAXBContext; import javax.xml.bind.Unmarshaller; import java.io.Reader; import java.io.StringReader; public class XmlBuilder { /** * JAXB將XML轉(zhuǎn)為指定的POJO * * @param clazz * @param xml * @return */ public static Object JAXB_XmlToBean(Class<?> clazz, String xml) { try { Object xmlObject; Reader reader; JAXBContext context = JAXBContext.newInstance(clazz); // XML 轉(zhuǎn)為對象的接口 Unmarshaller unmarshaller = context.createUnmarshaller(); reader = new StringReader(xml); //以文件流的方式傳入這個string xmlObject = unmarshaller.unmarshal(reader); reader.close(); return xmlObject; } catch (Exception e) { e.printStackTrace(); } return null; } /** * XStream將XML轉(zhuǎn)為指定的POJO * * @param clazz * @param xml * @return */ public static Object XStream_ToBean(Class<?> clazz, String xml) { Object xmlObject; XStream xstream = new XStream(); xstream.processAnnotations(clazz); xstream.autodetectAnnotations(true); xmlObject = xstream.fromXML(xml); return xmlObject; } }
controller
import com.zoo.weixin.test.api.xstream.CityList; import com.zoo.weixin.test.api.xstream.XmlBuilder; import lombok.Cleanup; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; import javax.servlet.ServletInputStream; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import java.nio.charset.StandardCharsets; @RestController public class XStreamController { @RequestMapping("JAXB") public CityList XStream(HttpServletRequest request, HttpServletResponse response) { StringBuilder xml = new StringBuilder(); try { @Cleanup ServletInputStream in = request.getInputStream(); // 將流轉(zhuǎn)換為字符串 byte[] b = new byte[4096]; for (int n; (n = in.read(b)) != -1; ) { xml.append(new String(b, 0, n, StandardCharsets.UTF_8)); } // XML轉(zhuǎn)為Java對象 CityList cityList = (CityList) XmlBuilder.JAXB_XmlToBean(CityList.class, xml.toString()); return cityList; } catch (Exception e) { e.printStackTrace(); } return null; } }
第二種方法是使用XStream
利用XStream在Java對象和XML之間相互轉(zhuǎn)換
簡介
Xstream是一種OXMapping
技術(shù),是用來處理XML
文件序列化的框架,在將JavaBean
序列化,或?qū)?code>XML文件反序列化的時候,不需要其它輔助類和映射文件,使得XML
序列化不再繁索。Xstream也可以將JavaBean
序列化成Json
或反序列化,使用非常方便。
主要使用
@XStreamAlias(“alis”)
java對象在xml中以標(biāo)簽的形式顯示時,如果名字與類名或者屬性名不一致,可以使用該標(biāo)簽并在括號內(nèi)注明別名。@XStreamOmitField
在輸出XML的時候忽略該屬性@XStreamImplicit
如果該屬性是一個列表或者數(shù)組,在XML中不顯示list或者Array字樣@XStreamAsAttribute
該屬性不單獨(dú)顯示成XML節(jié)點(diǎn),而是作為屬性顯示出來@XStreamContainedType
@XStreamConverter
設(shè)置轉(zhuǎn)換器@XStreamConverters
converter主要用于將某些字段進(jìn)行復(fù)雜的轉(zhuǎn)換,轉(zhuǎn)換過程寫在一個類中。
然后將其注冊到XStream。
首先導(dǎo)入jar包
<!--xstream--> <dependency> <groupId>com.thoughtworks.xstream</groupId> <artifactId>xstream</artifactId> <version>1.4.11.1</version> </dependency>
最外層bean
package com.guoyao.emergency.vo; import com.thoughtworks.xstream.annotations.XStreamAlias; import lombok.Data; import java.io.Serializable; @Data @XStreamAlias("InterFaceFile") public class xmlVo implements Serializable { private static final long serialVersionUID = 1L; @XStreamAlias("employee") Employee employee; @XStreamAlias("user") User user; }
兩個內(nèi)層bean
package com.guoyao.emergency.vo; import com.guoyao.emergency.common.MessageType; import com.thoughtworks.xstream.annotations.XStreamAlias; import lombok.Data; import org.springframework.beans.factory.annotation.Autowired; import java.io.Serializable; @Data @XStreamAlias("employee") public class Employee implements Serializable { private static final long serialVersionUID = 1L; @XStreamAlias("employeeId") private int employeeId; @XStreamAlias("employeeName") private String employeeName; @XStreamAlias("department") private String department; public Employee() { } public String getDepartment() { return department; } public void setDepartment(String department) { this.department = department; } public int getEmployeeId() { return employeeId; } public void setEmployeeId(int employeeId) { this.employeeId = employeeId; } public String getEmployeeName() { return employeeName; } public void setEmployeeName(String employeeName) { this.employeeName = employeeName; } public Employee(int employeeId, String employeeName, String department) { this.employeeId = employeeId; this.employeeName = employeeName; this.department = department; } }
package com.guoyao.emergency.vo; import com.thoughtworks.xstream.annotations.XStreamAlias; import lombok.Data; @Data @XStreamAlias("user") public class User { @XStreamAlias("username") private String username; @XStreamAlias("password") private String password; @XStreamAlias("number") private int number; public User(String username, String password, int number) { this.username = username; this.password = password; this.number = number; } public User() { this.username = username; this.password = password; } }
工具類及使用方法
package com.guoyao.emergency.util; import com.guoyao.emergency.common.IBasicXml; import com.guoyao.emergency.vo.Employee; import com.guoyao.emergency.vo.User; import com.guoyao.emergency.vo.xmlVo; import com.thoughtworks.xstream.XStream; import com.thoughtworks.xstream.io.xml.DomDriver; import org.springframework.beans.factory.annotation.Value; import org.w3c.dom.Document; import org.xml.sax.InputSource; import org.xml.sax.SAXException; import javax.xml.parsers.DocumentBuilder; import javax.xml.parsers.DocumentBuilderFactory; import javax.xml.parsers.ParserConfigurationException; import javax.xml.transform.Transformer; import javax.xml.transform.TransformerException; import javax.xml.transform.TransformerFactory; import javax.xml.transform.dom.DOMSource; import javax.xml.transform.stream.StreamResult; import java.io.File; import java.io.IOException; import java.io.StringReader; /** * @Description: 將Java對象序列化成XML格式,將XML反序列化還原為Java對象 */ public class xmlUtil extends XStream { /** * 將Java對象序列化成XML格式 * * @param vo * @return * @throws IOException */ public static String serialize(xmlVo vo) { // 將employee對象序列化為XML XStream xStream = new XStream(new DomDriver()); // 設(shè)置employee類的別名 xStream.alias("InterFaceFile", xmlVo.class); String personXml = xStream.toXML(vo); return personXml; } /** * 將XML反序列化還原為Java對象 * * @param personXml * @return */ public xmlVo deserialize(String personXml) { // 將employee對象序列化為XML XStream xstream = new XStream(new DomDriver()); XStream.setupDefaultSecurity(this); // to be removed after 1.5 xstream.allowTypesByWildcard(new String[]{ "com.xttblog.package.**" }); xmlVo employee = (xmlVo) xstream.fromXML(personXml); return employee; } /** * 將XML反序列化還原為Java對象 * java對象類型可配置 * * @param xmlStr * @return */ public static <T> T xmlToBean(String xmlStr, Class<T> cls) { XStream xstream = new XStream(); //不使用默認(rèn)的類加載器,需要手動設(shè)置類加載器 xstream.setClassLoader(cls.getClassLoader()); xstream.processAnnotations(cls); xstream.allowTypesByRegExp(new String[]{".*"}); Object obj = xstream.fromXML(xmlStr); return (T) obj; } /** * 生成Xml文件,可以寫入指定路徑 * * @param xmlSource * @throws SAXException * @throws ParserConfigurationException * @throws IOException * @throws TransformerException */ public static void stringToDom(String xmlSource) throws SAXException, ParserConfigurationException, IOException, TransformerException { // Parse the given input DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance(); DocumentBuilder builder = factory.newDocumentBuilder(); Document doc = builder.parse(new InputSource(new StringReader(xmlSource))); // Write the parsed document to an xml file TransformerFactory transformerFactory = TransformerFactory.newInstance(); Transformer transformer = transformerFactory.newTransformer(); DOMSource source = new DOMSource(doc); System.out.println(source); StreamResult result = new StreamResult(new File("my-file.xml")); transformer.transform(source, result); } public static void main(String[] args) throws IOException, ParserConfigurationException, TransformerException, SAXException { xmlVo vo = new xmlVo(); Employee employee = new Employee(); employee.setEmployeeId(1); employee.setEmployeeName("趙新國1111"); employee.setDepartment("軟件工程師"); User user = new User(); user.setUsername("zhangsan"); user.setPassword("10"); vo.setEmployee(employee); vo.setUser(user); // 序列化 String serialize = serialize(vo); System.out.println(serialize); // stringToDom(serialize); // 反序列化 xmlVo xmlVo = xmlToBean(serialize, xmlVo.class); System.out.println(xmlVo.toString()); User user1 = xmlVo.getUser(); System.out.println(user1.getUsername()); // xmlUtil util = new xmlUtil(); // xmlVo deserialize = util.deserialize(serialize); // System.out.println(deserialize.toString()); // User user1 = deserialize.getUser(); // System.out.println(user1.getUsername()); } }
重命名注解:@XStreamAlias()
這些命名都需要和解析的xml的屬性名一一對應(yīng),一旦不對應(yīng)就會報com.thoughtworks.xstream.mapper.CannotResolveClassException
異常,找不到對應(yīng)的類屬性
集合屬性的需要使用:@XStreamImplicit
,不然會報com.thoughtworks.xstream.converters.reflection.AbstractReflectionConverter$DuplicateFieldException
轉(zhuǎn)換器映射異常
省略集合根節(jié)點(diǎn):@XStreamImplicit
把字段節(jié)點(diǎn)設(shè)置成屬性:@XStreamAsAttribute
拓展了解
XStream提供了很多方法供我們使用
autodetectAnnotations()
自動檢測注解processAnnotations()
應(yīng)用傳過來的類的注解fromXML()
XML反序列化(JSON也是一樣)toXML()
XML序列化(JSON也是一樣)
自定義解析器
Xstream序列化XML
,解析器用StaxDriver
指定解析器:XStream xstream = new XStream(new StaxDriver());
Xstream序列化Json
,解析器用JettisonMappedXmlDriver
指定解析器:XStream xstream = new XStream(new JettisonMappedXmlDriver());
也可以不具體指定解析器,也是沒問題的
深入了解
XStreamxstream = new XStream();
默認(rèn)情況下,XStream
會 采用Xpp3
庫,XPP3
是一種運(yùn)行效率非常高的XML全解析實(shí)現(xiàn)。如果你不想依靠Xpp3
庫的話,也可以使用一個標(biāo)準(zhǔn)的JAXP DOM
解析器,可以采用以下語句進(jìn)行初始化:
//不使用XPP3
庫
XStreamxstream = new XStream(new DomDriver());
此xstream實(shí)例,為線程安全的,可以供多個線程進(jìn)行調(diào)用,共享使用。系統(tǒng)提供了多種標(biāo)識解析器供我們選擇,包括,DomDriver
、 JDomDriver
、StaxDriver
等等。
Xstream提供了對Json的支持,是因?yàn)閄stream內(nèi)置了兩個Driver:
1.JsonHierarchicalStreamDriver
:不依賴其他類庫,只實(shí)現(xiàn) obj->JSON
2.JettisonMappedXmlDriver
:依賴jettison
類庫,實(shí)現(xiàn) JSON->obj
or obj->JSON
兩種Driver在處理相同設(shè)置的Object時會得到不同的JSON串,JsonHierarchicalStreamDriver
得到的串更簡潔,確如官網(wǎng)所說。JsonHierarchicalStreamDriver
有個小問題——默認(rèn)輸出帶格式的JSON
串,結(jié)構(gòu)中帶空舉
總結(jié)
到此這篇關(guān)于java中xml和對象之間的互相轉(zhuǎn)換方法的文章就介紹到這了,更多相關(guān)java xml和對象互相轉(zhuǎn)換內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
- java利用JAXB實(shí)現(xiàn)對象和xml互相轉(zhuǎn)換方法與實(shí)例詳解
- 通過實(shí)例學(xué)習(xí)JAVA對象轉(zhuǎn)成XML輸出
- 將Java對象序列化成JSON和XML格式的實(shí)例
- Java對象的XML序列化與反序列化實(shí)例解析
- xml與Java對象的轉(zhuǎn)換詳解
- XML到Java代碼的數(shù)據(jù)綁定之對象
- Javabean基于xstream包實(shí)現(xiàn)轉(zhuǎn)XML文檔的方法
- 使用asx3m與xstream配合解決flex與java利用httpservice傳遞xml數(shù)據(jù)問題
- java使用xstream實(shí)現(xiàn)xml文件和對象之間的相互轉(zhuǎn)換
相關(guān)文章
MyBatis攔截器:給參數(shù)對象屬性賦值的實(shí)例
下面小編就為大家?guī)硪黄狹yBatis攔截器:給參數(shù)對象屬性賦值的實(shí)例。小編覺得挺不錯的,現(xiàn)在就分享給大家,也給大家做個參考。一起跟隨小編過來看看吧2017-04-04Mybatis?Plus?QueryWrapper復(fù)合用法詳解
這篇文章主要介紹了Mybatis?Plus?QueryWrapper復(fù)合用法詳解,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教。2022-01-01java 中動態(tài)代理(JDK,cglib)實(shí)例代碼
這篇文章主要介紹了java 中動態(tài)代理,這里介紹了JDK 動態(tài)代理與 cglib 動態(tài)代理的相關(guān)資料2017-04-04Jenkins自動部署SpringBoot項目實(shí)踐教程
這篇文章主要介紹了Jenkins自動部署SpringBoot項目實(shí)踐教程,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教2021-11-11Java中ByteArrayInputStream和ByteArrayOutputStream用法詳解
這篇文章主要介紹了Java中ByteArrayInputStream和ByteArrayOutputStream用法詳解,?ByteArrayInputStream?的內(nèi)部額外的定義了一個計數(shù)器,它被用來跟蹤?read()?方法要讀取的下一個字節(jié)2022-06-06scala+redis實(shí)現(xiàn)分布式鎖的示例代碼
這篇文章主要介紹了scala+redis實(shí)現(xiàn)分布式鎖的示例代碼,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2019-06-06