JAXBがxsd:dateTimeをマーシャルするときに使用される日付形式をどのように指定しますか?


86

JAXBが日付オブジェクト(XMLGregorianCalendar)をxsd:dateTime要素にマーシャリングする場合。結果のXMLの形式をどのように指定できますか?

例:デフォルトのデータ形式はミリ秒<StartDate>2012-08-21T13:21:58.000Z</StartDate> を使用します。ミリ秒を省略する必要があります。 <StartDate>2012-08-21T13:21:58Z</StartDate>

使用する出力フォーム/日付形式を指定するにはどうすればよいですか?オブジェクトのjavax.xml.datatype.DatatypeFactory作成に使用していXMLGregorianCalendarます。

XMLGregorianCalendar xmlCal = datatypeFactory.newXMLGregorianCalendar(cal);

回答:


126

を使用しXmlAdapterて、日付型をXMLに書き込む方法をカスタマイズできます。

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

}

次に、@XmlJavaTypeAdapter注釈をXmlAdapter使用して、を特定のフィールド/プロパティに使用する必要があることを指定します。

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

xjbバインディングファイルの使用:

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

上記の注釈を生成します。
(最終的に追加することによりxjc、名前空間を:xmlns:xjc="http://java.sun.com/xml/ns/jaxb/xjc"


2
この答えをありがとう!xsdまたはバインディングファイルを介して注釈を追加することは可能ですか?bindings.xmlについて頻繁に引用されるブログエントリを見つけただけですが、これは他の側面もカバーしていると思います。
guerda 2013

9
@PeterRaderが述べたように、SimpleDateFormatはスレッドセーフではありません-2つのスレッドがマーシャルまたはアンマーシャルのいずれかに同時に入ると、非常に予測できない結果が生じる可能性があります。これは通常のテストでは再現するのが非常に困難ですが、負荷がかかると発生する可能性があり、診断が非常に困難になります。marshalとunmarshalを使用して新しいSimpleDateFormatを作成することをお勧めします(ただし、必要に応じて静的フォーマット文字列を使用してください)。
コルセロー2015

1
私はこれをしました、そしてそれはほとんど働きました。ただし、Class has two properties of the same name "timeSeries"エラーが発生していました。これは、メンバーレベルではなく、ゲッターに注釈を付けることで解決されました。(stackoverflow.com/questions/6768544/の@megathorに感謝します… )
gordon613 2015年

1
@ gordon613-この記事では、注釈を配置する場所に関する追加情報を提供します: blog.bdoughan.com/2011/06/using-jaxbs-xmlaccessortype-to.html
bdoughan

3
重要なブロックは「同期」で保護されているため、問題はありません。複数の呼び出しが行われると、(パフォーマンス)の問題が発生します。
Mike Argyriou 2017

17

SimpleDateFormatを使用して、次の例のようにXMLGregorianCalendarを作成します。

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

最初のメソッドは、XMLマーシャラーによって有効なxsd:dateとしてフォーマットされたXMLGregorianCalendarのインスタンスを作成し、2番目のメソッドは有効なxsd:dateTimeになります。


2

私にとって非常に簡単な方法。JavaでマーシャリングするためのXMLGregorianCalendarのフォーマット。

データを適切な形式で作成するだけです。toString良い結果を生成呼び出されます。

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

使用法:

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);
    }
}
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.