Java Model
The model class Team
package j2s.team;
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.XmlElementWrapper;
import javax.xml.bind.annotation.XmlRootElement;
import javax.xml.bind.annotation.XmlType;
/*
* As the class Team is annotated with @XmlRootElement, JAXB transforms a Team
* instance into an XML document whose root element is <team>
*/
@XmlRootElement(name="team")
@XmlType(propOrder={"name","description","playerList"})
@XmlAccessorType(XmlAccessType.FIELD)
public class Team {
// fields
private String name;
private String description;
@XmlElement(name = "player")
@XmlElementWrapper(name = "players")
private List<Player> playerList;
public Team(String name, String description) {
this.name = name;
this.description = description;
this.playerList = new ArrayList<Player>();
}
// default constructor required by JAXB
public Team() {
this("team name", "team descr");
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getDescription() {
return description;
}
public void setDescription(String description) {
this.description = description;
}
public List<Player> getPlayers() {
return playerList;
}
public void setPlayers(List<Player> playerList) {
this.playerList = playerList;
}
public void addPlayer(Player dev) {
playerList.add(dev);
}
@Override
public String toString() {
return "Team [name=" + name + ", description=" + description + ", players=" + playerList + "]";
}
}
The model class Player
package j2s.team;
import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlAccessorType;
import javax.xml.bind.annotation.XmlAttribute;
import javax.xml.bind.annotation.XmlType;
@XmlAccessorType(XmlAccessType.FIELD)
@XmlType(propOrder={"name","number"})
public class Player {
public Player(String name, int number, String position){
this.name=name;
this.number=number;
this.position=position;
}
private String name;
private int number;
@XmlAttribute
private String position;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getNumber() {
return number;
}
public void setNumber(int number) {
this.number = number;
}
public String getPosition() {
return position;
}
public void setPosition(String position) {
this.position = position;
}
@Override
public String toString() {
return "Player [name=" + name + ", position=" + position + "]";
}
}
Use the Java Model with JAXB APIs
The JAXB Client class
package j2s.team.app;
import java.io.File;
import java.io.FileOutputStream;
import javax.xml.bind.JAXBContext;
import javax.xml.bind.JAXBElement;
import javax.xml.bind.JAXBException;
import javax.xml.bind.Marshaller;
import javax.xml.bind.annotation.XmlElementDecl;
import javax.xml.namespace.QName;
import j2s.team.Player;
import j2s.team.Team;
public class JAXBClient {
Team buildTeam() {
Team team = new Team("Chelsea Football Club", "club based in Fulham, London, England");
team.addPlayer(new Player("Willy Caballero", 1, "goalkeeper"));
team.addPlayer(new Player("Marcos Alonso", 3, "defender"));
team.addPlayer(new Player("Cesc Fabregas", 4, "midfielder"));
team.addPlayer(new Player("N'Golo Kante", 7, "midfielder"));
team.addPlayer(new Player("Loïc Remy", 8, "forward"));
team.addPlayer(new Player("Pedro", 11, "midfielder"));
team.addPlayer(new Player("Thibaut Courtois", 13, "goalkeeper"));
team.addPlayer(new Player("Victor Moses", 15, "midfielder"));
return team;
}
void marshallToSystemOutStream(Team team) {
try {
JAXBContext jaxbContext = JAXBContext.newInstance(Team.class);
Marshaller marshaller = jaxbContext.createMarshaller();
marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, Boolean.TRUE);
marshaller.marshal(team, System.out);
} catch (JAXBException e) {
e.printStackTrace();
}
}
void marshallToFileStream(Team team) {
try {
JAXBContext jaxbContext = JAXBContext.newInstance(Team.class);
Marshaller marshaller = jaxbContext.createMarshaller();
marshaller.marshal(team, new FileOutputStream(new File("team.mar")));
} catch (Exception e) {
e.printStackTrace();
}
}
// from Team object to XML document
@XmlElementDecl(namespace = "http://www.software-demon.com/team", name = "team")
JAXBElement toXml(Team team) {
return new JAXBElement(new QName("team"), Team.class, team);
}
}
The JUnit test class
package j2s.team.app;
import static org.junit.Assert.*;
import javax.xml.bind.JAXBElement;
import j2s.team.app.JAXBClient;
import j2s.team.Team;
public class JAXBClientTest {
private Team team;
@org.junit.Before
public void build(){
team = new JAXBClient().buildTeam();
}
@org.junit.Test
public void testRun() {
JAXBElement jaxbElem = new JAXBClient().toXml(team);
assertSame("the same team object", team, jaxbElem.getValue());
}
@org.junit.After
public void print(){
new JAXBClient().marshallToSystemOutStream(team);
}
}
The JUnit test outputs:
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<team>
<name>Chelsea Football Club</name>
<description>club based in Fulham, London, England</description>
<players>
<player position="goalkeeper">
<name>Willy Caballero</name>
<number>1</number>
</player>
<player position="defender">
<name>Marcos Alonso</name>
<number>3</number>
</player>
<player position="midfielder">
<name>Cesc Fabregas</name>
<number>4</number>
</player>
<player position="midfielder">
<name>N'Golo Kante</name>
<number>7</number>
</player>
<player position="forward">
<name>Loïc Remy</name>
<number>8</number>
</player>
<player position="midfielder">
<name>Pedro</name>
<number>11</number>
</player>
<player position="goalkeeper">
<name>Thibaut Courtois</name>
<number>13</number>
</player>
<player position="midfielder">
<name>Victor Moses</name>
<number>15</number>
</player>
</players>
</team>
Most important java annotations used by JAXB
- @XmlRootElement: maps a class or enum type to a XML schema global type
- @XmlType: maps class or enum type to a XML schema type
- @XmlElement: maps a JavaBean property to a XML element
Most important binding strategies used by JAXB
- @XmlAccessorType(XmlAccessType.PUBLIC_MEMBER): default binding strategy, every public getter/setter pair and every public field will be automatically bound to XML, unless annotated by XmlTransient.
- @XmlAccessorType(XmlAccessType.FIELD): every non static, non transient field in a JAXB-bound class will be automatically bound to XML
Common Terminology
- Serialization: the process of translating object state into a data format (a byte stream) that can be stored or transmitted and reconstructed later
- for example java serialization, database serialization, file serialization, RPC serialization (Microsoft RPC serialization, google GWT RPC serialization).
- Marshaling: the process of transforming the memory representation of an object to a data format suitable for storage or transmission
- for example CORBA marshaling, RMI marshaling
No comments:
Post a Comment