web-dev-qa-db-fra.com

Comment spécifiez-vous le format de date utilisé lorsque JAXB marshals xsd: dateTime?

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);
80
Young Fu

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.

116
Blaise Doughan

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.

16
Andrea Luciano

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;
    }
}
2
Iván

https://www.baeldung.com/jaxb

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);
    }
}
0
Mykhaylo Adamovych

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);
    }
}
0
Mykhaylo Adamovych