Java对象和XML的相互转换化

https://blog.csdn.net/u010331823/article/details/78258311

写在前面:Jaxb是JavaEE的规范.全称Java Architecture for XML Binding.  可以根据XML Schema产生Java类的技术.JAXB也提供了将XML实例文档反向生成Java对象树的方法,并能将Java对象树的内容重新写到XML实例文档.  JAXB 2.0是JDK 1.6的组成部分。JAXB 2.2.3是JDK 1.7的组成部分,在实际使用不需要引入新的jar.

1. 常用注解说明
常用的annotation有:
@XmlType
@XmlElement
@XmlRootElement
@XmlAttribute
@XmlAccessorType
@XmlAccessorOrder
@XmlTransient
@XmlJavaTypeAdapter
@Temporal(TemporalType.XXXX) -->JPA中的时间处理注解,非JAXB
@XmlElementWrapper

[email protected]
  @XmlType用在class类的注解,常与@XmlRootElement,@XmlAccessorType一起使用。它有三个属性:name、propOrder、namespace,经常使用的只有前两个属性。如:
同时使用了@XmlType(propOrder={})和@XmlAccessorOrder(XmlAccessOrder.ALPHABETICAL)的时候,生成的xml只按照propOrder定义的顺序生成元素
@XmlType(name = "basicStruct", propOrder = {
    "intValue",
    "stringArray",
    "stringValue"
)
在使用@XmlType的propOrder 属性时,必须列出JavaBean对象中的所有属性,否则会报错。

[email protected]
  @XmlRootElement用于类级别的注解,对应xml的跟元素,常与 @XmlType 和 @XmlAccessorType一起使用。如:
  @XmlType
  @XmlAccessorType(XmlAccessType.FIELD)
  @XmlRootElement
  public class Address {}

[email protected]
  @XmlElement将java对象的属性映射为xml的节点,在使用@XmlElement时,可通过name属性改变java对象属性在xml中显示的名称。如:
  @XmlElement(name="Address")  
  private String yourAddress;

[email protected]
  @XmlAttribute用于把java对象的属性映射为xml的属性,并可通过name属性为生成的xml属性指定别名。如:
  @XmlAttribute(name="Country")
  private String state;
 
[email protected]
  @XmlAccessorType用于指定由java对象生成xml文件时对java对象属性的访问方式。常与@XmlRootElement、@XmlType一起使用。它的属性值是XmlAccessType的4个枚举值,分别为:

XmlAccessType.FIELD:java对象中的所有成员变量
XmlAccessType.PROPERTY:java对象中所有通过getter/setter方式访问的成员变量
XmlAccessType.PUBLIC_MEMBER:java对象中所有的public访问权限的成员变量和通过getter/setter方式访问的成员变量
XmlAccessType.NONE:java对象的所有属性都不映射为xml的元素
注意:@XmlAccessorType的默认访问级别是XmlAccessType.PUBLIC_MEMBER,因此,如果java对象中的private成员变量设置了public权限的getter/setter方法,就不要在private变量上使用@XmlElement和@XmlAttribute注解,否则在由java对象生成xml时会报同一个属性在java类里存在两次的错误。同理,如果@XmlAccessorType的访问权限为XmlAccessType.NONE,如果在java的成员变量上使用了@XmlElement或@XmlAttribute注解,这些成员变量依然可以映射到xml文件。

注意:虽然@XmlAccessorType为XmlAccessType.NONE,但是在java类的私有属性上加了@XmlAttribute和@XmlElement注解后,这些私有成员会映射生成xml的元素

[email protected]
  @XmlAccessorOrder用于对java对象生成的xml元素进行排序。它有两个属性值:
  AccessorOrder.ALPHABETICAL:对生成的xml元素按字母书序排序
  XmlAccessOrder.UNDEFINED:不排序

[email protected]
  @XmlTransient用于标示在由java对象映射xml时,忽略此属性。即,在生成的xml文件中不出现此元素。

[email protected]
  @XmlJavaTypeAdapter常用在转换比较复杂的对象时,如map类型或者格式化日期等。使用此注解时,需要自己写一个adapter类继承XmlAdapter抽象类,并实现里面的方法。
  @XmlJavaTypeAdapter(value=xxx.class),value为自己定义的adapter类
  XmlAdapter 抽象接口如下:

public abstract class XmlAdapter<ValueType,BoundType> {    // Do-nothing constructor for the derived classes.
    protected XmlAdapter() {}
    // Convert a value type to a bound type.
    public abstract BoundType unmarshal(ValueType v);
    // Convert a bound type to a value type.
    public abstract ValueType marshal(BoundType v);
 }

下面举一个简单的例子:

1.School类 一些基本的属性,包含Student集合

package com.gs.mountain.test.xml;
import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlRootElement;
import java.util.ArrayList;
import java.util.List;
@XmlRootElement(name="list")
public class School {
private String name;
private String address;
private String level;
private long popular;
private List<Student> students=new ArrayList<Student>();
@XmlElement(name = "name")
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
@XmlElement(name = "address")
public String getAddress() {
return address;
}
public void setAddress(String address) {
this.address = address;
}
@XmlElement(name = "level")
public String getLevel() {
return level;
}
public void setLevel(String level) {
this.level = level;
}
@XmlElement(name = "popular")
public long getPopular() {
return popular;
}
public void setPopular(long popular) {
this.popular = popular;
}
@XmlElement(name = "Student")
public List<Student> getStudents() {
return students;
}
public void setStudents(List<Student> students) {
this.students = students;
}
}
2.Student类,包含爱好集合和一些基本的属性

package com.gs.mountain.test.xml;

import javax.xml.bind.annotation.XmlAttribute;
import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlElementWrapper;
import java.util.List;

public class Student {
String name; //姓名
String sex; //性别
int number; //学号
String className; //班级
List<String> hobby; //爱好

public Student(){
}
public Student(String name,String sex,int number,
String className,List<String> hobby) {
this.name = name;
this.sex = sex;
this.number = number;
this.className = className;
this.hobby = hobby;
}
@XmlAttribute(name="name")
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}

@XmlAttribute(name="sex")
public String getSex() {
return sex;
}
public void setSex(String sex) {
this.sex = sex;
}

@XmlAttribute(name="number")
public int getNumber() {
return number;
}
public void setNumber(int number) {
this.number = number;
}

@XmlElement(name="className")
public String getClassName() {
return className;
}
public void setClassName(String className) {
this.className = className;
}

@XmlElementWrapper(name="hobbys")
@XmlElement(name = "hobby")
public List<String> getHobby() {
return hobby;
}
public void setHobby(List<String> hobby) {
this.hobby = hobby;
}

}
3.工具类,提供xml到javaBean的相互转换 由 valvin大神提供,很好用(自己看其中的方法,说不定有你需要的)

/**
* Copyright (c) 2005-2012 springside.org.cn
*/
package com.gs.mountain.common.mapper;

import java.io.StringReader;
import java.io.StringWriter;
import java.util.Collection;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap;

import javax.xml.bind.JAXBContext;
import javax.xml.bind.JAXBElement;
import javax.xml.bind.JAXBException;
import javax.xml.bind.Marshaller;
import javax.xml.bind.Unmarshaller;
import javax.xml.bind.annotation.XmlAnyElement;
import javax.xml.namespace.QName;

import com.gs.mountain.common.utils.StringUtils;
import org.springframework.http.converter.HttpMessageConversionException;
import org.springframework.util.Assert;

import com.gs.mountain.common.utils.Exceptions;
import com.gs.mountain.common.utils.Reflections;

/**
* 使用Jaxb2.0实现XML<->Java Object的Mapper.
*
* 在创建时需要设定所有需要序列化的Root对象的Class.
* 特别支持Root对象是Collection的情形.
*
* @author calvin
* @version 2013-01-15
*/
@SuppressWarnings("rawtypes")
public class JaxbMapper {

private static ConcurrentMap<Class, JAXBContext> jaxbContexts = new ConcurrentHashMap<Class, JAXBContext>();

/**
* Java Object->Xml without encoding.
*/
public static String toXml(Object root) {
Class clazz = Reflections.getUserClass(root);
return toXml(root, clazz, null);
}

/**
* Java Object->Xml with encoding.
*/
public static String toXml(Object root, String encoding) {
Class clazz = Reflections.getUserClass(root);
return toXml(root, clazz, encoding);
}

/**
* Java Object->Xml with encoding.
*/
public static String toXml(Object root, Class clazz, String encoding) {
try {
StringWriter writer = new StringWriter();
createMarshaller(clazz, encoding).marshal(root, writer);
return writer.toString();
} catch (JAXBException e) {
throw Exceptions.unchecked(e);
}
}

/**
* Java Collection->Xml without encoding, 特别支持Root Element是Collection的情形.
*/
public static String toXml(Collection<?> root, String rootName, Class clazz) {
return toXml(root, rootName, clazz, null);
}

/**
* Java Collection->Xml with encoding, 特别支持Root Element是Collection的情形.
*/
public static String toXml(Collection<?> root, String rootName, Class clazz, String encoding) {
try {
CollectionWrapper wrapper = new CollectionWrapper();
wrapper.collection = root;

JAXBElement<CollectionWrapper> wrapperElement = new JAXBElement<CollectionWrapper>(new QName(rootName),
CollectionWrapper.class, wrapper);

StringWriter writer = new StringWriter();
createMarshaller(clazz, encoding).marshal(wrapperElement, writer);

return writer.toString();
} catch (JAXBException e) {
throw Exceptions.unchecked(e);
}
}

/**
* Xml->Java Object.
*/
@SuppressWarnings("unchecked")
public static <T> T fromXml(String xml, Class<T> clazz) {
try {
StringReader reader = new StringReader(xml);
return (T) createUnmarshaller(clazz).unmarshal(reader);
} catch (JAXBException e) {
throw Exceptions.unchecked(e);
}
}

/**
* 创建Marshaller并设定encoding(可为null).
* 线程不安全,需要每次创建或pooling。
*/
public static Marshaller createMarshaller(Class clazz, String encoding) {
try {
JAXBContext jaxbContext = getJaxbContext(clazz);

Marshaller marshaller = jaxbContext.createMarshaller();

marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, Boolean.TRUE);

if (StringUtils.isNotBlank(encoding)) {
marshaller.setProperty(Marshaller.JAXB_ENCODING, encoding);
}

return marshaller;
} catch (JAXBException e) {
throw Exceptions.unchecked(e);
}
}

/**
* 创建UnMarshaller.
* 线程不安全,需要每次创建或pooling。
*/
public static Unmarshaller createUnmarshaller(Class clazz) {
try {
JAXBContext jaxbContext = getJaxbContext(clazz);
return jaxbContext.createUnmarshaller();
} catch (JAXBException e) {
throw Exceptions.unchecked(e);
}
}

protected static JAXBContext getJaxbContext(Class clazz) {
Assert.notNull(clazz, "‘clazz‘ must not be null");
JAXBContext jaxbContext = jaxbContexts.get(clazz);
if (jaxbContext == null) {
try {
jaxbContext = JAXBContext.newInstance(clazz, CollectionWrapper.class);
jaxbContexts.putIfAbsent(clazz, jaxbContext);
} catch (JAXBException ex) {
throw new HttpMessageConversionException("Could not instantiate JAXBContext for class [" + clazz
+ "]: " + ex.getMessage(), ex);
}
}
return jaxbContext;
}

/**
* 封装Root Element 是 Collection的情况.
*/
public static class CollectionWrapper {

@XmlAnyElement
protected Collection<?> collection;
}

}

4.下面是测试的代码,结果很棒,so easy!

package com.gs.mountain.test.xml;

import com.gs.mountain.common.mapper.JaxbMapper;

import javax.xml.bind.JAXBException;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;

public class BeanToXml {

public static void main(String[] args) throws JAXBException, IOException {
List<String> hobby = new ArrayList();
hobby.add("篮球");
hobby.add("音乐");
hobby.add("乒乓球");

List<Student> studentList = new ArrayList();

Student st = new Student("张三","男",10001,"尖子班",hobby);
studentList.add(st);
Student st1 = new Student("李四","男",10002,"普通班",hobby);
studentList.add(st1);
Student st2 = new Student("莉莉","女",10003,"普通班",hobby);
studentList.add(st2);

School school = new School();
School school1 ;
School school2 ;
school.setAddress("成都市武侯区天府五街");
school.setLevel("高级中学");
school.setName("华阳中学");
school.setPopular(5000L);
school.setStudents(studentList);
school1=school;
school2=school;
List<School> listSchool=new ArrayList<School>();
listSchool.add(school);
listSchool.add(school1);
listSchool.add(school2);
String str = JaxbMapper.toXml(listSchool,"schoolList",School.class);

//写入到xml文件中
String xmlPath = "D:/testConfig.xml";
BufferedWriter bfw = new BufferedWriter(new FileWriter(new File(xmlPath)));
bfw.write(str);
bfw.close();
}
}

下面是由listSchool转化成的xml文件,内容如下:

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<schoolList>
<list>
<address>成都市武侯区天府五街</address>
<level>高级中学</level>
<name>华阳中学</name>
<popular>5000</popular>
<Student name="张三" number="10001" sex="男">
<className>尖子班</className>
<hobbys>
<hobby>篮球</hobby>
<hobby>音乐</hobby>
<hobby>乒乓球</hobby>
</hobbys>
</Student>
<Student name="李四" number="10002" sex="男">
<className>普通班</className>
<hobbys>
<hobby>篮球</hobby>
<hobby>音乐</hobby>
<hobby>乒乓球</hobby>
</hobbys>
</Student>
<Student name="莉莉" number="10003" sex="女">
<className>普通班</className>
<hobbys>
<hobby>篮球</hobby>
<hobby>音乐</hobby>
<hobby>乒乓球</hobby>
</hobbys>
</Student>
</list>
<list>
<address>成都市武侯区天府五街</address>
<level>高级中学</level>
<name>华阳中学</name>
<popular>5000</popular>
<Student name="张三" number="10001" sex="男">
<className>尖子班</className>
<hobbys>
<hobby>篮球</hobby>
<hobby>音乐</hobby>
<hobby>乒乓球</hobby>
</hobbys>
</Student>
<Student name="李四" number="10002" sex="男">
<className>普通班</className>
<hobbys>
<hobby>篮球</hobby>
<hobby>音乐</hobby>
<hobby>乒乓球</hobby>
</hobbys>
</Student>
<Student name="莉莉" number="10003" sex="女">
<className>普通班</className>
<hobbys>
<hobby>篮球</hobby>
<hobby>音乐</hobby>
<hobby>乒乓球</hobby>
</hobbys>
</Student>
</list>
<list>
<address>成都市武侯区天府五街</address>
<level>高级中学</level>
<name>华阳中学</name>
<popular>5000</popular>
<Student name="张三" number="10001" sex="男">
<className>尖子班</className>
<hobbys>
<hobby>篮球</hobby>
<hobby>音乐</hobby>
<hobby>乒乓球</hobby>
</hobbys>
</Student>
<Student name="李四" number="10002" sex="男">
<className>普通班</className>
<hobbys>
<hobby>篮球</hobby>
<hobby>音乐</hobby>
<hobby>乒乓球</hobby>
</hobbys>
</Student>
<Student name="莉莉" number="10003" sex="女">
<className>普通班</className>
<hobbys>
<hobby>篮球</hobby>
<hobby>音乐</hobby>
<hobby>乒乓球</hobby>
</hobbys>
</Student>
</list>
</schoolList>

————————————————
版权声明:本文为CSDN博主「mountainGS」的原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/u010331823/java/article/details/78258311

原文地址:https://www.cnblogs.com/zhoading/p/12634435.html

时间: 2024-10-11 06:14:49

Java对象和XML的相互转换化的相关文章

XML编程总结(六)——使用JAXB进行java对象和xml格式之间的相互转换

(六)使用JAXB进行java对象和xml格式之间的相互转换 JAXB能够使用Jackson对JAXB注解的支持实现(jackson-module-jaxb-annotations),既方便生成XML,也方便生成JSON,这样一来可以更好的标志可以转换为JSON对象的JAVA类. JAXB(Java Architecture for XML Binding) 是一个业界的标准,是一项可以根据XML Schema产生Java类的技术.该过程中,JAXB也提供了将XML实例文档反向生成Java对象树

java socket报文通信(三)java对象和xml格式文件的相互转换

前两节讲了socket服务端,客户端的建立以及报文的封装.今天就来讲一下java对象和xml格式文件的相互转换. 上一节中我们列举了一个报文格式,其实我们可以理解为其实就是一个字符串.但是我们不可能每次都去写字符串啊,这样的话肯定要疯.既然是面向对象的编程,肯定会有好的办法来解决这个问题.我们使用JAXBContext这个工具. package cn.com.egj.entity.shortcutTransfer.test; import java.io.BufferedReader; impo

玩转Java对象和XML相互转换

最近在项目中一直出现Java对象和XML之间的相互转换,一开始由于项目很庞大,我又是临时调度过去,导致在按照项目组长的要求进行写代码的同时,总是在这块云里雾里,最近才慢慢开始搞清楚项目中具体的使用缘由.但是项目中封装的代码总是很庞大,因为要考虑太多的东西,而对于此,我只能通过小的Demo来说明,其实在项目中用到很多插件,轻巧,灵便,封装很好使用,但这里我讲解的是JAXB(Java Architecture for XML Binding). JAXB(Java Architecture for

JAVA对象和XML文档、原来他们之间还有这一出

最近项目开发中遇到一个问题,访问接口不再通过url地址请求的方式,而是 通过socket发送xml格式的报文到指定服务器来进行信息的统一认证.. 因此组装xml格式的报文字符串以及解析服务器返回的xml格式的字符获得所需数据成了 解决问题的关键..在这之前,以为会有点难...做完之后,然并卵,也就那么一回事... LZ主要用的xStream类..这个类的完美地解决了XML文档和JAVA对象之间的转换.. 由于刚刚接触这个类...对于里面提供的很多功能还没细细挖掘..只是简单地实现了 我想要实现的

通过JAXB完成Java对象与XML之间的转换

Java对象转换XML的过程叫marshal. XML转换到Java对象的过程叫unmarshal. 一.Java对象转化为XML 这里省略getter和setter方法 通过标注@XMLRootElement用于标注XML的根元素.这个类的所有属性默认映射为根元素的子元素. 运行代码后,将生成一个D:\test.xml文件,其数据为 二.XML转化为Java对象 代码运行如下 三.更为复杂的映射 将XML中数据读到ArticleData中,类中有一个List,保存每条article数据

使用XStream注解实现Java对象与XML互相转换的代码示例

本文记录一下使用xstream这个api的注解特性对Java对象与XML字符串相互转换的一些代码示例.    我们很多人都处理过XML文件,也有很多非常成熟的第三方开源软件.如:jdom.dom4j等.虽然他们的功能非常强大,但在使用上还是有点不那么习惯.对于格式比较固定的XML文档,它的结构没有变化或是很少变化,这时将它转换成我们熟悉的Java对象来操作的话,会使工作变得更容易一些,而xstream正好可以满足这一点.    本文所用xstream的版本为:1.4.7 <dependency>

使用JAXB实现JAVA对象和XML字符串的互相转换实例

测试类: package com.yanek.test; import java.util.ArrayList; import java.util.List; import com.yanek.test.JaxbUtil.CollectionWrapper; public class Test { /** * @param args */ public static void main(String[] args) { //创建java对象 Hotel hotel=new Hotel(); ho

java对象与xml相互转换 ---- xstream

XStream是一个Java对象和XML相互转换的工具,很好很强大.提供了所有的基础类型.数组.集合等类型直接转换的支持. XStream中的核心类就是XStream类,一般来说,熟悉这个类基本就够用了. 由于XStream.jar依赖于xmlpull.jar 所以,需将这两个jar一同导入. 下载地址 : https://pan.baidu.com/s/1eSpZs3o#path=%252F%25E5%25B7%25A5%25E5%2585%25B7jar XStream对象相当Java对象和

JAXB 实现java对象与xml之间互相转换

首先熟悉一下JAXB实现对象与xml互转时常用的一些注解使用: [email protected],用于类级别的注解,对应xml的跟元素.通过name属性定义这个根节点的名称. [email protected],定义映射这个类中的何种类型都需要映射到xml.(如果不存在@XmlAccessorType,默认使用XmlAccessType.PUBLIC_MEMBER注解) 参数:XmlAccessType.FIELD: java对象中的所有成员变量. XmlAccessType.PROPERTY