12

JAXB が XML スキーマのバインドされたクラスを生成する方法に問題があります (精度のために、これを変更することはできません)。xsd:date 型を Joda-time LocalDate オブジェクトにマップしたいので、ここ、ここ、ここを読んDateAdapterクラスを作成しました。

public class DateAdapter extends XmlAdapter<String,LocalDate> {
    private static DateTimeFormatter fmt = DateTimeFormat.forPattern("yyyyMMdd");

    public LocalDate unmarshal(String v) throws Exception {
        return fmt.parseLocalDate(v);
    }

    public String marshal(LocalDate v) throws Exception {
        return v.toString("yyyyMMdd");
    }
}

そして、グローバル バインディング ファイルに以下を追加しました。

  <jaxb:globalBindings>
        <jaxb:javaType name="org.joda.time.LocalDate" xmlType="xs:date"
            parseMethod="my.classes.adapters.DateAdapter.unmarshal"
            printMethod="my.classes.adapters.DateAdapter.marshal" />
    </jaxb:globalBindings>

問題は、プロジェクトを Maven コンパイルしようとすると、次のエラーで失敗することです。

[ERROR] \My\Path\MyProject\target\generated-sources\xjc\my\classes\generated\Adapter1.java:[20,59] non-static method unmarshal(java.lang.String) cannot be referenced from a static context
[ERROR] \My\Path\MyProject\target\generated-sources\xjc\my\classes\generated\Adapter1.java:[24,59] non-static method marshal(org.joda.time.LocalDate) cannot be referenced from a static context

...そして、これは物事が奇妙になるところです。JAXB は、以下を含むクラス Adapter1 を生成します。

public class Adapter1
    extends XmlAdapter<String, LocalDate>
{


    public LocalDate unmarshal(String value) {
        return (my.classes.adapters.DateAdapter.unmarshal(value));
    }

    public String marshal(LocalDate value) {
        return (my.classes.adapters.DateAdapter.marshal(value));
    }

}

....これがコンパイルエラーの原因です。

さて、私の質問は次のとおりです。

  • アダプターが XmlAdapter をオーバーライドしているため、メソッドを静的にすることはできません....どうすればこれを回避できますか?
  • Adapter1.class の生成を完全に回避できますか?? パッケージレベルの注釈 XmlJavaTypeAdapters を使用している可能性があります。(JAXB は独自の package-info.java を既に生成しています....)

私の状況を明確にしたことを願っています。
ありがとう

4

7 に答える 7

7

延長する必要はありませんXmlAdapter

POJO で静的メソッドを作成するだけで機能します。

例:

 public class DateAdapter {
    private static DateTimeFormatter fmt = DateTimeFormat.forPattern("yyyyMMdd");

    public static LocalDate unmarshal(String v) throws Exception {
        return fmt.parseLocalDate(v);
    }

    public static String marshal(LocalDate v) throws Exception {
        return v.toString("yyyyMMdd");
    }
 }
于 2012-09-20T13:35:45.993 に答える
4

拡張する必要はなくXmlAdapter、Joda-Time v2 では静的メソッドを実装する必要さえありません。これらは既に提供されているためです。

<jaxb:javaType xmlns="http://java.sun.com/xml/ns/jaxb" 
    name="org.joda.time.LocalDate"
    xmlType="xs:date"
    parseMethod="org.joda.time.LocalDate.parse"
    printMethod="java.lang.String.valueOf"
/>

xs:date xs:time および xs:dateTime の JAXB データ型コンバーターを参照してください。

于 2016-06-10T11:36:48.330 に答える
3

このソリューションが役立つことがわかりました http://blog.bdoughan.com/2011/05/jaxb-and-joda-time-dates-and-times.html

アダプタを作成します

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); - old solution that didn't properly handled the timezone
        return DateTime.parse(v);
    }

    public String marshal(DateTime v) throws Exception {
        return v.toString();
    }

}

次に、ソースで blog/jodatime/package-info.java を定義して、注釈を付けて登録します

@XmlJavaTypeAdapters({ @XmlJavaTypeAdapter(type = DateTime.class, value = JodaDateTimeJaxbAdapter.class) })
package blog.jodatime;

import javax.xml.bind.annotation.adapters.*;

import org.joda.time.*;

次に、DateTime のシリアル化が他の変更なしで行われることを期待する必要があります。クラスに @XmlRootElement で注釈を付けることを忘れないでください。

于 2013-07-16T09:51:15.177 に答える
3

XML スキーマから XmlAdapters を生成するときは、変換のロジックを .xml ではなく静的メソッドに配置する必要がありますXmlAdapter。これは、XmlAdapterロジックを生成できることを活用するためのものです。これが奇妙なメカニズムであることは認識しています。

完全な例

于 2012-09-20T13:33:30.700 に答える
3

XmlAdapterJaxB の Java モデルに注釈を付けたい場合、つまり annotation を使用して、これを拡張しています@XmlJavaTypeAdapter(Adapter1.class)。あなたの場合、拡張しない静的メソッドを持つクラスが必要ですXmlAdapter。parse メソッド (文字列を取得して日付を返す) と print メソッド (日付を取得して文字列を返す) が必要になります。

于 2012-09-20T13:41:17.550 に答える