2

免責事項:私はこのすべてにおいて信じられないほど素人です

XMLに加えてJSONを出力するために取り組んでいるプロジェクトを取得しようとしています。元々、これを行うための以前の方法には、Element の引数を取り、net.sf JSONObject 型のオブジェクトに再帰的に挿入して JSON 出力を作成し、法線を使用して XML にマーシャリングする方法JAXBContextが含まれていました。Marshaller

私が望んでいたのは、MOXy を JAXB プロバイダーとして使用し、バインディングから XML と JSON の両方をマーシャリングすることでした。

当初、XML がマーシャリングされたとき、私は次のことを行いました。

jc = JAXBContext.newInstance("packageA:packageB:packageC...etc.");
public static String marshal(JAXBContext context, JAXBElement<?> je) throws JAXBException {
    StringWriter sout = new StringWriter();
    Marshaller m = context.createMarshaller();
    m.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, Boolean.FALSE);
    m.setProperty(Marshaller.JAXB_ENCODING, "UTF-8");
    m.marshal(je, sout);
    return sout.toString();
}

その後

JAXBElement<myObject> jaxb = 
  new JAXBElement<myObject>(myObject_QNAME, myObject.class, null, value);
return XmlResponseMessage(marshal(jc, jaxb));
}

(これはおそらく重要なので、私が取り組んでいるアプリケーションは spring フレームワークを使用していることに言及する必要があります。)

また、私は EclipseLink に関する Blaise のブログ投稿をすべて読みました。何回か。私はそれについて非常に浅い理解しか持っていないので、彼のページの1つに私をリンクする代わりに、その解決策とそれが機能する理由を説明していただければ幸いです

そうは言っても、バインディングを取得jaxb.propertiesするのではなく、MOXy を取得しようとするために、パッケージの 1 つにファイルを含めてみましJAXBElementた。ただし、JAXBContext.newInstance("my list of : delimited packages")プログラムがハングするだけです。エラーでもなく、ハングするだけです。ステップスルーすると、EclipseLinknewInstanceメソッドの呼び出しがハングしていることがわかります。オンラインで解決策を何時間も探しました。Class[] に含めるクラスが多すぎるため、クラスの配列を使用してプロパティを設定できません。これが、プロパティ ファイルを使用する代わりにネイティブの moxy API を使用できなかった理由でもあります。EclipseLink が正しくセットアップされていると思います。環境変数を設定しeclipselink_home eclipselink.jar をビルドパスに追加しました。

4

1 に答える 1

1

更新 #2

この問題の修正は EclipseLink 2.4.2 および 2.5.0 ストリームにチェックインされており、2013 年 3 月 12 日以降、修正を含むナイトリー ビルドを次のリンクからダウンロードできます。


更新 #1

数回メールをやり取りした結果、発生している問題は次のバグによるものだと思います。リンクを使用して、この問題に関する進捗状況を追跡できます。

以下に、それがどのように現れるかを示します。

ObjectFactory

問題が発生するには、 が と同じである@XmlElementDecl注釈が必要です。namesubstitutionHeadName

@XmlRegistry
public class ObjectFactory {

    @XmlElementDecl(name="foo", substitutionHeadName="foo")
    public JAXBElement<Foo> createBar(Foo foo) {
        return new JAXBElement<Foo>(new QName("foo"), Foo.class, foo);
    }

}

ドメイン オブジェクト (Foo)

@XmlElementRef次に、ドメイン オブジェクトの 1 つに、で定義した要素を参照する注釈を付ける必要があります@XmlElementDecl

public class Foo {

    @XmlElementRef(name="foo")
    public Foo foo;

}

デモ

を作成するときに問題が発生しますJAXBContext

public class Demo {

    public static void main(String[] args) throws Exception {
        JAXBContext jc = JAXBContext.newInstance(Foo.class, ObjectFactory.class);
        System.out.println(jc.getClass());
    }

}

痕跡

MOXy は参照要素を追加する無限ループに入ります。

...
    at org.eclipse.persistence.jaxb.compiler.AnnotationsProcessor.addReferencedElement(AnnotationsProcessor.java:3740)
    at org.eclipse.persistence.jaxb.compiler.AnnotationsProcessor.addReferencedElement(AnnotationsProcessor.java:3740)
    at org.eclipse.persistence.jaxb.compiler.AnnotationsProcessor.addReferencedElement(AnnotationsProcessor.java:3740)
    at org.eclipse.persistence.jaxb.compiler.AnnotationsProcessor.addReferencedElement(AnnotationsProcessor.java:3740)
    at org.eclipse.persistence.jaxb.compiler.AnnotationsProcessor.addReferencedElement(AnnotationsProcessor.java:3740)
    at org.eclipse.persistence.jaxb.compiler.AnnotationsProcessor.addReferencedElement(AnnotationsProcessor.java:3740)
    at org.eclipse.persistence.jaxb.compiler.AnnotationsProcessor.addReferencedElement(AnnotationsProcessor.java:3740)
    at org.eclipse.persistence.jaxb.compiler.AnnotationsProcessor.addReferencedElement(AnnotationsProcessor.java:3740)
    at org.eclipse.persistence.jaxb.compiler.AnnotationsProcessor.addReferencedElement(AnnotationsProcessor.java:3740)
...

元の答え

以下を使用してJAXBContext. ネイティブ MOXy コードを使用して、標準の JAXB impl 検索コードをバイパスします。

JAXBContext jc = org.eclipse.persistence.jaxb.JAXBContextFactory.createContext("packageA:packageB:packageC...etc.");

それが機能する場合、問題が impl ルックアップ コードに関連していることがわかり、そこから進むことができます。

于 2013-03-05T21:35:44.657 に答える