JAXB - Hello World with Namespace

时间:2023-03-08 21:57:26

如果元素带有命名空间,那么处理方式与 JAXB - Hello World 会略有不同。

1. XML Schema:

<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:jxb="http://java.sun.com/xml/ns/jaxb" xmlns:ns0="http://www.huey.com/hello/beans/" targetNamespace="http://www.huey.com/hello/beans/" jxb:version="2.0">
<xsd:element name="Greetings" type="ns0:GreetingListType"/>
<xsd:complexType name="GreetingListType">
<xsd:sequence>
<xsd:element name="Greeting" type="ns0:GreetingType" maxOccurs="unbounded"/>
</xsd:sequence>
</xsd:complexType>
<xsd:complexType name="GreetingType">
<xsd:sequence>
<xsd:element name="Text" type="xsd:string"/>
</xsd:sequence>
<xsd:attribute name="language" type="xsd:language"/>
</xsd:complexType>
</xsd:schema>

2. 编译 schema 生成 Java 类:

xjc hello.xsd    // 取默认的包路径,根据命名空间生成

3. 修改生成的 GreetingListType.java 文件,添加 @XmlRootElement,指定根元素的名称和命名空间:

package com.huey.hello.beans;

import java.util.ArrayList;
import java.util.List;
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 javax.xml.bind.annotation.XmlType; @XmlAccessorType(XmlAccessType.FIELD)
@XmlType(name = "GreetingListType", propOrder = {
"greeting"
})
@XmlRootElement(namespace = "http://www.huey.com/hello/beans/", name = "Greetings")
public class GreetingListType { @XmlElement(name = "Greeting", required = true)
protected List<GreetingType> greeting; public List<GreetingType> getGreeting() {
if (greeting == null) {
greeting = new ArrayList<GreetingType>();
}
return this.greeting;
} }

4. marshal:

public class JaxbUtils {

    // ...

    public static <T> String marshal(T obj) {
StringWriter writer = new StringWriter();
try { JAXBContext jc = JAXBContext.newInstance(obj.getClass());
Marshaller m = jc.createMarshaller();
m.setProperty( Marshaller.JAXB_FORMATTED_OUTPUT, Boolean.TRUE );
m.marshal(obj, writer);
} catch (JAXBException jbe) {
// ...
}
return writer.toString();
}
}

5. 测试 JaxbUtils.marshal 方法:

public class JaxbUtilsTest {
@Test
public void testMarshal() throws Exception {
GreetingListType glt = new GreetingListType();
GreetingType gt1 = new GreetingType();
gt1.setLanguage("en");
gt1.setText("Hello world");
glt.getGreeting().add(gt1);
GreetingType gt2 = new GreetingType();
gt2.setLanguage("fr");
gt2.setText("Bonjour, madame");
glt.getGreeting().add(gt2); System.out.println(JaxbUtils.marshal(glt));
}
}

6. JaxbUtils.marshal 测试输出:

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<ns2:Greetings xmlns:ns2="http://www.huey.com/hello/beans/">
<Greeting language="en">
<Text>Hello world</Text>
</Greeting>
<Greeting language="fr">
<Text>Bonjour, madame</Text>
</Greeting>
</ns2:Greetings>

7. unmarshal:

public class JaxbUtils {

    // ...

    public static <T> T unmarshal(Class<T> docClass, InputStream inputStream) throws JAXBException {
JAXBContext jc = JAXBContext.newInstance(docClass);
Unmarshaller u = jc.createUnmarshaller();
T obj = (T) u.unmarshal(inputStream);
return obj;
}
}

8. 以 JaxbUtils.marshal 的测试输出作为 JaxbUtils.unmarshal 的输入做测试:

public class JaxbUtilsTest {
@Test
public void testUnmarshal() throws Exception {
String path = "/files/hello.xml";
InputStream in = JaxbUtilsTest.class.getResourceAsStream(path);
try {
GreetingListType greetingList = JaxbUtils.unmarshal(GreetingListType.class, in);
List<GreetingType> greetings = greetingList.getGreeting();
for (GreetingType greeting : greetings) {
System.out.println(greeting.getLanguage() + ": " + greeting.getText());
}
} catch (JAXBException e) {
e.printStackTrace();
} finally {
IOUtils.closeQuietly(in);
}
}
}

9. JaxbUtils.unmarshal 测试输出:

fr: Bonjour, madame
en: Hey, you

Namespace