java中xml和对象之间的互相转换方法
作者:怼怼_bml
例子是把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) 实现XML与Bean的相互转换
简介
JAXB是一个业界的标准,是一项可以根据XML Schema
产生Java
类的技术。该过程中,JAXB也提供了将XML实例文档反向生成Java
对象树的方法,并能将Java
对象树的内容重新写到 XML
实例文档。
Jaxb 2.0是JDK 1.6的组成部分。我们不需要下载第三方jar包 即可做到轻松转换。Jaxb2使用了JDK的新特性,如:Annotation
、GenericType
等,需要在即将转换的JavaBean
中添加annotation
注解。
重要的使用有:
JAXBContext
类,是应用的入口,用于管理XML/Java绑定信息。Marshaller
接口,将Java对象序列化为XML数据。Unmarshaller
接口,将XML数据反序列化为Java对象。@XmlType
,将Java类或枚举类型映射到XML模式类型@XmlAccessorType(XmlAccessType.FIELD)
,控制字段或属性的序列化。FIELD
表示JAXB
将自动绑定Java类中的每个非静态的(static)、非瞬态的(由@XmlTransient
标 注)字段到XML。其他值还有XmlAccessType
.PROPERTY
和XmlAccessType.NONE
。@XmlAccessorOrder
,控制JAXB 绑定类中属性和字段的排序。@XmlJavaTypeAdapter
,使用定制的适配器(即扩展抽象类XmlAdapter并覆盖marshal()和unmarshal()方法),以序列化Java类为XML。@XmlElementWrapper
,对于数组或集合(即包含多个元素的成员变量),生成一个包装该数组或集合的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的属性一一对应
需要有个工具类XmlBuilder,主要是将XML转为指定的对象里面只需要一个方法
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转为指定的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 转为对象的接口 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转为指定的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(); // 将流转换为字符串 byte[] b = new byte[4096]; for (int n; (n = in.read(b)) != -1; ) { xml.append(new String(b, 0, n, StandardCharsets.UTF_8)); } // XML转为Java对象 CityList cityList = (CityList) XmlBuilder.JAXB_XmlToBean(CityList.class, xml.toString()); return cityList; } catch (Exception e) { e.printStackTrace(); } return null; } }
第二种方法是使用XStream
利用XStream在Java对象和XML之间相互转换
简介
Xstream是一种OXMapping
技术,是用来处理XML
文件序列化的框架,在将JavaBean
序列化,或将XML
文件反序列化的时候,不需要其它辅助类和映射文件,使得XML
序列化不再繁索。Xstream也可以将JavaBean
序列化成Json
或反序列化,使用非常方便。
主要使用
@XStreamAlias(“alis”)
java对象在xml中以标签的形式显示时,如果名字与类名或者属性名不一致,可以使用该标签并在括号内注明别名。@XStreamOmitField
在输出XML的时候忽略该属性@XStreamImplicit
如果该属性是一个列表或者数组,在XML中不显示list或者Array字样@XStreamAsAttribute
该属性不单独显示成XML节点,而是作为属性显示出来@XStreamContainedType
@XStreamConverter
设置转换器@XStreamConverters
converter主要用于将某些字段进行复杂的转换,转换过程写在一个类中。
然后将其注册到XStream。
首先导入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; }
两个内层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()); // 设置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(); //不使用默认的类加载器,需要手动设置类加载器 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的属性名一一对应,一旦不对应就会报com.thoughtworks.xstream.mapper.CannotResolveClassException
异常,找不到对应的类属性
集合属性的需要使用:@XStreamImplicit
,不然会报com.thoughtworks.xstream.converters.reflection.AbstractReflectionConverter$DuplicateFieldException
转换器映射异常
省略集合根节点:@XStreamImplicit
把字段节点设置成属性:@XStreamAsAttribute
拓展了解
XStream提供了很多方法供我们使用
autodetectAnnotations()
自动检测注解processAnnotations()
应用传过来的类的注解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();
默认情况下,XStream
会 采用Xpp3
库,XPP3
是一种运行效率非常高的XML全解析实现。如果你不想依靠Xpp3
库的话,也可以使用一个标准的JAXP DOM
解析器,可以采用以下语句进行初始化:
//不使用XPP3
库
XStreamxstream = new XStream(new DomDriver());
此xstream实例,为线程安全的,可以供多个线程进行调用,共享使用。系统提供了多种标识解析器供我们选择,包括,DomDriver
、 JDomDriver
、StaxDriver
等等。
Xstream提供了对Json的支持,是因为Xstream内置了两个Driver:
1.JsonHierarchicalStreamDriver
:不依赖其他类库,只实现 obj->JSON
2.JettisonMappedXmlDriver
:依赖jettison
类库,实现 JSON->obj
or obj->JSON
两种Driver在处理相同设置的Object时会得到不同的JSON串,JsonHierarchicalStreamDriver
得到的串更简洁,确如官网所说。JsonHierarchicalStreamDriver
有个小问题——默认输出带格式的JSON
串,结构中带空举
总结
到此这篇关于java中xml和对象之间的互相转换方法的文章就介绍到这了,更多相关java xml和对象互相转换内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!