1

xjcで生成されたクラスをカスタム例外のサブクラスにして、実際にそれらをスローし、JAXBContextで処理できるようにするにはどうすればよいですか?多くの場合、Webサービスは、実際には例外であるはずの定義されたさまざまな障害を返しますが、そうではないため、不必要にそれらをラップする必要があります。

4

2 に答える 2

2

そこから拡張されたJAXB(JSR-222)モデルを作成できたとしても、そこからExceptionを作成することはできませんJAXBContextExceptionJAXBと互換性のあるドメインモデルでラップすることをお勧めします。

Javaモデル(Foo)

以下は、を拡張する単純なJavaクラスですException

package forum12840627;

import javax.xml.bind.annotation.XmlRootElement;

@XmlRootElement
public class Foo extends Exception {

}

デモ

JAXBContext以下のデモコードは、Javaモデルでを作成しようとします。

package forum12840627;

import javax.xml.bind.JAXBContext;

public class Demo {

    public static void main(String[] args) throws Exception {
        JAXBContext jc = JAXBContext.newInstance(Foo.class);
    }

}

出力

以下は、デモコードの実行から返される例外です。問題はException、有効なJAXBクラスではなく、JAXB実装がJavaモデルを処理するときにスーパークラスをプルすることです。(注:独自のドメインモデルでは、スーパークラスに注釈を付けて、スーパークラス@XmlTransientが処理されないようにすることができます:http://blog.bdoughan.com/2011/06/ignoring-inheritance-with-xmltransient.html

Exception in thread "main" com.sun.xml.bind.v2.runtime.IllegalAnnotationsException: 1 counts of IllegalAnnotationExceptions
java.lang.StackTraceElement does not have a no-arg default constructor.
    this problem is related to the following location:
        at java.lang.StackTraceElement
        at public java.lang.StackTraceElement[] java.lang.Throwable.getStackTrace()
        at java.lang.Throwable
        at java.lang.Exception
        at forum12840627.Foo

    at com.sun.xml.bind.v2.runtime.IllegalAnnotationsException$Builder.check(IllegalAnnotationsException.java:102)
    at com.sun.xml.bind.v2.runtime.JAXBContextImpl.getTypeInfoSet(JAXBContextImpl.java:472)
    at com.sun.xml.bind.v2.runtime.JAXBContextImpl.<init>(JAXBContextImpl.java:302)
    at com.sun.xml.bind.v2.runtime.JAXBContextImpl$JAXBContextBuilder.build(JAXBContextImpl.java:1140)
    at com.sun.xml.bind.v2.ContextFactory.createContext(ContextFactory.java:154)
    at com.sun.xml.bind.v2.ContextFactory.createContext(ContextFactory.java:121)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
    at java.lang.reflect.Method.invoke(Method.java:597)
    at javax.xml.bind.ContextFinder.newInstance(ContextFinder.java:202)
    at javax.xml.bind.ContextFinder.find(ContextFinder.java:363)
    at javax.xml.bind.JAXBContext.newInstance(JAXBContext.java:574)
    at javax.xml.bind.JAXBContext.newInstance(JAXBContext.java:522)
    at forum12840627.Demo.main(Demo.java:8)

更新#1

JAXBプロバイダーとしてEclipseLinkJAXB(MOXy)を使用している場合、javax.*およびjava.*パッケージ内のクラスはドメインクラスとして扱われないため、この例外は表示されません。MOXyは、WebLogic 12c環境のデフォルトのJAXBプロバイダーであるか、jaxb.propertiesファイルを使用して構成できます。

詳細については

更新#2

JAXBリファレンス実装の最新バージョンは、MOXyと同様にこのユースケースを処理しているように見えます。私の元々の移植性の懸念はそれほど問題ではないかもしれません。

于 2012-12-05T14:21:08.710 に答える
1

そうそう、やっと見つけた!Inheritance プラグインは、生成されたクラスをクラスから継承させたり、追加のインターフェースを実装したりできます。

次のようなものを含める必要があります

  <bindings node="//xsd:complexType[@name='WhateverException']">
    <inheritance:extends>foo.bar.WhateverException</inheritance:extends>
  </bindings>

バインディング ファイルに追加し、getStackTrace() をオーバーライドして、マーシャリングされないように null を返します。

残念ながら、一部の JAXB 実装で問題が発生する可能性があります ( Blaise Doughan の回答を参照)。その回避策はまだ見つかりません。そのため、あまり移植性のないソリューションを使用するか、JAXB オブジェクトを例外にラップすることができます。

于 2012-12-05T16:10:14.867 に答える