JAXB is a powerful yet simple to use api to read and write xml in java .
This is the sample xml which we want to read using java .
this is root class which is mapped to xmlObject element in the xml
This is the sample xml which we want to read using java .
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<xmlObject>
<auction>
<auctionType>PUBLIC</auctionType>
<description>this is auction from file</description>
<product>
<details>Product XML</details>
<name>this is product from file</name>
</product>
<bids>
<bid>
<amount>23</amount>
<time>23-12-2012</time>
<user>abhishek</user>
</bid>
<bid>
<amount>25</amount>
<time>23-11-2012</time>
<user>john</user>
</bid>
</bids>
<startDateTime>2012-10-30T23:46:13.394</startDateTime>
<endDateTime>2012-12-30T23:46:13.394</endDateTime>
</auction>
</xmlObject>
this is root class which is mapped to xmlObject element in the xml
package com.xml;
import java.io.File;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashSet;
import java.util.LinkedList;
import java.util.List;
import java.util.Set;
import javax.xml.bind.JAXBContext;
import javax.xml.bind.JAXBException;
import javax.xml.bind.Marshaller;
import javax.xml.bind.Unmarshaller;
import javax.xml.bind.annotation.XmlRootElement;
import com.model.Auction;
import com.model.AuctionStatus;
import com.model.AuctionType;
import com.model.Bid;
import com.model.Product;
/**
* JAXB class to create Java Objects from XML File
* @author abhishek.somani
*
*/
@XmlRootElement(name = "xmlObject")
public class XMLObject
{
private List<auction> auction;
public XMLObject()
{
auction = new ArrayList<auction>();
}
public List<auction> getAuction()
{
return auction;
}
public List<auction> setAuction(List<auction> aunctions)
{
return this.auction = aunctions;
}
}
This is Auction class which is mapped to auction element in xml.
package com.model;
import java.io.Serializable;
import java.util.Date;
import java.util.HashSet;
import java.util.Set;
import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlElementWrapper;
import javax.xml.bind.annotation.XmlRootElement;
import javax.xml.bind.annotation.XmlTransient;
/**
* Model class Mapped to database table auction and XmlElement auction
* @author abhishek.somani
*
*/
@XmlRootElement
public class Auction implements Serializable
{
/**
*
*/
private static final long serialVersionUID = 1L;
private Product product;
private int id;
private String auctionStatus;
private String auctionType;
private String description;
private Date startDateTime;
private Date endDateTime;
private Bid winnerBid;
private Set<Bid> bids = new HashSet<Bid>();
public static long getSerialversionuid()
{
return serialVersionUID;
}
public Bid getWinnerBid()
{
return winnerBid;
}
public void setWinnerBid(Bid winnerbid)
{
this.winnerBid = winnerbid;
}
public Auction()
{
}
public Auction(Product product, Date startTime, String type, String status)
{
this.product = product;
this.startDateTime = startTime;
this.auctionType = type;
this.auctionStatus = status;
}
public Set<Bid> getBids()
{
return bids;
}
@XmlElement(name = "bid")
@XmlElementWrapper(name = "bids")
public void setBids(Set<Bid> bids)
{
this.bids = bids;
}
public Product getProduct()
{
return product;
}
public void setProduct(Product product)
{
this.product = product;
}
public int getId()
{
return id;
}
@XmlTransient
public void setId(int id)
{
this.id = id;
}
public String getAuctionStatus()
{
return auctionStatus;
}
public void setAuctionStatus(String auctionStatus)
{
this.auctionStatus = auctionStatus;
}
public String getAuctionType()
{
return auctionType;
}
public void setAuctionType(String acutionType)
{
this.auctionType = acutionType;
}
public String getDescription()
{
return description;
}
public void setDescription(String description)
{
this.description = description;
}
public Date getStartDateTime()
{
return startDateTime;
}
public void setStartDateTime(Date startDateTime)
{
this.startDateTime = startDateTime;
}
public Date getEndDateTime()
{
return endDateTime;
}
public void setEndDateTime(Date endDateTime)
{
this.endDateTime = endDateTime;
}
public boolean isActive()
{
return this.auctionStatus.equals(AuctionStatus.ACTIVE.toString());
}
}
@XmlElementWrapper is used to create a list object containing the inner JAXB elements .
like in xml bids element contains zero or more bid element ,
where bid also can be mapped to another JAXB class .
By default if you don't specify @XmlElement on every getter method , it map every member field to xml.
@XmlTransient is used if we want to skip some fields not to be mapped in xml .
Bid class which is mapped to bid element in xml.
package com.model; import java.util.Date; import java.util.HashSet; import java.util.Set; import javax.xml.bind.annotation.XmlRootElement; import javax.xml.bind.annotation.XmlTransient; /** * Model class for bid table * @author abhishek.somani * */ @XmlRootElement public class Bid implements ComparableProduct class which is mapped to product element in xml.{ private int id; private String user; private Auction auction; private double amount; private Date time; private Set auctions = new HashSet(0); public Bid() { } public Bid(Auction auction, String user, double amount, Date time) { this.auction = auction; this.user = user; this.amount = amount; this.time = time; } public int getId() { return id; } @XmlTransient public void setId(int id) { this.id = id; } public String getUser() { return user; } public void setUser(String user) { this.user = user; } public Auction getAuction() { return auction; } public void setAuction(Auction auction) { this.auction = auction; } public Double getAmount() { return amount; } public void setAmount(Double amount) { this.amount = amount; } public Date getTime() { return time; } public void setTime(Date time) { this.time = time; } //compareto method determines which bid is higher @Override public int compareTo(Bid o) { int compare = 0; if (this.amount > o.amount) compare = 1; else if (this.amount < o.amount) compare = -1; else if (this.amount == o.amount) { //if amount is same then compare time , bid with more time is smaller compare = this.time.compareTo(o.time) >= 0 ? -1 : 1; } return compare; } public Set getAuctions() { return this.auctions; } public void setAuctions(Set auctions) { this.auctions = auctions; } }
package com.model;
import java.util.HashSet;
import java.util.Set;
import javax.xml.bind.annotation.XmlRootElement;
@XmlRootElement
public class Product
{
private int id;
private String name;
private String details;
private Set auctions = new HashSet(0);
public Product()
{
}
public Product(String name, String details)
{
this.name = name;
this.details = details;
}
public int getId()
{
return id;
}
public void setId(int id)
{
this.id = id;
}
public String getName()
{
return name;
}
public void setName(String name)
{
this.name = name;
}
public String getDetails()
{
return details;
}
public void setDetails(String details)
{
this.details = details;
}
public Set getAuctions()
{
return this.auctions;
}
public void setAuctions(Set auctions)
{
this.auctions = auctions;
}
}
Main class to read and write
public static void main(String args[]) throws JAXBException
{
new XMLObject().writeXml(null, null);
}
public List readXml(File file) throws JAXBException
{
JAXBContext jaxbContext = JAXBContext.newInstance(XMLObject.class);
Unmarshaller jaxbUnmarshaller = jaxbContext.createUnmarshaller();
XMLObject a = (XMLObject) jaxbUnmarshaller.unmarshal(file);
for (Auction au : a.getAuction())
{
au.setAuctionStatus(AuctionStatus.ACTIVE.name());
au.setEndDateTime(null);
}
return null;
}
public List readXml(InputStream is) throws JAXBException
{
JAXBContext jaxbContext = JAXBContext.newInstance(XMLObject.class);
Unmarshaller jaxbUnmarshaller = jaxbContext.createUnmarshaller();
XMLObject a = (XMLObject) jaxbUnmarshaller.unmarshal(is);
return a.getAuction();
}
public void writeXml(List list,File f) throws JAXBException
{
XMLObject root = new XMLObject();
List auctions = new LinkedList();
Auction a = new Auction();
a.setAuctionType(AuctionType.PUBLIC.toString());
a.setDescription("test");
Set bids = new HashSet();
Bid b = new Bid();
b.setAmount(new Double(233));
b.setTime(new Date());
bids.add(b);
a.setBids(bids);
Product p = new Product();
p.setName("p1");
p.setDetails("details");
a.setProduct(p);
a.setStartDateTime(new Date());
auctions.add(a);
root.setAuction(auctions);
File file = new File("F:/Workspace/testing/wfile.xml");
JAXBContext jaxbContext = JAXBContext.newInstance(XMLObject.class);
Marshaller jaxbMarshaller = jaxbContext.createMarshaller();
// output pretty printed
jaxbMarshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);
jaxbMarshaller.marshal(root, file);
jaxbMarshaller.marshal(root, System.out);
}
Common Exception : JAXBException :Class has two properties of the same name
To resolve this error , we have to use annotations on getter method rather than field methods