web-dev-qa-db-ja.com

JAX-WS-例外をフォールトにマップする

JAX WSを使用してWebServiceを公開しています。このサービスの操作の一部は、例外を生成する可能性があります。内部サーバー例外ではなく、操作呼び出しの入力引数に依存する例外。

次のように、操作がカスタム例外をスローするように指定した場合:

@WebService
@SOAPBinding(style = Style.RPC, use = Use.LITERAL)
public class MyServiceEndpointImpl implements MyServiceEndpoint {

    @WebMethod
    public void throwsException throws InvalidInputException;
}

アプリケーションを実行すると、次のスタックトレースが発生します。

 com.Sun.xml.ws.model.RuntimeModelerException: runtime modeler error: Wrapper class com.mypackage.ws.services.jaxws.InvalidInputExceptionBean is not found. Have you run APT to generate them?
    at com.Sun.xml.ws.model.RuntimeModeler.getClass(RuntimeModeler.Java:285)
    at com.Sun.xml.ws.model.RuntimeModeler.processExceptions(RuntimeModeler.Java:1006)
    at com.Sun.xml.ws.model.RuntimeModeler.processRpcMethod(RuntimeModeler.Java:969)
    at com.Sun.xml.ws.model.RuntimeModeler.processMethod(RuntimeModeler.Java:546)
    at com.Sun.xml.ws.model.RuntimeModeler.processClass(RuntimeModeler.Java:370)
    at com.Sun.xml.ws.model.RuntimeModeler.buildRuntimeModel(RuntimeModeler.Java:256)
    at com.Sun.xml.ws.server.EndpointFactory.createSEIModel(EndpointFactory.Java:322)
    at com.Sun.xml.ws.server.EndpointFactory.createEndpoint(EndpointFactory.Java:188)
    at com.Sun.xml.ws.api.server.WSEndpoint.create(WSEndpoint.Java:467)
    at org.jvnet.jax_ws_commons.spring.SpringService.getObject(SpringService.Java:333)
    at org.jvnet.jax_ws_commons.spring.SpringService.getObject(SpringService.Java:45)
    at org.springframework.beans.factory.support.FactoryBeanRegistrySupport$1.run(FactoryBeanRegistrySupport.Java:121)

@XmlRootEntityInvalidInputExceptionに追加しても問題は解決しません。

これがWebサービスを介して障害を報告する推奨方法ではない場合、より良い方法はありますか?私の例外はRuntimeExceptionから継承し、トランスポートに依存してエラー処理を行う必要がありますか(つまり、すべてがSOAPExceptionにラップされます)? Spring-WS 'SoapFaultAnnotationExceptionResolverのようなものを期待していた。 JAX-WSで利用できる同様のものはありますか?

27
waxwing

_@WebFault_ で例外に注釈を付けようとしましたか?また、getFaultInfo()を実装していますか?

編集:私は私の答えがおそらく十分に詳細ではなかったことに気づきました。 this thread で思い出されるように(例):

JAX-WS 2.0仕様では、_@WebFault_で注釈が付けられた例外に2つのコンストラクターと1つのメソッドが必要であることを要求しています[障害情報を取得するのに適しています]:

_WrapperException(String message, FaultBean faultInfo)
WrapperException(String message, FaultBean faultInfo, Throwable cause)
FaultBean getFaultInfo()
_

WrapperExceptionは例外の名前に置き換えられ、FaultBeanはフォルトBeanを実装するクラス名に置き換えられます。フォルトBeanはJava Beanであり、フォルトの情報が含まれ、Webサービスクライアントがフォルトの原因を知るために使用されます。

これについては、セクション2.5「JAX-WS仕様の障害」で詳しく説明しています。あなたの例外はこれに準拠していますか?コードを投稿できますか?


OPは正しいです。仕様2.1、セクション3.7サービス固有の例外に従って、_@WebFault_アノテーションを使用する必要はありません。JAX-WSは、セクション2.5で説明されているパターンに一致しない例外に対してラッパーBeanを動的に生成できます(提供するだけです)障害に含めたい情報のゲッター)。セクション2.5で説明されているパターンに一致する例外(つまり、getFaultInfoメソッドと_@WebFault_アノテーションを持つ例外)の場合、FaultBeanが入力として使用されます例外をXMLスキーマにマッピングするときにJAXBに。

したがって、上記の解決策(セクション2.5で説明されているパターンに一致する)は回避策にすぎません。ラッパーBeanの生成は、他の例外でも機能するはずです。そして、なぜこれがここで失敗するのかわかりません。

27
Pascal Thivent

上記の回答への追加。私は私のInvalidInputException実装としてこれで終わりました:

@WebFault(faultBean = "com.mypackage.ws.exception.FaultBean")
public class InvalidInputException extends Exception {

    private static final long serialVersionUID = 1L;

    private FaultBean faultBean;

    public InvalidInputException() {
        super();
    }

    public InvalidInputException(String message, FaultBean faultBean, Throwable cause) {
        super(message, cause);
        this.faultBean = faultBean;
    }

    public InvalidInputException(String message, FaultBean faultBean) {
        super(message);
        this.faultBean = faultBean;
    }

    public FaultBean getFaultInfo() {
        return faultBean;
    }
}

そしてFaultBeanは、現在データがまったくない単純なPOJOです。現在、JAX-WS仕様(3.7サービス固有の例外を参照)によると、@ WebFaultで注釈が付けられた例外に必要なものに準拠しているため、そのためのラッパーBeanは作成されず、おそらく失敗していました。

これはまともな回避策ですが、質問のエラーについては説明していません。

17
waxwing