web-dev-qa-db-ja.com

JAX-WS入力を検証する最善の方法は?

現在、JAX-WSを使用して新しいWebサービスのセットを作成していますが、入力を検証するための最良の方法を決定するのに苦労しています。実装クラスでいくつかの検証を行うことができますが、いくつかの入力エラーはサイレントに失敗します。たとえば、数値要素の文字データは、JAXBオブジェクトの整数になります。

これらは私が出くわしたデザインです。

  1. @SchemaValidation
    このアノテーションをエンドポイントクラスに追加すると、JAX-WSが検証を処理します。これはTomcatでローカルに機能しましたが、一部のサーバーでは機能しないという懸念があります。私の主な不満は、応答でエラーがどのように出力されるかについての制御を放棄しなければならないことです。

  2. 文字列としてのすべての入力
    私はこのアプローチが嫌いですが、すべての入力が文字列として定義されている他のWebサービスを見てきました。これは、APIを呼び出す場所で確認できるため、数値要素の文字データのケースをキャッチしますが、誤った名前のxml要素は見逃します。

せっけんの障害としてではなく、APIエラーと同じ方法でエラーを返すことを本当に望んでいます。何か案は?ある種のフィルターでリクエストを傍受することについて話しているサイトをいくつか見ました。ただし、これがさまざまな操作のさまざまな応答でどのように機能するかはわかりません。

例えば。

<S:Envelope xmlns:S="http://schemas.xmlsoap.org/soap/envelope/">
   <S:Body>
      <myOperationResponse>
         <return>
            <success>false</success>
            <errors>
               <error>
                  <code>UNIQUECODE</code>
                  <message>Message text</message>
               </error>
            </errors>
         </return>
      </myOperationResponse>
   </S:Body>
</S:Envelope>

多分私はあまりにも多くを求めていますが、私が何かを逃したかどうか見るだろうと思いました。 TIA。

11
Ben Thurley

1つの可能な方法を説明するこの記事を見つけました。
http://one-size-doesnt-fit-all.blogspot.co.uk/2009/04/jax-ws-schemavalidation-custom-handler.html

標準の応答レイアウトで解析エラーメッセージを返すようにしています。私はそれが顧客のマシンで動作することをテストする必要があります。 (@SchemaValidationで問題が発生したと言う人もいます)

8
Ben Thurley

制御を主張する場合(Jax-WSを実行するときに通常は放棄する必要があるようなもの...)、XSDスキーマに対して検証するプロバイダーとバリデーターを実装できます。

XSDスキーマは、入力の検証(タイプと潜在的な列挙、パターンマッチングなど)を処理します。

_javax.xml.ws.Provider_をSOAPエンドポイントとして実装するには、次のようなクラスを作成します

_@javax.xml.ws.ServiceMode(value = javax.xml.ws.Service.Mode.MESSAGE)
@javax.xml.ws.WebServiceProvider(
    wsdlLocation = "WEB-INF/wsdl/MyService.wsdl", 
    targetNamespace = "urn-com-acme-webservice", 
    serviceName = "ProcessPurchaseOrderService", 
    portName = "ProcessPurchaseOrderPort"
)
public class ProcessPurchaseOrder implements Provider<SOAPMessage> {


            @override
    public SOAPMessage invoke(final SOAPMessage request) {

                //see below     
    }
}
_

SOAPMessageinvokeメソッドに渡され、SOAPMessageでラップされた有効な応答またはSOAPFaultが返されます。

XSDを再度検証するには、_javax.xml.validator_を使用します。

_    URL url = this.getClass().getResource(xsdSchemaLocation);

    String language = XMLConstants.W3C_XML_SCHEMA_NS_URI;
    SchemaFactory factory = SchemaFactory.newInstance(language);
    Schema schema = factory.newSchema(url);

    validator = schema.newValidator();
_

SOAPBody xmlを抽出し、validate()メソッドを使用してValidatorに対して検証します。

検証に関する例外をキャッチし、独自のSOAP障害:

_ //Build the SOAP Fault Response
 MessageFactory factory = MessageFactory.newInstance(SOAPConstants.SOAP_1_1_PROTOCOL);
 SOAPMessage response = factory.createMessage();

 SOAPFault fault = response.getSOAPBody().addFault();
 fault.setFaultString(myCustomErrorString);

 fault.addDetail().addChildElement("exception").addTextNode(myCustomErrorId);
_

次に、障害を含むSOAPMessageを返します。

(いいえ、私はSOAP Webサービス)が好きではありません)

7
Bruno Grieder

達成しようとしているシナリオでは、SOAP障害はありません。検証ロジック()の一部になります最終的にリクエストを処理するコード)は、すべての検証シナリオが処理されることを確認する必要があります。

私たちは、サードパーティでWebサービスを統合しても、SOAPの障害から多くを解読できず、あなたが考えていたのと同じようにエラー応答を作成するというこのシナリオに直面していました。次のアプローチを提案します。

  • 独自の検証ロジックを作成する
  • 適切なオブジェクト構造を作成します。すでにXML形式のものがあります。それを客観化する必要があります。
  • この検証ロジックを呼び出して、入力オブジェクトを渡します。検証ロジックは、すべての入力を検証し、適切な応答オブジェクト(myOperationResponse)を設定します。
  • 検証メソッドに戻ったら、ステータスオブジェクトまたはエラーオブジェクトを確認します。エラーがある場合は、応答オブジェクトを返しますOR要求の処理をさらに進めてから、成功応答を返します。
2
Santosh

私があなたを正しく理解しているかどうかはわかりませんが、mabyこれはあなたを助けます:

http://blog.bdoughan.com/2010/12/jaxb-and-marshalunmarshal-schema.html

0
Dennis Kriechel