JAXB实例入门

本文介绍了JAXB的基本用法,包括Java对象转XML、XML转Java对象,详细展示了各种转换操作,如设置属性、使用EclipseLink MOXy、监听器、注解、适配器和Schema验证等。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

[b]JAXB(Java Architecture for XML Binding)[/b],JDK标准规范,Java对象和XML之间的转换,和SAX/DOM不同的是无需关注XML解析细节。
[list]
[*]Marshalling – 把Java对象转换成XML
[*]Unmarshalling – 把XML转换成Java对象[/list]
[b]版本:[/b]
* JDK1.6开始提供JAXB 2.0(建议使用最新版JDK)
* 低于JDK1.6的版本需要下载jaxb-api.jar和jaxb-impl.jar
* JAXB还有JDK以外的很多第三方实现,比如:EclipseLink MOXy

以下代码都去掉了Bean的Setter/Getter,具体可执行的完整工程代码,可从附件下载。

[b](1) 基本[/b]

[b]Java对象 -> XML[/b]

@XmlRootElement
public class Sample {
private int id;
private String name;
private boolean flag;
}


Sample s = new Sample();
s.setId(101);
s.setName("basicObj2XML");
s.setFlag(false);

StringWriter w = new StringWriter();
// JAXB是JDK封装好的解析器
JAXB.marshal(s, new StreamResult(w)); // 输出到字符串
System.out.println(w.toString());

[quote]<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<sample>
<flag>false</flag>
<id>101</id>
<name>basicObj2XML</name>
</sample>
[/quote]

转换后的XML内容可以直接输出到其他流(比如:控制台、文件等)

Sample s = new Sample();
s.setId(102);
s.setName("basicObj2Output");
s.setFlag(false);

JAXB.marshal(s, System.out); // 输出到控制台
JAXB.marshal(s, new File("d:\\jaxb_sample.xml")); // 输出到文件


[b]XML -> Java对象[/b]

String xml = "<?xml version=\"1.0\"?>"
+ "<sample>"
+ " <id>103</id>"
+ " <name>basicXML2Obj</name>"
+ " <flag>false</flag>"
+ "</sample>";

StringReader r = new StringReader(xml);
Sample ss = JAXB.unmarshal(r, Sample.class);
System.out.println(ss.toString());


[b](2) 通过JAXBContext创建解析器[/b]

[b]创建Marshaller[/b]

JAXBContext jaxbContext = JAXBContext.newInstance(Sample.class);
Marshaller marshaller = jaxbContext.createMarshaller();
marshaller.marshal(s, System.out);


[b]创建Unmarshaller[/b]

JAXBContext jaxbContext = JAXBContext.newInstance(Sample.class);
Unmarshaller unmarshaller = jaxbContext.createUnmarshaller();
StringReader r = new StringReader(xml);
Sample sample = unmarshaller.unmarshal(new StreamSource(r), Sample.class).getValue();
System.out.println(sample.toString());


[b]设置Marshaller属性[/b]
[b]marshaller.setProperty();[/b]

JAXBContext jaxbContext = JAXBContext.newInstance(Sample.class);
Marshaller marshaller = jaxbContext.createMarshaller();
// 设置格式化后输出
marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);
// 设置字符集
marshaller.setProperty(Marshaller.JAXB_ENCODING, Charset.defaultCharset().name());
marshaller.marshal(s, System.out);


[b](3) 采用EclipseLink MOXy作为JAXB provider[/b]
1)下载导入eclipselink.jar
2)在POJO的包下新建jaxb.properties
[quote]#Sun JAXB
javax.xml.bind.context.factory=com.sun.xml.internal.bind.v2.ContextFactory
#Eclipse MOXy
#javax.xml.bind.context.factory=org.eclipse.persistence.jaxb.JAXBContextFactory [/quote]
*** SUN的JAXB实现会在xml中添加属性standalone="yes",而EclipseLink MOXy就不会。

[b](4) 监听器[/b]

[b]marshaller.setListener();[/b]

[b]Marshaller监听器[/b]

public class MarshallListener extends Marshaller.Listener {

public void beforeMarshal(Object source) {
System.out.println("BEFORE_MARSHAL fired");
}

public void afterMarshal(Object source) {
System.out.println("AFTER_MARSHAL fired");
}

}


JAXBContext jaxbContext = JAXBContext.newInstance(Sample.class);
Marshaller marshaller = jaxbContext.createMarshaller();
// 设置监听器(!!!Sun JAXB实现有Bug会被执行两次,而Eclipse MOXy能正确执行一次!!!)
marshaller.setListener(new MarshallListener());
marshaller.marshal(s, System.out);


[b]Unmarshaller监听器[/b]

public class UnmarshallListener extends Unmarshaller.Listener {

@Override
public void beforeUnmarshal(Object target, Object parent) {
System.out.println("BEFORE_UNMARSHAL fired");
}

@Override
public void afterUnmarshal(Object target, Object parent) {
System.out.println("AFTER_UNMARSHAL fired");
}

}


JAXBContext jaxbContext = JAXBContext.newInstance(Sample.class);
Unmarshaller unmarshaller = jaxbContext.createUnmarshaller();
// 设置监听器
unmarshaller.setListener(new UnmarshallListener());
StringReader r = new StringReader(xml);
Sample sample = unmarshaller.unmarshal(new StreamSource(r), Sample.class).getValue();
System.out.println(sample.toString());


[b](5) 注解[/b]

[b]设置内部标签顺序(默认是按标签字母排序)[/b]
[b]@XmlType(propOrder={"id", "name", "flag"})[/b]

@XmlRootElement
@XmlType(propOrder={"id", "name", "flag"})
public class SampleOrder {
private int id;
private String name;
private boolean flag;
}

[quote]<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<sampleOrder>
<id>501</id>
<name>marshallerTagOrder</name>
<flag>false</flag>
</sampleOrder>[/quote]

[b]把字段值作为属性(默认都是标签)[/b]
[b]@XmlAttribute[/b]

@XmlRootElement
@XmlAccessorType(XmlAccessType.FIELD)
public class SampleAttribute {
@XmlAttribute
private int id;
private String name;
private boolean flag;
}

[quote]<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<sampleAttribute id="502">
<name>SampleAttribute</name>
<flag>false</flag>
</sampleAttribute>[/quote]

[b]不输出某个字段值[/b]
[b]@XmlTransient[/b]

@XmlRootElement
@XmlAccessorType(XmlAccessType.FIELD)
public class SampleTransient {
private int id;
private String name;
@XmlTransient
private boolean flag;
}

[quote]<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<sampleTransient>
<id>503</id>
<name>SampleTransient</name>
</sampleTransient>[/quote]

[b]空值处理[/b]

[b]@XmlElement(nillable = true)[/b]


SampleEmpty s = new SampleEmpty();
s.setId(504);
s.setName("SampleEmpty");
s.setFlag(false);
s.setName1(null);
s.setName2("");
s.setName3(null);


@XmlRootElement
@XmlAccessorType(XmlAccessType.FIELD)
public class SampleEmpty {
private int id;
private String name;
private boolean flag;
private String name1;
private String name2;
@XmlElement(nillable = true)
private String name3;
}

[quote]<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<sampleEmpty>
<id>504</id>
<name>SampleEmpty</name>
<flag>false</flag>
<name2></name2>
<name3 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:nil="true"/>
</sampleEmpty>[/quote]

[b]变更输出标签属性名称[/b]

[b]@XmlRootElement(name="foobar-tag")
@XmlAttribute(name="foobar-id")
@XmlElement(name="foobar-value")[/b]


@XmlRootElement(name="foobar-tag")
@XmlAccessorType(XmlAccessType.FIELD)
public class SampleName {
@XmlAttribute(name="foobar-id")
private int id;
@XmlElement(name="foobar-value")
private String name;
private boolean flag;
}

[quote]<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<foobar-tag foobar-id="505">
<foobar-value>SampleName</foobar-value>
<flag>false</flag>
</foobar-tag>[/quote]

[b]Bean类型[/b]

@XmlRootElement
public class SampleBeanNested {
private int id;
private String name;
private boolean flag;
private People people;
}

public class People {
private int id;
private String name;
}

[quote]<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<sampleBeanNested>
<flag>false</flag>
<id>506</id>
<name>SampleBeanNested</name>
<people>
<id>100</id>
<name>People</name>
</people>
</sampleBeanNested>[/quote]

[b]List类型[/b]

[b]【字符串】默认[/b]


@XmlRootElement
public class SampleStringList1 {
private int id;
private String name;
private boolean flag;
private List<String> emailAddresses;
}

[quote]<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<sampleStringList1>
<emailAddresses>a1.rensanning@gmail.com</emailAddresses>
<emailAddresses>a2.rensanning@gmail.com</emailAddresses>
<emailAddresses>a3.rensanning@gmail.com</emailAddresses>
<flag>false</flag>
<id>507</id>
<name>SampleStringList1</name>
</sampleStringList1>[/quote]

[b]@XmlElementWrapper[/b]


@XmlRootElement
@XmlAccessorType(XmlAccessType.FIELD)
public class SampleStringList2 {
private int id;
private String name;
private boolean flag;
@XmlElementWrapper(name="email-addresses")
@XmlElement(name="email-address")
private List<String> emailAddresses;
}

[quote]<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<sampleStringList2>
<id>508</id>
<name>SampleStringList2</name>
<flag>false</flag>
<email-addresses>
<email-address>b1.rensanning@gmail.com</email-address>
<email-address>b2.rensanning@gmail.com</email-address>
<email-address>b3.rensanning@gmail.com</email-address>
</email-addresses>
</sampleStringList2>[/quote]

[b]@XmlList[/b]


@XmlRootElement
@XmlAccessorType(XmlAccessType.FIELD)
public class SampleStringList3 {
private int id;
private String name;
private boolean flag;
@XmlList
private List<String> emailAddresses;
}

[quote]<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<sampleStringList3>
<id>509</id>
<name>SampleStringList3</name>
<flag>false</flag>
<emailAddresses>c1.rensanning@gmail.com c2.rensanning@gmail.com c3.rensanning@gmail.com</emailAddresses>
</sampleStringList3>[/quote]

[b]【Bean】默认[/b]


@XmlRootElement
public class SampleBeanList1 {
private int id;
private String name;
private boolean flag;
private List<People> peoples;
}

[quote]<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<sampleBeanList1>
<flag>false</flag>
<id>510</id>
<name>SampleBeanList1</name>
<peoples>
<id>100</id>
<name>People1</name>
</peoples>
<peoples>
<id>200</id>
<name>People2</name>
</peoples>
<peoples>
<id>300</id>
<name>People3</name>
</peoples>
</sampleBeanList1>[/quote]

[b]@XmlElementWrapper[/b]


@XmlRootElement
@XmlAccessorType(XmlAccessType.FIELD)
public class SampleBeanList2 {
private int id;
private String name;
private boolean flag;
@XmlElementWrapper(name="list")
@XmlElement(name="people")
private List<People> peoples;
}

[quote]<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<sampleBeanList2>
<id>511</id>
<name>SampleBeanList2</name>
<flag>false</flag>
<list>
<people>
<id>100</id>
<name>People1</name>
</people>
<people>
<id>200</id>
<name>People2</name>
</people>
<people>
<id>300</id>
<name>People3</name>
</people>
</list>
</sampleBeanList2>[/quote]

[b]@XmlElements[/b]


@XmlRootElement
@XmlAccessorType(XmlAccessType.FIELD)
public class SampleBeanList3 {
private int id;
private String name;
private boolean flag;
@XmlElementWrapper(name="list")
@XmlElements( {
@XmlElement(name = "man", type = Man.class),
@XmlElement(name = "woman", type = Woman.class)
})
private List<People> peoples;
}

[quote]<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<sampleBeanList3>
<id>512</id>
<name>SampleBeanLis3</name>
<flag>false</flag>
<list>
<man>
<id>100</id>
<name>Man</name>
<attr1>Attr1</attr1>
</man>
<woman>
<id>200</id>
<name>Woman</name>
<attr2>Attr2</attr2>
</woman>
</list>
</sampleBeanList3>[/quote]

[b]枚举类型[/b]

[b]@XmlEnum、@XmlEnumValue[/b]


@XmlEnum(Integer.class)
@XmlType
public enum BloodType {
@XmlEnumValue("1") A,
@XmlEnumValue("2") B,
@XmlEnumValue("3") O,
@XmlEnumValue("4") AB
}

@XmlRootElement
public class SampleEnum {
private int id;
private String name;
private boolean flag;
private BloodType bloodType;
}

[quote]<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<sampleEnum>
<bloodType>2</bloodType>
<flag>false</flag>
<id>513</id>
<name>SampleEnum</name>
</sampleEnum>[/quote]

[b](6) 适配器 [/b]

[b]@XmlJavaTypeAdapter[/b]


public class DateAdapter extends XmlAdapter<String, Date> {

private static final SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy/MM/dd hh:mm:ss");

public Date unmarshal(String v) throws Exception {
return dateFormat.parse(v);
}

public String marshal(Date v) throws Exception {
return dateFormat.format(v);
}

}

@XmlRootElement
@XmlAccessorType(XmlAccessType.FIELD)
public class SampleDateAdapter {
private int id;
private String name;
private boolean flag;
@XmlJavaTypeAdapter(DateAdapter.class)
private Date date;
}

[quote]<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<sampleDateAdapter>
<id>601</id>
<name>SampleDateAdapter</name>
<flag>false</flag>
<date>2017/06/09 09:52:26</date>
</sampleDateAdapter>[/quote]

[b](7) Schema检验[/b]

[b]SampleSchema.xsd[/b]

<?xml version="1.0" encoding="UTF-8"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema">

<xs:element name="SampleSchema">
<xs:complexType>
<xs:sequence>
<xs:element name="name" type="xs:string" />
<xs:element name="flag" type="xs:boolean" />
</xs:sequence>
<xs:attribute name="id" type="xs:int" />
</xs:complexType>
</xs:element>

</xs:schema>


[b]marshaller.setSchema();[/b]


@XmlRootElement(name="SampleSchema")
@XmlAccessorType(XmlAccessType.FIELD)
public class SampleSchema {
@XmlAttribute
private int id;
private String name;
private boolean flag;
}


SampleSchema s = new SampleSchema();
s.setId(701);
s.setName("SampleSchema");
s.setFlag(false);

ClassLoader classLoader = new Main().getClass().getClassLoader();
File schemaFile = new File(classLoader.getResource("SampleSchema.xsd").getFile());

SchemaFactory sf = SchemaFactory.newInstance(XMLConstants.W3C_XML_SCHEMA_NS_URI);
Schema schema = sf.newSchema(schemaFile);

JAXBContext jaxbContext = JAXBContext.newInstance(SampleSchema.class);
Marshaller marshaller = jaxbContext.createMarshaller();
marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);
// 设置Schema
marshaller.setSchema(schema);
marshaller.marshal(s, System.out);

[quote]<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<SampleSchema id="701">
<name>SampleSchema</name>
<flag>false</flag>
</SampleSchema>[/quote]

[b]validator.validate(source);[/b]


SampleSchema s = new SampleSchema();
s.setId(702);
s.setName("marshallerValidator");
s.setFlag(false);

ClassLoader classLoader = new Main().getClass().getClassLoader();
File schemaFile = new File(classLoader.getResource("SampleSchema.xsd").getFile());

SchemaFactory sf = SchemaFactory.newInstance(XMLConstants.W3C_XML_SCHEMA_NS_URI);
Schema schema = sf.newSchema(schemaFile);

JAXBContext jaxbContext = JAXBContext.newInstance(SampleSchema.class);

// 校验XML
JAXBSource source = new JAXBSource(jaxbContext, s);
Validator validator = schema.newValidator();
validator.setErrorHandler(new CustomValidationErrorHandler());
validator.validate(source);

Marshaller marshaller = jaxbContext.createMarshaller();
marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);
marshaller.marshal(s, System.out);


[b](8) 捕获事件[/b]

[b]marshaller.setEventHandler();[/b]


public class CustomEventHandler implements ValidationEventHandler {

@Override
public boolean handleEvent(ValidationEvent event) {
System.out.println(event.getSeverity());

if (event.getSeverity() == ValidationEvent.ERROR
|| event.getSeverity() == ValidationEvent.FATAL_ERROR) {
ValidationEventLocator locator = event.getLocator();
System.out.println("Line:Col[" + locator.getLineNumber() + ":" + locator.getColumnNumber() + "]");
throw new RuntimeException(event.getMessage(), event.getLinkedException());
}
return true;
}

}


JAXBContext jaxbContext = JAXBContext.newInstance(Sample.class);
Unmarshaller unmarshaller = jaxbContext.createUnmarshaller();
// 设置事件处理器
unmarshaller.setEventHandler(new CustomEventHandler());
StringReader r = new StringReader(xml);
Sample sample = unmarshaller.unmarshal(new StreamSource(r), Sample.class).getValue();
System.out.println(sample.toString());
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值