Статьи

JAXB и Joda-Time: даты и время

Joda-Time предоставляет альтернативу классам Date и Calendar, которые в настоящее время представлены в Java SE. Поскольку они предоставляются в отдельной библиотеке, JAXB не обеспечивает сопоставление по умолчанию для этих классов. Мы можем предоставить необходимое отображение через XmlAdapters. В этом посте мы рассмотрим следующие типы Joda-Time:
  DateTime
, DateMidnight,
LocalDate,
LocalTime
,
LocalDateTime.

Модель Java


Следующая модель домена будет использоваться для этого примера:

package blog.jodatime;
 
import javax.xml.bind.annotation.XmlRootElement;
import javax.xml.bind.annotation.XmlType;
 
import org.joda.time.DateMidnight;
import org.joda.time.DateTime;
import org.joda.time.LocalDate;
import org.joda.time.LocalDateTime;
import org.joda.time.LocalTime;
 
@XmlRootElement
@XmlType(propOrder={
    "dateTime",
    "dateMidnight",
    "localDate",
    "localTime",
    "localDateTime"})
public class Root {
 
    private DateTime dateTime;
    private DateMidnight dateMidnight;
    private LocalDate localDate;
    private LocalTime localTime;
    private LocalDateTime localDateTime;
 
    public DateTime getDateTime() {
        return dateTime;
    }
 
    public void setDateTime(DateTime dateTime) {
        this.dateTime = dateTime;
    }
 
    public DateMidnight getDateMidnight() {
        return dateMidnight;
    }
 
    public void setDateMidnight(DateMidnight dateMidnight) {
        this.dateMidnight = dateMidnight;
    }
 
    public LocalDate getLocalDate() {
        return localDate;
    }
 
    public void setLocalDate(LocalDate localDate) {
        this.localDate = localDate;
    }
 
    public LocalTime getLocalTime() {
        return localTime;
    }
 
    public void setLocalTime(LocalTime localTime) {
        this.localTime = localTime;
    }
 
    public LocalDateTime getLocalDateTime() {
        return localDateTime;
    }
 
    public void setLocalDateTime(LocalDateTime localDateTime) {
        this.localDateTime = localDateTime;
    }
 
}
XmlAdapters


Поскольку Joda-Time и XML Schema представляют данные и информацию о времени в соответствии с ISO 8601, реализация XmlAdapters довольно тривиальна.

DateTimeAdapter

package blog.jodatime;
 
import javax.xml.bind.annotation.adapters.XmlAdapter;
import org.joda.time.DateTime;
 
public class DateTimeAdapter
    extends XmlAdapter<String, DateTime>{
 
    public DateTime unmarshal(String v) throws Exception {
        return new DateTime(v);
    }
 
    public String marshal(DateTime v) throws Exception {
        return v.toString();
    }
 
}
DateMidnightAdapter

package blog.jodatime;
 
import javax.xml.bind.annotation.adapters.XmlAdapter;
import org.joda.time.DateMidnight;
 
public class DateMidnightAdapter
    extends XmlAdapter<String, DateMidnight> {
 
    public DateMidnight unmarshal(String v) throws Exception {
        return new DateMidnight(v);
    }
 
    public String marshal(DateMidnight v) throws Exception {
        return v.toString();
    }
 
}
LocalDateAdapter

package blog.jodatime;
 
import javax.xml.bind.annotation.adapters.XmlAdapter;
import org.joda.time.LocalDate;
 
public class LocalDateAdapter
    extends XmlAdapter<String, LocalDate>{
 
    public LocalDate unmarshal(String v) throws Exception {
        return new LocalDate(v);
    }
 
    public String marshal(LocalDate v) throws Exception {
        return v.toString();
    }
 
}
LocalTimeAdapter

package blog.jodatime;
 
import javax.xml.bind.annotation.adapters.XmlAdapter;
import org.joda.time.LocalTime;
 
public class LocalTimeAdapter
    extends XmlAdapter<String, LocalTime> {
 
    public LocalTime unmarshal(String v) throws Exception {
        return new LocalTime(v);
    }
 
    public String marshal(LocalTime v) throws Exception {
        return v.toString();
    }
 
}
LocalDateTimeAdapter

package blog.jodatime;
 
import javax.xml.bind.annotation.adapters.XmlAdapter;
import org.joda.time.LocalDateTime;
 
public class LocalDateTimeAdapter
    extends XmlAdapter<String, LocalDateTime>{
 
    public LocalDateTime unmarshal(String v) throws Exception {
        return new LocalDateTime(v);
    }
 
    public String marshal(LocalDateTime v) throws Exception {
        return v.toString();
    }
 
}
Регистрация XmlAdapters


Мы будем использовать
аннотацию
@XmlJavaTypeAdapters для регистрации типов Joda-Time на уровне пакета. Это означает, что всякий раз, когда эти типы обнаруживаются в поле / свойстве класса в этом пакете
, автоматически применяется
XmlAdapter .

@XmlJavaTypeAdapters({
    @XmlJavaTypeAdapter(type=DateTime.class,
        value=DateTimeAdapter.class),
    @XmlJavaTypeAdapter(type=DateMidnight.class,
        value=DateMidnightAdapter.class),
    @XmlJavaTypeAdapter(type=LocalDate.class,
        value=LocalDateAdapter.class),
    @XmlJavaTypeAdapter(type=LocalTime.class,
        value=LocalTimeAdapter.class),
    @XmlJavaTypeAdapter(type=LocalDateTime.class,
        value=LocalDateTimeAdapter.class)
})
package blog.jodatime;
 
import javax.xml.bind.annotation.adapters.XmlJavaTypeAdapter;
import javax.xml.bind.annotation.adapters.XmlJavaTypeAdapters;
 
import org.joda.time.DateMidnight;
import org.joda.time.DateTime;
import org.joda.time.LocalDate;
import org.joda.time.LocalDateTime;
import org.joda.time.LocalTime;
Демо

Для запуска следующей демонстрации вам понадобится банка Joda-Time на вашем пути к классам. Это можно получить здесь:

  • http://sourceforge.net/projects/joda-time/files/joda-time/
    package blog.jodatime;
     
    import javax.xml.bind.JAXBContext;
    import javax.xml.bind.Marshaller;
     
    import org.joda.time.DateMidnight;
    import org.joda.time.DateTime;
    import org.joda.time.LocalDate;
    import org.joda.time.LocalDateTime;
    import org.joda.time.LocalTime;
     
    public class Demo {
     
        public static void main(String[] args) throws Exception {
            Root root = new Root();
            root.setDateTime(new DateTime(2011, 5, 30, 11, 2, 30, 0));
            root.setDateMidnight(new DateMidnight(2011, 5, 30));
            root.setLocalDate(new LocalDate(2011, 5, 30));
            root.setLocalTime(new LocalTime(11, 2, 30));
            root.setLocalDateTime(new LocalDateTime(2011, 5, 30, 11, 2, 30));
     
            JAXBContext jc = JAXBContext.newInstance(Root.class);
     
            Marshaller marshaller = jc.createMarshaller();
            marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);
            marshaller.marshal(root, System.out);
        }
     
    }