JAXB provides XMLAdapter to change the format of default JAXB types. For example, formatting decimal places in Decimal or BigDecimal, Date formatting etc.
How to do it?
First look at the following plain vanilla example of JAXB
How to do it?
First look at the following plain vanilla example of JAXB
package com.test; import java.math.BigDecimal; import javax.xml.bind.annotation.XmlElement; import javax.xml.bind.annotation.XmlRootElement; import javax.xml.datatype.XMLGregorianCalendar; @XmlRootElement public class Loan { private String name; private Long amount; private XMLGregorianCalendar startDate; private BigDecimal interestRate; public String getName() { return name; } @XmlElement public void setName(String name) { this.name = name; } public BigDecimal getInterestRate() { return interestRate; } @XmlElement public void setInterestRate(BigDecimal interestRate) { this.interestRate = interestRate; } public XMLGregorianCalendar getStartDate() { return startDate; } @XmlElement public void setStartDate(XMLGregorianCalendar startDate) { this.startDate = startDate; } public Long getAmount() { return amount; } @XmlElement public void setAmount(Long amount) { this.amount = amount; } }If we marshall the Loan object, the output is similar to
<?xml version="1.0" encoding="UTF-8" standalone="yes"?> <loan> <amount>200000</amount> <interestRate>15.6</interestRate> <name>Name</name> <startDate>2013-05-19T16:02:51.080+05:30</startDate> </loan>Now, format the XMLGregorianCalendar to YYYY-MM-DD in XML. For this, we need to add a new XMLAdapter which can convert(marshall) from Calendar format to String format.
package com.test; import javax.xml.bind.annotation.adapters.XmlAdapter; import javax.xml.datatype.XMLGregorianCalendar; public class CalendarAdaptor extends XmlAdapter<String, XMLGregorianCalendar> { @Override public String marshal(XMLGregorianCalendar v) throws Exception { return v.getYear()+"-"+v.getMonth()+"-"+v.getDay(); } @Override public XMLGregorianCalendar unmarshal(String v) throws Exception { return null; } }and Add the Adapter to the property where we would like to change. So the Loan.java file will be changed at the setStartDate method to following
@XmlJavaTypeAdapter(CalendarAdaptor.class) public void setStartDate(XMLGregorianCalendar startDate) { this.startDate = startDate; }When we marshall the same Loan object now, with the above change, the xml string will be
<?xml version="1.0" encoding="UTF-8" standalone="yes"?> <loan> <amount>200000</amount> <interestRate>15.6</interestRate> <name>Name</name> <startDate>2013-5-19</startDate> </loan>But the thing is, we need to change each property for the class definitions to affect this change. Instead of changing the classes, we can provide this adapter change at the package level by defining a class called package-info.java without changing the individual class properties. By doing this, all the XMLGregorianCalendar attributes in the package will follow the format defined by the Adapter. package-info.java
@XmlJavaTypeAdapter(value=CalendarAdaptor.class, type=XMLGregorianCalendar.class) package com.test; import javax.xml.datatype.XMLGregorianCalendar; import javax.xml.bind.annotation.adapters.XmlJavaTypeAdapter;