Lorsque JAXB regroupe un objet de date (XMLGregorianCalendar
) dans un élément xsd: dateTime, comment pouvez-vous spécifier le format du XML résultant?
Par exemple: Le format de données par défaut utilise millisecondes <StartDate>2012-08-21T13:21:58.000Z</StartDate>
Je dois omettre les millisecondes. <StartDate>2012-08-21T13:21:58Z</StartDate>
Comment puis-je spécifier le format de formulaire/date de sortie que je souhaite utiliser? J'utilise javax.xml.datatype.DatatypeFactory
pour créer l'objet XMLGregorianCalendar
.
XMLGregorianCalendar xmlCal = datatypeFactory.newXMLGregorianCalendar(cal);
Vous pouvez utiliser une XmlAdapter
pour personnaliser la manière dont un type de date est écrit en XML.
import Java.text.SimpleDateFormat;
import Java.util.Date;
import javax.xml.bind.annotation.adapters.XmlAdapter;
public class DateAdapter extends XmlAdapter<String, Date> {
private final SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
@Override
public String marshal(Date v) throws Exception {
synchronized (dateFormat) {
return dateFormat.format(v);
}
}
@Override
public Date unmarshal(String v) throws Exception {
synchronized (dateFormat) {
return dateFormat.parse(v);
}
}
}
Ensuite, vous utilisez l'annotation @XmlJavaTypeAdapter
pour spécifier que la variable XmlAdapter
doit être utilisée pour un champ/une propriété spécifique.
@XmlElement(name = "timestamp", required = true)
@XmlJavaTypeAdapter(DateAdapter.class)
protected Date timestamp;
En utilisant un fichier de liaison xjb:
<jxb:javaType name="Java.time.ZonedDateTime"
xmlType="xs:dateTime"
parseMethod="my.package.DateAdapter.parseDateTime"
printMethod="my.package.DateAdapter.formatDateTime" />
produira l'annotation mentionnée ci-dessus.
J'utilise un SimpleDateFormat pour créer le XMLGregorianCalendar, comme dans cet exemple:
public static XMLGregorianCalendar getXmlDate(Date date) throws DatatypeConfigurationException {
return DatatypeFactory.newInstance().newXMLGregorianCalendar(new SimpleDateFormat("yyyy-MM-dd").format(date));
}
public static XMLGregorianCalendar getXmlDateTime(Date date) throws DatatypeConfigurationException {
return DatatypeFactory.newInstance().newXMLGregorianCalendar(new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss").format(date));
}
La première méthode crée une instance de XMLGregorianCalendar qui est formatée par le marshaller XML en tant que xsd: date valide, la deuxième méthode produit un xsd: dateTime valide.
Un moyen très facile pour moi. Formatage de XMLGregorianCalendar pour le marshalling en Java.
Je crée juste mes données dans le bon format. La toString
sera appelée produisant le bon résultat.
public static final XMLGregorianCalendar getDate(Date d) {
try {
return DatatypeFactory.newInstance().newXMLGregorianCalendar(new SimpleDateFormat("yyyy-MM-dd").format(d));
} catch (DatatypeConfigurationException e) {
return null;
}
}
public class DateAdapter extends XmlAdapter<String, Date> {
private static final ThreadLocal<DateFormat> dateFormat
= new ThreadLocal<DateFormat>() {
@Override
protected DateFormat initialValue() {
return new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
}
}
@Override
public Date unmarshal(String v) throws Exception {
return dateFormat.get().parse(v);
}
@Override
public String marshal(Date v) throws Exception {
return dateFormat.get().format(v);
}
}
Usage:
import com.company.LocalDateAdapter.yyyyMMdd;
...
@XmlElement(name = "PROC-DATE")
@XmlJavaTypeAdapter(yyyyMMdd.class)
private LocalDate processingDate;
LocalDateAdapter
import javax.xml.bind.annotation.adapters.XmlAdapter;
import org.joda.time.LocalDate;
import org.joda.time.format.DateTimeFormat;
import org.joda.time.format.DateTimeFormatter;
public class LocalDateAdapter extends XmlAdapter<String, LocalDate> {
public static final class yyyyMMdd extends LocalDateAdapter {
public yyyyMMdd() {
super("yyyyMMdd");
}
}
public static final class yyyy_MM_dd extends LocalDateAdapter {
public yyyy_MM_dd() {
super("yyyy-MM-dd");
}
}
private final DateTimeFormatter formatter;
public LocalDateAdapter(String pattern) {
formatter = DateTimeFormat.forPattern(pattern);
}
@Override
public String marshal(LocalDate date) throws Exception {
return formatter.print(date);
}
@Override
public LocalDate unmarshal(String date) throws Exception {
return formatter.parseLocalDate(date);
}
}