JAXB marshals xsd: dateTime olduğunda kullanılan tarih formatını nasıl belirlersiniz?


87

JAXB bir date nesnesini ( XMLGregorianCalendar) bir xsd: dateTime öğesine sıraladığında. Elde edilen XML'nin biçimini nasıl belirtebilirsiniz?

Örneğin: Varsayılan veri biçimi milisaniyeleri <StartDate>2012-08-21T13:21:58.000Z</StartDate> atlamam gereken milisaniyeleri kullanıyor. <StartDate>2012-08-21T13:21:58Z</StartDate>

Kullanmasını istediğim çıktı formunu / tarih formatını nasıl belirtebilirim? Nesneyi javax.xml.datatype.DatatypeFactoryoluşturmak için kullanıyorum XMLGregorianCalendar.

XMLGregorianCalendar xmlCal = datatypeFactory.newXMLGregorianCalendar(cal);

Yanıtlar:


127

XmlAdapterBir tarih türünün XML'e nasıl yazılacağını özelleştirmek için an kullanabilirsiniz .

package com.example;

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);
        }
    }

}

Ardından @XmlJavaTypeAdapterek açıklamayı, XmlAdapterbelirli bir alan / özellik için kullanılması gerektiğini belirtmek için kullanırsınız.

@XmlElement(name = "timestamp", required = true) 
@XmlJavaTypeAdapter(DateAdapter.class)
protected Date timestamp; 

Bir xjb bağlama dosyası kullanarak:

<xjc:javaType name="java.util.Date" xmlType="xs:dateTime"
        adapter="com.example.DateAdapter"/>

yukarıda belirtilen açıklamayı üretecektir.
(By sonunda ekleyerek xjcad: xmlns:xjc="http://java.sun.com/xml/ns/jaxb/xjc")


2
Bu cevap için teşekkürler! Ek açıklamayı xsd veya bir bağlama dosyası aracılığıyla eklemek mümkün mü? Yalnızca bindings.xml hakkında sıkça alıntılanan blog girişinizi buldum, ancak bu diğer yönleri de kapsıyor, sanırım.
guerda

9
@PeterRader'ın da belirttiği gibi, SimpleDateFormat iş parçacığı için güvenli değildir - iki iş parçacığı aynı anda ya mareşal ya da unmarshal girecek olsaydı, çok öngörülemeyen sonuçlar elde edebilirsiniz. Bunu normal testlerde yeniden üretmek çok zor olurdu, ancak yük altında olabilir ve teşhis edilmesi son derece zor olurdu. Mareşal ve unmarshal ile yeni bir SimpleDateFormat oluşturmak daha iyidir (ancak gerekirse statik bir biçim dizesi kullanın).
Colselaw

1
Bunu yaptım ve neredeyse işe yaradı. Ancak Class has two properties of the same name "timeSeries"hata alıyordum - bu, ek açıklamayı üye düzeyinde değil alıcıya koyarak çözüldü. (Dan @megathor sayesinde stackoverflow.com/questions/6768544/... )
gordon613

1
@ gordon613 - Bu makale, ek açıklamayı nereye koyacağınızla ilgili bazı ek bilgiler sağlayacaktır: blog.bdoughan.com/2011/06/using-jaxbs-xmlaccessortype-to.html
bdoughan

3
Kritik blok "senkronize" ile korunduğu için herhangi bir problem yaşanmaz. Birden fazla arama yapılırsa (performans) sorunu olacaktır.
Mike Argyriou

17

XMLGregorianCalendar'ı oluşturmak için bir SimpleDateFormat kullanıyorum, bu örnekte olduğu gibi:

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));
}

İlk yöntem, XML düzenleyici tarafından geçerli bir xsd: date olarak biçimlendirilmiş bir XMLGregorianCalendar örneği oluşturur, ikinci yöntem geçerli bir xsd: dateTime sonucunu verir.


2

Benim için çok kolay bir yol. Java'da sıralama yapmak için XMLGregorianCalendar'ı biçimlendirme.

Verilerimi sadece iyi formatta oluşturuyorum. toStringİyi bir sonuç üreten çağrılır.

public static final XMLGregorianCalendar getDate(Date d) {
    try {
        return DatatypeFactory.newInstance().newXMLGregorianCalendar(new SimpleDateFormat("yyyy-MM-dd").format(d));
    } catch (DatatypeConfigurationException e) {
        return null;
    }
}

1

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

Kullanım:

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);
    }
}
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.