Simple Object Access Protocol (SOAP) - 概要。 石鹸とは

30.07.2019 アプリケーション

10 件の回答

WSDL は、Web サービスを記述する XML ドキュメントです。 これは実際には Web Services Definition Language の略です。

SOAP は、アプリケーション間で特定のプロトコル (HTTP や SMTP など) を介して情報を交換できるようにする XML ベースのプロトコルです。 これは Simple Object Access Protocol の略で、情報を伝達するためのメッセージング形式に XML を使用します。

REST はアーキテクチャ スタイルです ネットワークシステムそして代表国家の移行を主張する。 それ自体は標準ではありませんが、HTTP、URL、XML などの標準を使用します。

誰かが SOAP/WSDL について言及するたびに、xml で定義されたオブジェクトやクラスのことを思い出します。

「他の PHP クラスと同じように SOAP を使用しています。ただし、この場合、クラスはローカルに存在しません。」 ファイルシステムアプリケーションですが、http 経由でアクセスされるリモート ホスト上にあります。"... "SOAP サービスを別の PHP クラスとして使用することを考えている場合、WSDL ドキュメントはすべてのアプリケーションのリストです。 利用可能な方法そしてクラスプロパティ。」

そして、誰かが REST について話すたびに、私は POST、GET、DELETE などの HTTP コマンド (リクエスト メソッド) について考えます。

例: 簡単な言葉で言うと、電卓 Web サービスをお持ちの場合。

WSDL: WSDL は、クライアントに実装または公開できる機能について説明します。 例: 追加、削除、減算など。

SOAP: SOAP を使用すると、doDelete()、doSubtract()、doAdd() などのアクションを実際に実行できます。 つまり、SOAP と WSDL はリンゴとオレンジのようなものです。 それらを比較すべきではありません。 どちらも独自の機能を持っています。

SOAP と WSDL を使用する理由: プラットフォーム全体で独立したデータを交換するため。

編集:通常では 日常生活:

WSDL:レストランに行くとメニュー項目が表示されますが、これが WSDL です。

プロキシクラス:さて、メニュー項目を見た後、頭を組み立てます (注文に基づいて心を処理します)。つまり、基本的には WSDL ドキュメントに基づいて Proxy クラスを作成します。

石鹸:次に、実際にメニューに基づいて食べ物を注文すると、SOAP を使用して実行されるサービス メソッドを呼び出すためにプロキシ クラスを使用することが暗示されます。

SOAP → SOAP (Simple Object Access Prototype) は、マシン間通信用に設計されたプロトコルベースのアプリケーション層です。 プロトコルは標準ルールを定義します。 特定のプロトコルを使用するすべての当事者は、プロトコルの規則に従う必要があります。 TCP と同様に、トランスポート層で巻き戻されます。 SOAP プロトコルは、アプリケーション レベル (SOAP をサポートするアプリケーション (Axis2、.Net)) で理解されます。

WSDL -> SOAP メッセージは、SoapEnevelope -> SoapHeader と SoapBody で構成されます。 メッセージの形式は定義されていませんか? すべてのトランスポート (HTTP、JMS) がサポートされていますか? この情報がなければ。 特定の Web サービスを使用したいクライアントにとって、SOAP メッセージを作成するのは困難です。 たとえそうできたとしても、それが常に機能するかどうかはわかりません。 WSDL は救世主です。 WSDL (Web サービス記述言語) は、SOAP メッセージの操作、メッセージ形式、およびトランスポート データを定義します。

REST → REST (Representation State Transfer) はトランスポートベースです。 アクション指向の SOAP とは異なり、REST はよりリソース指向です。 REST は URL (例 -http://(serverAddress)/employees/employeeNumber/12345) を使用してリソースを検索し、次のものに依存します。 トランスポートプロトコル(HTTP-GET、POST、PUT、DELETE など) リソースを実行するアクション用。 REST サービスは、URL に基づいてリソースを検索し、トランスポート アクション動詞に基づいてアクションを実行します。 それはむしろ建築スタイルと慣習に関するものです。

SOAP は、Simple (sic) Object Access Protocol の略です。 これは、HTTP 経由で XML を送信することにより、リモート オブジェクトへのリモート プロシージャ コールを行うことを目的としていました。

WSDL は Web サービス記述言語です。 「.wsdl」エンドポイントで終わるリクエストでは、使用されることが予想されるリクエストとレスポンスを説明する XML メッセージが表示されます。 サービスとクライアントの間の契約について説明します。

REST は HTTP を使用してサービスにメッセージを送信します。

SOAP は仕様であり、REST はスタイルです。

複雑なことを「ただ」理解することはできません。

WSDL は、Web サービスを記述するための XML ベースの言語です。 メッセージ、操作、および情報について説明します。 トランスポートネットワーク、サービスによって使用されます。 これらの Web サービスは通常 SOAP を使用しますが、他のプロトコルを使用する場合もあります。

WSDL はプログラムで読み取り可能なため、Web サービスを呼び出すために必要なクライアント コードのすべてまたは一部を生成するために使用できます。 これが、SOAP 指向の Web サービスを「自己記述型」と呼ぶことを意味します。

REST は WSDL とはまったく関係ありません。

Wikipedia には、「Web サービス記述言語は、Web サービスを記述するためのモデルを提供する XML ベースの言語です。」と記載されています。 つまり、javadoc が Java ライブラリを指すのと同様に、WSDL は Web サービスを指します。

ただし、WSDL の非常に優れた点は次のとおりです。 ソフトウェア WSDLを使用してクライアントとサーバーを生成できます。

シンプル オブジェクト アクセス プロトコル (SOAP)プロトコルベースです XML言語、異なるアプリケーション システム間でインターネットを介してメッセージを送信するためのルールを定義します。 主にリモート プロシージャ コールに使用されます。 SOAP は元々、(SOAP の Web アプリケーションへの統合を簡素化するために) HTTP の「上位」で機能するように設計されましたが、現在では SMTP などの他のトランスポート プロトコルも使用できるようになりました。

インターネット上にアプリケーション アクセス サービスを作成しているとします。 消費者は、情報を提供することでこのサービスと対話します。 サーバーはデータを処理し、結果を消費者に返します。 システムとの通信を維持するための最良の方法は何ですか?

カスタムクライアントを作成できます- サーバーアプリケーションまた、消費者はサービスにアクセスするために特別なクライアント プログラムを使用する必要があります。 しかし、インターネット ビジネスに真剣に取り組んでいる場合は、Windows、Macintosh、Unix、Linux など、考えられるすべてのクライアント プラットフォームで動作するクライアントを作成する必要があります。つまり、さまざまなクライアントを作成する必要があります。 。

Web の使用についてどう思いますか? もちろん、このソリューションは十分に許容できますが、ブラウザの実装と密接に結びついており、受信および送信情報を送受信するためのインフラストラクチャを作成し、そのような交換用にデータをフォーマットしてパッケージ化する必要があります。 Java または ActiveX を選択して複雑なアプリケーションを実装することもできますが、その場合、明らかに膨らんだ帯域幅要件と不十分なセキュリティを理由に、一部のユーザーがサービスを拒否する可能性があります。

必要なのは、アプリケーション データのパッケージ化と、コンテンツに適合した XML を使用した Web 経由の送信を簡素化する単純なプロトコルだけです。 そうすることで、送信者と受信者の両方がメッセージの内容を簡単に解釈できるようになります。 同時に、HTTP Web プロトコルをトランスポートとして使用することで、ファイアウォール保護のレベルを下げる必要をなくすことができます。

よく説明されている Simple Object Access Protocol (SOAP) は、ホストがアプリケーション オブジェクトをリモートで呼び出して結果を返すことを可能にする単純な「接着」プロトコルです。 SOAP オファー 最小セットアプリケーションがメッセージを渡すことを許可する条件。クライアントはメッセージを送信してプログラム オブジェクトを呼び出すことができ、サーバーはその呼び出しの結果を返すことができます。

SOAP は非常に単純です。メッセージは SOAP コマンドを含む XML ドキュメントです。 SOAP は理論的にはアプリケーションの任意のトランスポート プロトコルに関連付けることができますが、通常は HTTP と組み合わせて使用​​されます。

ケナード・スクリブナー、この本の著者の一人 SOAP を理解する: 信頼できるソリューション(Macmillan USA、2000) によれば、SOAP はメソッドの呼び出しに必要な情報 (引数の値やトランザクション識別子など) を XML 形式に変換することで機能します。

データは HTTP またはその他のトランスポート プロトコルでカプセル化され、受信者 (通常はサーバー) に送信されます。 このサーバーはパケットから SOAP データを抽出し、必要な処理を実行し、結果を SOAP 応答として返します。

Scribner 氏は、SOAP は Java のリモート メソッド呼び出しプロトコルや CORBA の General Inter-ORB Protocol と同様に、リモート プロシージャ コール プロトコルとして機能すると指摘しました。

HTTP と XML は事実上あらゆる場所で使用されているため、SOAP はこれまでに構築されたリモート プロシージャ コール プロトコルの中で最も拡張性が高いと思われると Scribner 氏は述べています。 SOAP は、完全なオブジェクト アーキテクチャとして機能するように設計されていません。

SOAP は、Java、分散コンポーネント オブジェクト モデル、および CORBA のリモート メソッド呼び出しプロトコルを置き換えるものではありません。 これらのモデルのいずれでも使用できるルールが提供されます。 SOAP は完全なソリューションではありません。 オブジェクトのアクティブ化や保護はサポートされていません。 Scribner 氏によると、SOAP 開発者は、コードを作成するのではなく、SOAP 上にコードを構築することで「ユーザーが自分でこのコードを追加すると信頼している」とのことです。 整数部プロトコル自体。

この図は、ホストが特定の株式の価格の見積もりサービスを要求する SOAP 1.1 仕様からの例を示しています。 SOAP リクエストは HTTP POST に埋め込まれており、リクエストの本文ではリクエストのタイプとパラメータ (銘柄記号) を指定します。 また、応答では、単一の戻り値 (34.5 インチ) を含む HTTP 応答にカプセル化された XML オブジェクトも提供されます。 この場合).

SOAPの特徴

SOAP を使用すると、開発者は既存のアプリケーションのプログラムを呼び出すための SOAP メッセージを作成するのと同じくらい迅速に Web サービスを作成し、それらのアプリケーションを単純な Web ページに追加できます。 さらに、開発者は専用アプリケーションで SOAP 呼び出しを使用し、他の人の Web ページに移植できるアプリケーションを作成できるため、時間と費用のかかる開発プロセスを回避できます。

『Understanding SOAP』という本のもう 1 人の著者である Mark Stiver 氏によると、これはまさに Microsoft が有望な .Net プラットフォームで追求している目標です。 「ここがSOAPの強みです。 これは、開発者にとって、潜在的な非互換性を心配することなくアプリケーションを作成するための非常に優れた方法を提供します」と彼は言います。

SOAPの例

次の例は、GetLastTradePrice という SOAP リクエストを示しています。これにより、クライアントは特定の株式の最新相場のリクエストを送信できます。

POST/株価情報 HTTP/1.1
ホスト: ストッククォートサーバー.com
コンテンツタイプ:テキスト/xml; charset="utf-8"
コンテンツの長さ:んんん
SOAPアクション:「染ウリ」

最初の 5 行 (HTTP ヘッダーの一部) はメッセージ タイプ (POST)、ホスト、ペイロード タイプ、およびペイロード長を指定し、SOAPAction ヘッダーは SOAP リクエストの目的を指定します。 SOAP メッセージ自体は XML ドキュメントであり、最初に SOAP エンベロープがあり、次に XML要素、SOAP 名前空間と属性 (存在する場合) を指定します。 SOAP エンベロープには、ヘッダー (ただし、この場合は含まれません) と、その後に続く SOAP 本文を含めることができます。 この例では、本文には GetLastTradePrice リクエストと、最新の相場がリクエストされる銘柄のシンボルが含まれています。 このクエリに対する答えは次のようになります。

HTTP/1.1 200 OK
コンテンツタイプ:テキスト/xml; charset="utf-8"
コンテンツの長さ:んんん

繰り返しますが、最初の 3 行は HTTP ヘッダーの一部です。 SOAP メッセージ自体は、GetLastTradePriceResponse というラベルが付いた元のリクエストに対する応答を含むエンベロープで構成され、戻り値 (この場合は 34.5) が含まれます。

帽子 7月 23, 2013 at 01:09 pm

PHP での SOAP クライアント/サーバー アプリケーションの作成

  • PHP
  • チュートリアル

こんにちは、みんな!
たまたま、 最近 Webサービスの開発を始めました。 ただし、今日のトピックは私に関するものではなく、SOAP 1.2 プロトコルに基づいて独自の XML Web サービスを作成する方法についてです。

このトピックを読んだ後、次のことができるようになることを願っています。

  • Web アプリケーションの独自のサーバー実装を作成します。
  • Web アプリケーションの独自のクライアント実装を作成します。
  • 独自の Web サービス記述 (WSDL) を作成します。
  • 同じタイプのデータのクライアント配列をサーバーに送信します。
ご想像のとおり、すべての魔法は次のように起こります。 PHPを使用して組み込みの SoapClient クラスと SoapServer クラス。 私たちのウサギはSMSメッセージを送信するサービスになります。

1 問題ステートメント

1.1 境界

最初に、このトピックの最後に達成される結果に対処することを提案します。 上で発表したように、SMS メッセージを送信するサービスを作成します。より正確には、SOAP プロトコルを介してさまざまなソースからメッセージを受信します。 その後、それらがどのような形式でサーバーに届くかを検討します。 残念ながら、プロバイダーにさらに送信するためにメッセージをキューに入れるプロセスについては、多くの理由からこの投稿の範囲を超えています。

1.2 どのデータを変更しますか?

よかった、境界線が決まりました! 次に実行する必要があるステップは、サーバーとクライアントの間でどのようなデータを交換するかを決定することです。 このトピックについては、髪をあまり長く分割せず、主な質問にすぐに自分で答えることをお勧めします。
  • SMS メッセージを加入者に送信するには、サーバーに最低限どのデータを送信する必要がありますか?
  • クライアントのニーズを満たすためには、サーバーから最低限どのようなデータを送信する必要がありますか?
このためには、次のものを送信する必要があることがわかります。
  • 番号 携帯電話、 そして
  • SMS メッセージのテキスト。
基本的に、送信にはこれら 2 つの特徴だけで十分ですが、誕生日の挨拶を含む SMS が午前 3 時か 4 時に届く場合をすぐに想像します。 この瞬間、私のことを忘れずにいてくれた皆さんにとても感謝します! したがって、サーバーにも送信し、
  • SMS メッセージを送信した日付。
次にサーバーに送信したいのは次のとおりです。
  • メッセージの種類。
このパラメータは必須ではありませんが、ニュースで何人の顧客を「喜ばせた」かをすぐに上司に伝え、またこの問題に関する美しい統計を作成する必要がある場合に非常に役立ちます。

それなのに、忘れ物をしてしまった! もう少し詳しく考えると、クライアントは一度に 1 つの SMS メッセージまたは多数の SMS メッセージをサーバーに送信できることに注目してください。 つまり、1 つのデータ パケットには 1 から無限のメッセージを含めることができます。

その結果、SMS メッセージを送信するには次のデータが必要であることがわかりました。

  • 携帯電話番号、
  • SMS メッセージのテキスト、
  • SMS メッセージを加入者に送信する時刻、
  • メッセージタイプ。

最初の質問には答えましたが、次は 2 番目の質問に答える必要があります。 そして、おそらく私は少しいじることを自分自身に許可します。 したがって、サーバーからはブール データのみを送信します。その意味は次のとおりです。

  • TRUE – パケットはサーバーに正常に到達し、認証を通過し、SMS プロバイダーに送信するためにキューに入れられました。
  • FALSE – その他すべての場合

これで問題文の説明は終わりです。 そして最後に、楽しい部分に取り掛かりましょう。この SOAP がどのような奇妙な獣であるかを理解しましょう。

2 石鹸とは何ですか?

一般に、当初は SOAP とは何かについて何も書くつもりはなく、必要な仕様を備えた w3.org Web サイトへのリンクと Wikipedia へのリンクに限定したいと考えていました。 しかし、最後にこのプロトコルについて短いメモを書くことにしました。

そして、このデータ交換プロトコルが、いわゆる RPC (リモート プロシージャ コール) パラダイムに基づくプロトコルのサブセットに属し、その対極にあるのが REST (Representational State Transfer) であるという事実から話を始めます。 これについては、Wikipedia で詳しく読むことができます。記事へのリンクはトピックの最後にあります。 これらの記事から、次のことを理解する必要があります。「RPC アプローチでは、少数の ネットワークリソース多数のメソッドと複雑なプロトコルを使用します。 REST アプローチでは、メソッドの数とプロトコルの複雑さが厳しく制限されているため、個々のリソースの数が大きくなる可能性があります。」 つまり、私たちに関して言えば、これは、サイト上の RPC アプローチの場合、サービスへの入力 (リンク) が常に 1 つあり、データとともに転送される受信データを処理するためにどのプロシージャを呼び出す必要があることを意味します。サイトには多くの入力 (リンク) があり、それぞれが特定のデータのみを受け入れて処理します。 これらのアプローチの違いをさらに簡単に説明する方法を知っている読者がいる場合は、必ずコメントに書き込んでください。

次に SOAP について知っておく必要があるのは、このプロトコルはトランスポートとして同じ XML を使用するということです。これは一方では非常に優れています。 すぐに私たちの武器庫は、 与えられた言語マークアップ、つまり XML スキーマ - XML ドキュメントの構造を記述するための言語 (Wikipedia に感謝!)。これにより、サーバーがクライアントから受信したデータの自動検証が可能になります。

これで、SOAP がリモート プロシージャ コールの実装に使用されるプロトコルであり、トランスポートとして XML を使用することがわかりました。 Wikipedia の記事を読むと、HTTP との組み合わせだけでなく、あらゆるアプリケーション レベルのプロトコルでも使用できることがわかります (残念ながら、このトピックでは SOAP over HTTP のみを考慮します)。 そして、私がこれらすべての中で最も好きなものは何か知っていますか? 推測がない場合は、ヒントを与えます - SOAP!... まだ推測がありませんか?... Wikipedia の記事を本当に読んでいますか?... 一般的に、私はこれ以上あなたを苦しめるつもりはありません。 したがって、私はすぐに答えに行きます。「SOAP (英語の Simple Object Access Protocol から - シンプル) プロトコルオブジェクトへのアクセス。 仕様1.2まで)」。 この行の最も注目すべき点は斜体です。 これらすべてからどのような結論を導き出したのかはわかりませんが、次のことがわかります。このプロトコルは決して「単純」とは言えないため(そして明らかにw3さえもこれに同意している)、バージョン1.2からどういうわけか復号化されなくなりました。 ! そして、それは SOAP (単に SOAP) として知られるようになりました。

さて、すみません、少し脱線してしまいました。 先ほども書きましたが、トランスポートには XML が使用されており、クライアントとサーバーの間でやり取りされるパケットは SOAP エンベロープと呼ばれます。 封筒の一般的な構造を考えると、非常に見覚えのあるものに思えるでしょう。 HTML ページの構造に似ています。 メインセクションがあります - 封筒、セクションが含まれます ヘッダそして 、 または 故障。 で データは送信され、エンベロープの必須セクションですが、 ヘッダはオプションです。 で ヘッダ認証や、Web サービス手順の入力データに直接関係しないその他のデータが送信される場合があります。 について 故障エラーが発生した場合にサーバーからクライアントにメッセージが送信されることを除いて、特別に伝えるべきことは何もありません。

これで、SOAP プロトコルに関する私のレビュー ストーリーは終了します (クライアントとサーバーが最終的にエンベロープを相互に実行できるようになったら、エンベロープ自体とその構造をさらに詳しく見ていきます)。そして、新しいものが始まります - と呼ばれる SOAP コンパニオンについて WSDL(Web サービス記述言語)。 はい、はい、これはまさに私たちのほとんどが怖がって API を取得して実装しようとすることさえ避けてしまうものです。 このプロトコル。 結果として、私たちは通常、トランスポートとして JSON を使用して車輪を再発明します。 では、WSDLとは何でしょうか? WSDL は、XML 言語 (c) Wikipedia をベースとした、Web サービスを記述し、Web サービスにアクセスするための言語です。 この定義がこのテクノロジーの神聖な意味全体を明確にしない場合は、私自身の言葉で説明してみます。

WSDL は、クライアントがサーバーと正常に通信できるように設計されています。 これを行うには、拡張子「*.wsdl」のファイルに次の情報を記述します。

  • どのような名前空間が使用されましたか?
  • どのようなデータスキーマが使用されましたか?
  • Web サービスはクライアントからどのような種類のメッセージを期待していますか?
  • どのデータがどの Web サービス プロシージャに属するか、
  • Web サービスにはどのようなプロシージャが含まれていますか?
  • クライアントは Web サービス プロシージャをどのように呼び出す必要がありますか。
  • 顧客からの電話はどのアドレスに送信されるべきですか?
ご覧のとおり、 このファイルそしてWebサービス全体があります。 クライアントで WSDL ファイルのアドレスを指定することで、あらゆる Web サービスについてすべてを知ることができます。 その結果、Web サービス自体がどこにあるのかについてまったく知る必要はありません。 知っておく必要があるのは、その WSDL ファイルの場所だけです。 SOAP はロシアのことわざで言われているほど怖くないことがすぐに分かるでしょう。

3 XML スキーマの概要

現在、私たちは SOAP とは何か、SOAP の内部に何が含まれているかについて多くのことを理解し、SOAP を取り巻くテクノロジー スタックの概要を把握しています。 まず第一に、SOAP はクライアントとサーバー間の対話方法であり、そのトランスポートとして XML マークアップ言語が使用されるため、このセクションでは、XML スキーマを使用して自動データ検証がどのように行われるかについて少し理解します。

図の主なタスクは、処理するデータの構造を記述することです。 XML スキーマ内のすべてのデータは次のように分割されます。 単純(スカラー) と 複雑な(構造) タイプ。 単純なタイプには次のタイプが含まれます。

  • ライン、
  • 番号、
  • ブール値、
  • の日付。
内部に拡張機能のない非常にシンプルなもの。 それらの対極は複雑な複合型です。 誰もが思い浮かべる複雑な型の最も単純な例はオブジェクトです。 たとえば、本。 このブックは次のプロパティで構成されます。 著者, 名前, 価格, ISBN番号等 そして、これらのプロパティは、単純なタイプまたは複雑なタイプのいずれかになります。 XML スキーマの役割は、これを記述することです。

SMS メッセージ用の XML スキーマを作成することはやめることをお勧めします。 以下は SMS メッセージの XML 説明です。

71239876543 テストメッセージ 2013-07-20T12:00:00 12
複合型図は次のようになります。


このエントリは次のようになります: 変数「」があります。 メッセージ" タイプ " メッセージ" そして " という複合型があります メッセージ" 一連の要素で構成されます" 電話" タイプ , « 文章" タイプ , « 日付" タイプ 日付時刻, « タイプ" タイプ 10進数。 これらの型は単純で、スキーマの説明ですでに定義されています。 おめでとう! 最初の XML スキーマを作成しました。

要素の意味は「 要素" そして " 複合タイプ「すべてのことが多かれ少なかれ明らかになったため、これ以上それらに焦点を当てるのはやめて、作曲家の要素に直接切り替えましょう。」 順序」 コンポーザー要素を使用すると、「 順序「それに含まれる要素は常に図で指定された順序で配置する必要があり、それらはすべて必須であることをお知らせします。 でも絶望しないでください! XML スキーマにはさらに 2 つのコンポーザー要素があります。 選択" そして " 全て」 作曲 " 選択「そこにリストされている要素の 1 つと作曲者が必ず存在することを発表します。」 全て» – リストされた要素の任意の組み合わせ。

覚えているとおり、このトピックの最初のセクションでは、1 つから無限までの SMS メッセージをパッケージで送信できることに同意しました。 したがって、このようなデータが XML スキーマでどのように宣言されるかを理解することを提案します。 一般的なパッケージ構造は次のようになります。

71239876543 テストメッセージ1 2013-07-20T12:00:00 12 71239876543 テストメッセージN 2013-07-20T12:00:00 12
このような複雑な型の図は次のようになります。


最初のブロックには、複合型のおなじみの宣言が含まれています。 メッセージ」 お気づきかと思いますが、「」に含まれる各単純型には メッセージ"、新しい明確な属性が追加されました" 分発生" そして " 最大発生数」 名前から推測できるように、最初の ( 分発生) このシーケンスには、タイプ「」の要素が少なくとも 1 つ含まれている必要があることを示します。 電話», « 文章», « 日付" そして " タイプ"、次の ( 最大発生数) 属性は、シーケンス内にそのような要素が最大 1 つしか存在しないことを宣言します。 その結果、任意のデータのスキーマを記述すると、次のようになります。 最も幅広い選択肢それらを設定することで!

図の 2 番目のブロックは要素を宣言します。 メッセージリスト" タイプ " メッセージリスト」 それは明らかです」 メッセージリスト" は少なくとも 1 つの要素を含む複合型です。" メッセージ"、 しかし 最大数このような要素には制限がありません。

4 WSDL を作成する

WSDL が当社の Web サービスであることを覚えていますか? 覚えておいてください! これを作成すると、小さな Web サービスがその上で実行されます。 したがって、いじらないことをお勧めします。

一般に、すべてが正しく機能するためには、正しい MIME タイプの WSDL ファイルをクライアントに転送する必要があります。 これを行うには、それに応じて Web サーバーを設定する必要があります。つまり、「*.wsdl」拡張子を持つファイルの MIME タイプを次の行に設定します。

アプリケーション/wsdl+xml
しかし実際には、通常は PHP 経由で HTTP ヘッダーを送信しました。 テキスト/xml»:

Header("Content-Type: text/xml; charset=utf-8");
そしてすべてがうまくいきました!

私たちの単純な Web サービスにはかなり印象的な説明が含まれることをすぐに警告したいと思います。心配しないでください。なぜなら... テキストのほとんどは義務的なもので、一度書いてしまえば、それをある Web サービスから別の Web サービスにいつでもコピーできます。

WSDL は XML であるため、これについて最初の行に直接記述する必要があります。 ファイルのルート要素は常に「」という名前にする必要があります。 定義»:


通常、WSDL は 4 ~ 5 つのメイン ブロックで構成されます。 一番最初のブロックは Web サービスの定義、つまりエントリ ポイントです。


ここには、「」というサービスがあると書かれています。 SMSサービス」 原則として、WSDL ファイル内のすべての名前は任意に変更できます。 彼らはまったく何の役割も果たしません。

この後、Webサービス「 SMSサービス" というエントリ ポイント ("ポート") があります。 SMSサービスポート」 クライアントからサーバーへのすべてのリクエストはこのエントリ ポイントに送信されます。 そして要素に「 住所» リクエストを受け入れるハンドラー ファイルへのリンク。

Web サービスを定義し、そのエントリ ポイントを指定したら、サポートされているプロシージャをそれにバインドする必要があります。


これを行うために、どの操作がどのような形式で呼び出されるかをリストします。 それらの。 ポート用 " SMSサービスポート" バインディングは次の名前で定義されます " Smsサービスバインディング"、呼び出しタイプが " RPC」と送信プロトコルとして HTTP が使用されます。 したがって、ここでは HTTP 経由で RPC 呼び出しを行うことを示しました。 この後、どのような手順かを説明します( 手術) は Web サービスでサポートされています。 私たちがサポートする手順は 1 つだけです。 SMSを送信」 この手順により、素晴らしいメッセージがサーバーに送信されます。 手順を宣言した後、データがどのような形式で送信されるかを示す必要があります。 この場合、標準の SOAP エンベロープが使用されることが示されています。

その後、プロシージャをメッセージにバインドする必要があります。


これを行うには、バインディングのタイプを「」に指定します。 SmsServicePortType" そして要素内で" ポートタイプ"同じタイプの名前を使用して、プロシージャとメッセージのバインドを示します。 それで、 受信メッセージ(クライアントからサーバーへ) と呼ばれます。 sendSmsRequest" および送信 (サーバーからクライアント) " sendSmsResponse」 WSDL 内のすべての名前と同様、受信メッセージと送信メッセージの名前は任意です。

次に、メッセージ自体を説明する必要があります。 受信と送信:


これを行うには、要素を追加します。 メッセージ「名前付き」 sendSmsRequest" そして " sendSmsResponse" それぞれ。 これらの中で、入力はデータ型に対応する構造を持つエンベロープである必要があることを示しています。 リクエスト」 その後、データ型「」を含むエンベロープがサーバーから返されます。 応答».

次に、これらのタイプの説明を WSDL ファイルに追加する必要があります。 また、WSDL は受信データと送信データをどのように記述すると思いますか? あなたはとっくの昔にすでにすべてを理解しており、XML スキーマを使用することを自分に言い聞かせていたと思います。 そしてあなたは絶対に正しいでしょう!


おめでとうございます! 最初の WSDL が作成されました。 そして私たちは目標の達成にまた一歩近づいています。
次に、独自の分散アプリケーションを開発するために PHP が何を提供してくれるのかを見ていきます。

5 最初の SOAP サーバー

前に、PHP で SOAP サーバーを作成するには、組み込みの SoapServer クラスを使用すると書きました。 すべてのために さらなるアクション私と同じように起こったので、PHPを少し調整する必要があります。 さらに正確に言うと、「php-soap」拡張機能がインストールされていることを確認する必要があります。 PHP の公式 Web サイトで Web サーバーにインストールする方法を読むことをお勧めします (参考文献のリストを参照)。

すべてのインストールと構成が完了したら、ホスティングのルート フォルダーにファイルを作成する必要があります。 SMSサービス.php» 次の内容:

setClass("SoapSmsGateWay"); //サーバーを起動 $server->handle();
「ini_set」関数の境界より上にあるものについては説明する必要がないと思います。 なぜなら そこで、どの HTTP ヘッダーをサーバーからクライアントに送信するかが決定され、環境が構成されます。 「ini_set」の行では、WSDL ファイルのキャッシュを無効にして、その変更がクライアントにすぐに反映されるようにします。

さあ、サーバーに来ます! ご覧のとおり、SOAP サーバー全体にはわずか 3 行しかかかりません。 最初の行では、SoapServer オブジェクトの新しいインスタンスを作成し、Web サービスの WSDL 記述のアドレスをそのコンストラクターに渡します。 これで、ホスティングのルートに、わかりやすい名前のファイルとして配置されることがわかりました。 smsservice.wsdl.php」 2 行目では、クライアントから受信したエンベロープを処理し、応答でエンベロープを返すためにどのクラスを取得する必要があるかを SOAP サーバーに伝えます。 ご想像のとおり、このクラスで唯一のメソッドが説明されます。 SMSを送信。 3 行目でサーバーを起動します。 以上で、サーバーの準備が整いました。 私たち全員を祝福します。

次に、WSDL ファイルを作成する必要があります。 これを行うには、前のセクションから内容を単純にコピーするか、自由に少し「テンプレート化」することができます。

"; ?> /" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:soap12="http://schemas.xmlsoap.org/wsdl/soap12/" xmlns:http="http:// schemas.xmlsoap.org/wsdl/http/" name="SmsWsdl" xmlns="http://schemas.xmlsoap.org/wsdl/"> /"> /smsservice.php" />
この段階では、結果として得られるサーバーに完全に満足しているはずです。 受信する封筒を記録し、受信データを冷静に分析できます。 サーバー上で何かを受信するには、クライアントが必要です。 それでは早速始めましょう!

6 SOAP クライアントが途中です

まず最初に、クライアントを記述するファイルを作成する必要があります。 いつものように、これをホストのルートに作成し、「」という名前にします。 client.php" そして、その中に次のように書きます。

メッセージリスト = 新しいメッセージリスト(); $req->messageList->message = new Message(); $req->messageList->message->phone = "79871234567"; $req->messageList->message->text = "テストメッセージ 1"; $req->messageList->message->date = "2013-07-21T15:00:00.26"; $req->messageList->message->type = 15; $client = new SoapClient("http://($_SERVER["HTTP_HOST"])/smsservice.wsdl.php", array("soap_version" => SOAP_1_2)); var_dump($client->sendSms($req));
オブジェクトについて説明しましょう。 WSDL を作成したとき、サーバーに受信するエンベロープの 3 つのエンティティが記述されました。 リクエスト, メッセージリストそして メッセージ。 それに応じたクラス リクエスト, メッセージリストそして メッセージこれらは、PHP スクリプト内のこれらのエンティティを反映しています。

オブジェクトを定義したら、オブジェクトを作成する必要があります( $req)、サーバーに送信します。 この後には、私たちにとって最も大切な 2 つのセリフが続きます。 私たちのSOAPクライアントです! 信じられないかもしれませんが、サーバーがクライアントからメッセージの受信を開始し、サーバーがメッセージを正常に受信して処理するにはこれで十分です。 最初の部分では、SoapClient クラスのインスタンスを作成し、WSDL ファイルの場所のアドレスをそのコンストラクターに渡します。また、パラメーターでは、SOAP プロトコル バージョン 1.2 を使用して動作することを明示的に示します。 次の行でメソッドを呼び出します SMSを送信物体 $クライアントすぐに結果をブラウザに表示します。
実行して、最終的に何が得られるか見てみましょう。

次のオブジェクトがサーバーから返されました。

オブジェクト(stdClass) public "ステータス" => ブール値 true
そして、これは素晴らしいことです。なぜなら... これで、サーバーが動作しており、動作しているだけでなく、クライアントに値を返すこともできることがわかりました。

次に、サーバー側に慎重に保存されているログを見てみましょう。 最初の部分では、サーバーに到着した生データが表示されます。

79871234567 テストメッセージ1 2013-07-21T15:00:00.26 15
これが封筒です。 これで、それがどのようなものであるかがわかりました。 ただし、常にそれを確認することに興味があるとは考えにくいため、ログ ファイルからオブジェクトを逆シリアル化して、すべてが正常かどうかを確認してみましょう。

Object(stdClass) public "messageList" => object(stdClass) public "message" => object(stdClass) public "phone" => string "79871234567" (length=11) public "text" => string "テストメッセージ 1 " (長さ = 37) パブリック "日付" => 文字列 "2013-07-21T15:00:00.26" (長さ = 22) パブリック "タイプ" => 文字列 "15" (長さ = 2)
ご覧のとおり、オブジェクトは正しく逆シリアル化されました。これを皆さんに祝福したいと思います。 次はもっと面白いことが私たちを待っています! つまり、クライアントを 1 つの SMS メッセージだけでなく、パック全体 (より正確には 3 つ) をサーバーに送信します。

7 複雑なオブジェクトの送信

大量のメッセージを 1 つのパケットでサーバーに転送する方法を考えてみましょう。 おそらく一番多いのは 簡単な方法で messageList 要素内に配列構成が存在します。 これをやろう:

// サーバーに送信するオブジェクトを作成 $req = new Request(); $req->messageList = 新しい MessageList(); $msg1 = 新しいメッセージ(); $msg1->電話 = "79871234567"; $msg1->text = "テストメッセージ 1"; $msg1->date = "2013-07-21T15:00:00.26"; $msg1->タイプ = 15; $msg2 = 新しいメッセージ(); $msg2->電話 = "79871234567"; $msg2->text = "テストメッセージ 2"; $msg2->date = "2014-08-22T16:01:10"; $msg2->タイプ = 16; $msg3 = 新しいメッセージ(); $msg3->電話 = "79871234567"; $msg3->text = "テストメッセージ 3"; $msg3->date = "2014-08-22T16:01:10"; $msg3->タイプ = 17; $req->messageList->message = $msg1; $req->messageList->message = $msg2; $req->messageList->message = $msg3;
ログには、次のパケットがクライアントから受信されたことが示されています。

79871234567 テストメッセージ1 2013-07-21T15:00:00.26 15 79871234567 テストメッセージ2 2014-08-22T16:01:10 16 79871234567 テストメッセージ3 2014-08-22T16:01:10 17
なんてナンセンスだと思いますか? そして、あなたはある意味では正しいでしょう、なぜなら... オブジェクトがクライアントから出たことを知るとすぐに、それはまったく同じ形でエンベロープの形でサーバーに届きました。 確かに、SMS メッセージは必要な方法で XML にシリアル化されておらず、要素でラップする必要がありました。 メッセージ、 ありませんで 構造体。 では、そのようなオブジェクトがどのような形式でメソッドに渡されるかを見てみましょう。 SMSを送信:

オブジェクト(stdClass) public "messageList" => object(stdClass) public "message" => object(stdClass) public "Struct" => 配列 (size=3) 0 => object(stdClass) public "phone" => 文字列"79871234567" (長さ=11) パブリック "テキスト" => 文字列 "テスト メッセージ 1" (長さ = 37) パブリック "日付" => 文字列 "2013-07-21T15:00:00.26" (長さ = 22) パブリック " type" => 文字列 "15" (length=2) 1 => object(stdClass) public "phone" => 文字列 "79871234567" (length=11) public "text" => string "テスト メッセージ 2" (length= 37) public "date" => string "2014-08-22T16:01:10" (length=19) public "type" => string "16" (length=2) 2 => object(stdClass) public "phone " => 文字列 "79871234567" (長さ=11) パブリック "テキスト" => 文字列 "テストメッセージ 3" (長さ=37) パブリック "日付" => 文字列 "2014-08-22T16:01:10" (長さ= 19) パブリック "タイプ" => 文字列 "17" (長さ = 2)
この知識は私たちに何をもたらすのでしょうか? ただ、選択したパスが正しくなく、「サーバー上で正しいデータ構造を取得するにはどうすればよいですか?」という質問に対する答えが得られていません。 しかし、絶望しないで、配列を型に変換してみることをお勧めします。 オブジェクト:

$req->messageList->message = (オブジェクト)$req->messageList->message;
この場合、別の封筒を受け取ります。

79871234567 テストメッセージ1 2013-07-21T15:00:00.26 15 79871234567 テストメッセージ2 2014-08-22T16:01:10 16 79871234567 テストメッセージ3 2014-08-22T16:01:10 17
メソッドに入ってきた SMSを送信オブジェクトは次の構造を持っています。

オブジェクト(stdClass) public "messageList" => object(stdClass) public "message" => object(stdClass) public "BOGUS" => 配列 (size=3) 0 => object(stdClass) public "phone" => 文字列"79871234567" (長さ=11) パブリック "テキスト" => 文字列 "テスト メッセージ 1" (長さ = 37) パブリック "日付" => 文字列 "2013-07-21T15:00:00.26" (長さ = 22) パブリック " type" => 文字列 "15" (length=2) 1 => object(stdClass) public "phone" => 文字列 "79871234567" (length=11) public "text" => string "テスト メッセージ 2" (length= 37) public "date" => string "2014-08-22T16:01:10" (length=19) public "type" => string "16" (length=2) 2 => object(stdClass) public "phone " => 文字列 "79871234567" (長さ=11) パブリック "テキスト" => 文字列 "テストメッセージ 3" (長さ=37) パブリック "日付" => 文字列 "2014-08-22T16:01:10" (長さ= 19) パブリック "タイプ" => 文字列 "17" (長さ = 2)
私の場合、「項の位置を変えても合計は変わらない」(c)。 何 インチキ、 何 構造体– まだ目標を達成していません! それを達成するには、これらの理解できない名前の代わりに、ネイティブの名前が表示されるようにする必要があります。 メッセージ。 しかし、著者はこれを達成する方法をまだ知りません。 したがって、私たちができる唯一のことは、余分なコンテナを取り除くことです。 言い換えれば、代わりに次のことを確認します。 メッセージなりました インチキ! これを行うには、次のようにオブジェクトを変更します。

// サーバーに送信するオブジェクトを作成 $req = new Request(); $msg1 = 新しいメッセージ(); $msg1->電話 = "79871234567"; $msg1->text = "テストメッセージ 1"; $msg1->date = "2013-07-21T15:00:00.26"; $msg1->タイプ = 15; $msg2 = 新しいメッセージ(); $msg2->電話 = "79871234567"; $msg2->text = "テストメッセージ 2"; $msg2->date = "2014-08-22T16:01:10"; $msg2->タイプ = 16; $msg3 = 新しいメッセージ(); $msg3->電話 = "79871234567"; $msg3->text = "テストメッセージ 3"; $msg3->date = "2014-08-22T16:01:10"; $msg3->タイプ = 17; $req->messageList = $msg1; $req->messageList = $msg2; $req->messageList = $msg3; $req->messageList = (オブジェクト)$req->messageList;
運が良くて、図から正しい名前が出てきたらどうなるでしょうか? これを行うために、届いた封筒を見てみましょう。

79871234567 テストメッセージ1 2013-07-21T15:00:00.26 15 79871234567 テストメッセージ2 2014-08-22T16:01:10 16 79871234567 テストメッセージ3 2014-08-22T16:01:10 17
はい、奇跡は起こりませんでした! インチキ– 勝てないよ! に来た SMSを送信この場合のオブジェクトは次のようになります。

オブジェクト(stdClass) public "messageList" => object(stdClass) public "BOGUS" => 配列 (size=3) 0 => object(stdClass) public "phone" => string "79871234567" (length=11) public " text" => 文字列 "テスト メッセージ 1" (長さ = 37) public "date" => 文字列 "2013-07-21T15:00:00.26" (長さ = 22) public "type" => 文字列 "15" (長さ=2) 1 => object(stdClass) public "phone" => string "79871234567" (length=11) public "text" => string "テストメッセージ 2" (length=37) public "date" => string " 2014-08-22T16:01:10" (length=19) public "type" => string "16" (length=2) 2 => object(stdClass) public "phone" => string "79871234567" (length= 11) public "text" => string "テストメッセージ 3" (length=37) public "date" => string "2014-08-22T16:01:10" (length=19) public "type" => string " 17インチ (長さ=2)
彼らが言うように、「ほぼ」! この (少し悲しい) メモについて、ゆっくりと話をまとめて、自分たちでいくつかの結論を導き出すことを提案します。

8 結論

ついにここに到着しました! 今何ができるかを考えてみましょう。
  • 必要なものを書くことができます WebサービスWSDL-ファイル;
  • SOAP 経由でサーバーと通信できる独自のクライアントを簡単に作成できます。
  • 自分で書くことができます 独自のサーバー SOAP を介して外部と通信する。
  • 同じタイプのオブジェクトの配列をクライアントからサーバーに送信できます (いくつかの制限があります)。
また、ちょっとした調査中にいくつかの発見がありました。
  • ネイティブ SoapClient クラスは、XML 内の同じタイプのデータ構造を正しくシリアル化しません。
  • 配列を XML にシリアル化すると、という追加の要素が作成されます。 構造体;
  • オブジェクトを XML にシリアル化すると、と呼ばれる追加の要素が作成されます。 インチキ;
  • インチキ~よりも悪気が少ない 構造体エンベロープがよりコンパクトになるという事実によるものです (エンベロープの XML ヘッダーに余分な名前空間が追加されません)。
  • 残念ながら、SoapServer クラスは、XML スキーマを使用してエンベロープ データを自動的に検証しません (おそらく他のサーバーも検証しません)。
  • チュートリアル

こんにちは、みんな!
ひょんなことから最近Webサービスの開発を始めました。 ただし、今日のトピックは私に関するものではなく、SOAP 1.2 プロトコルに基づいて独自の XML Web サービスを作成する方法についてです。

このトピックを読んだ後、次のことができるようになることを願っています。

  • Web アプリケーションの独自のサーバー実装を作成します。
  • Web アプリケーションの独自のクライアント実装を作成します。
  • 独自の Web サービス記述 (WSDL) を作成します。
  • 同じタイプのデータのクライアント配列をサーバーに送信します。
ご想像のとおり、すべての魔法は PHP と組み込みの SoapClient クラスと SoapServer クラスを使用して実行されます。 私たちのウサギはSMSメッセージを送信するサービスになります。

1 問題ステートメント

1.1 境界

最初に、このトピックの最後に達成される結果に対処することを提案します。 上で発表したように、SMS メッセージを送信するサービスを作成します。より正確には、SOAP プロトコルを介してさまざまなソースからメッセージを受信します。 その後、それらがどのような形式でサーバーに届くかを検討します。 残念ながら、プロバイダーにさらに送信するためにメッセージをキューに入れるプロセスについては、多くの理由からこの投稿の範囲を超えています。

1.2 どのデータを変更しますか?

よかった、境界線が決まりました! 次に実行する必要があるステップは、サーバーとクライアントの間でどのようなデータを交換するかを決定することです。 このトピックについては、髪をあまり長く分割せず、主な質問にすぐに自分で答えることをお勧めします。
  • SMS メッセージを加入者に送信するには、サーバーに最低限どのデータを送信する必要がありますか?
  • クライアントのニーズを満たすためには、サーバーから最低限どのようなデータを送信する必要がありますか?
このためには、次のものを送信する必要があることがわかります。
  • 携帯電話番号と
  • SMS メッセージのテキスト。
基本的に、送信にはこれら 2 つの特徴だけで十分ですが、誕生日の挨拶を含む SMS が午前 3 時か 4 時に届く場合をすぐに想像します。 この瞬間、私のことを忘れずにいてくれた皆さんにとても感謝します! したがって、サーバーにも送信し、
  • SMS メッセージを送信した日付。
次にサーバーに送信したいのは次のとおりです。
  • メッセージの種類。
このパラメータは必須ではありませんが、ニュースで何人の顧客を「喜ばせた」かをすぐに上司に伝え、またこの問題に関する美しい統計を作成する必要がある場合に非常に役立ちます。

それなのに、忘れ物をしてしまった! もう少し詳しく考えると、クライアントは一度に 1 つの SMS メッセージまたは多数の SMS メッセージをサーバーに送信できることに注目してください。 つまり、1 つのデータ パケットには 1 から無限のメッセージを含めることができます。

その結果、SMS メッセージを送信するには次のデータが必要であることがわかりました。

  • 携帯電話番号、
  • SMS メッセージのテキスト、
  • SMS メッセージを加入者に送信する時刻、
  • メッセージタイプ。

最初の質問には答えましたが、次は 2 番目の質問に答える必要があります。 そして、おそらく私は少しいじることを自分自身に許可します。 したがって、サーバーからはブール データのみを送信します。その意味は次のとおりです。

  • TRUE – パケットはサーバーに正常に到達し、認証を通過し、SMS プロバイダーに送信するためにキューに入れられました。
  • FALSE – その他すべての場合

これで問題文の説明は終わりです。 そして最後に、楽しい部分に取り掛かりましょう。この SOAP がどのような奇妙な獣であるかを理解しましょう。

2 石鹸とは何ですか?

一般に、当初は SOAP とは何かについて何も書くつもりはなく、必要な仕様を備えた w3.org Web サイトへのリンクと Wikipedia へのリンクに限定したいと考えていました。 しかし、最後にこのプロトコルについて短いメモを書くことにしました。

そして、このデータ交換プロトコルが、いわゆる RPC (リモート プロシージャ コール) パラダイムに基づくプロトコルのサブセットに属し、その対極にあるのが REST (Representational State Transfer) であるという事実から話を始めます。 これについては、Wikipedia で詳しく読むことができます。記事へのリンクはトピックの最後にあります。 これらの記事から、次のことを理解する必要があります。「RPC アプローチでは、少数のネットワーク リソースを多数のメソッドと複雑なプロトコルで使用できます。 REST アプローチでは、メソッドの数とプロトコルの複雑さが厳しく制限されているため、個々のリソースの数が大きくなる可能性があります。」 つまり、私たちに関して言えば、これは、サイト上の RPC アプローチの場合、サービスへの入力 (リンク) が常に 1 つあり、データとともに転送される受信データを処理するためにどのプロシージャを呼び出す必要があることを意味します。サイトには多くの入力 (リンク) があり、それぞれが特定のデータのみを受け入れて処理します。 これらのアプローチの違いをさらに簡単に説明する方法を知っている読者がいる場合は、必ずコメントに書き込んでください。

次に SOAP について知っておく必要があるのは、このプロトコルはトランスポートとして同じ XML を使用するということです。これは一方では非常に優れています。 私たちの武器には、このマークアップ言語、つまり XML ドキュメントの構造を記述する言語 (Wikipedia に感謝!) である XML スキーマに基づく一連のテクノロジーの全能力が即座に組み込まれており、サーバーが受信したデータの自動検証が可能になります。クライアントから。

これで、SOAP がリモート プロシージャ コールの実装に使用されるプロトコルであり、トランスポートとして XML を使用することがわかりました。 Wikipedia の記事を読むと、HTTP との組み合わせだけでなく、あらゆるアプリケーション レベルのプロトコルでも使用できることがわかります (残念ながら、このトピックでは SOAP over HTTP のみを考慮します)。 そして、私がこれらすべての中で最も好きなものは何か知っていますか? 推測がない場合は、ヒントを与えます - SOAP!... まだ推測がありませんか?... Wikipedia の記事を本当に読んでいますか?... 一般的に、私はこれ以上あなたを苦しめるつもりはありません。 したがって、私はすぐに答えに行きます。「SOAP (英語の Simple Object Access Protocol から - シンプル) プロトコルオブジェクトへのアクセス。 仕様1.2まで)」。 この行の最も注目すべき点は斜体です。 これらすべてからどのような結論を導き出したのかはわかりませんが、次のことがわかります。このプロトコルは決して「単純」とは言えないため(そして明らかにw3さえもこれに同意している)、バージョン1.2からどういうわけか復号化されなくなりました。 ! そして、それは SOAP (単に SOAP) として知られるようになりました。

さて、すみません、少し脱線してしまいました。 先ほども書きましたが、トランスポートには XML が使用されており、クライアントとサーバーの間でやり取りされるパケットは SOAP エンベロープと呼ばれます。 封筒の一般的な構造を考えると、非常に見覚えのあるものに思えるでしょう。 HTML ページの構造に似ています。 メインセクションがあります - 封筒、セクションが含まれます ヘッダそして 、 または 故障。 で データは送信され、エンベロープの必須セクションですが、 ヘッダはオプションです。 で ヘッダ認証や、Web サービス手順の入力データに直接関係しないその他のデータが送信される場合があります。 について 故障エラーが発生した場合にサーバーからクライアントにメッセージが送信されることを除いて、特別に伝えるべきことは何もありません。

これで、SOAP プロトコルに関する私のレビュー ストーリーは終了します (クライアントとサーバーが最終的にエンベロープを相互に実行できるようになったら、エンベロープ自体とその構造をさらに詳しく見ていきます)。そして、新しいものが始まります - と呼ばれる SOAP コンパニオンについて WSDL(Web サービス記述言語)。 はい、はい、これはまさに私たちのほとんどがこのプロトコルに API を実装しようとすることすら怖がらせるものです。 結果として、私たちは通常、トランスポートとして JSON を使用して車輪を再発明します。 では、WSDLとは何でしょうか? WSDL は、XML 言語 (c) Wikipedia をベースとした、Web サービスを記述し、Web サービスにアクセスするための言語です。 この定義がこのテクノロジーの神聖な意味全体を明確にしない場合は、私自身の言葉で説明してみます。

WSDL は、クライアントがサーバーと正常に通信できるように設計されています。 これを行うには、拡張子「*.wsdl」のファイルに次の情報を記述します。

  • どのような名前空間が使用されましたか?
  • どのようなデータスキーマが使用されましたか?
  • Web サービスはクライアントからどのような種類のメッセージを期待していますか?
  • どのデータがどの Web サービス プロシージャに属するか、
  • Web サービスにはどのようなプロシージャが含まれていますか?
  • クライアントは Web サービス プロシージャをどのように呼び出す必要がありますか。
  • 顧客からの電話はどのアドレスに送信されるべきですか?
ご覧のとおり、このファイルは Web サービス全体です。 クライアントで WSDL ファイルのアドレスを指定することで、あらゆる Web サービスについてすべてを知ることができます。 その結果、Web サービス自体がどこにあるのかについてまったく知る必要はありません。 知っておく必要があるのは、その WSDL ファイルの場所だけです。 SOAP はロシアのことわざで言われているほど怖くないことがすぐに分かるでしょう。

3 XML スキーマの概要

現在、私たちは SOAP とは何か、SOAP の内部に何が含まれているかについて多くのことを理解し、SOAP を取り巻くテクノロジー スタックの概要を把握しています。 まず第一に、SOAP はクライアントとサーバー間の対話方法であり、そのトランスポートとして XML マークアップ言語が使用されるため、このセクションでは、XML スキーマを使用して自動データ検証がどのように行われるかについて少し理解します。

図の主なタスクは、処理するデータの構造を記述することです。 XML スキーマ内のすべてのデータは次のように分割されます。 単純(スカラー) と 複雑な(構造) タイプ。 単純なタイプには次のタイプが含まれます。

  • ライン、
  • 番号、
  • ブール値、
  • の日付。
内部に拡張機能のない非常にシンプルなもの。 それらの対極は複雑な複合型です。 誰もが思い浮かべる複雑な型の最も単純な例はオブジェクトです。 たとえば、本。 このブックは次のプロパティで構成されます。 著者, 名前, 価格, ISBN番号等 そして、これらのプロパティは、単純なタイプまたは複雑なタイプのいずれかになります。 XML スキーマの役割は、これを記述することです。

SMS メッセージ用の XML スキーマを作成することはやめることをお勧めします。 以下は SMS メッセージの XML 説明です。

71239876543 テストメッセージ 2013-07-20T12:00:00 12
複合型図は次のようになります。


このエントリは次のようになります: 変数「」があります。 メッセージ" タイプ " メッセージ" そして " という複合型があります メッセージ" 一連の要素で構成されます" 電話" タイプ , « 文章" タイプ , « 日付" タイプ 日付時刻, « タイプ" タイプ 10進数。 これらの型は単純で、スキーマの説明ですでに定義されています。 おめでとう! 最初の XML スキーマを作成しました。

要素の意味は「 要素" そして " 複合タイプ「すべてのことが多かれ少なかれ明らかになったため、これ以上それらに焦点を当てるのはやめて、作曲家の要素に直接切り替えましょう。」 順序」 コンポーザー要素を使用すると、「 順序「それに含まれる要素は常に図で指定された順序で配置する必要があり、それらはすべて必須であることをお知らせします。 でも絶望しないでください! XML スキーマにはさらに 2 つのコンポーザー要素があります。 選択" そして " 全て」 作曲 " 選択「そこにリストされている要素の 1 つと作曲者が必ず存在することを発表します。」 全て» – リストされた要素の任意の組み合わせ。

覚えているとおり、このトピックの最初のセクションでは、1 つから無限までの SMS メッセージをパッケージで送信できることに同意しました。 したがって、このようなデータが XML スキーマでどのように宣言されるかを理解することを提案します。 一般的なパッケージ構造は次のようになります。

71239876543 テストメッセージ1 2013-07-20T12:00:00 12 71239876543 テストメッセージN 2013-07-20T12:00:00 12
このような複雑な型の図は次のようになります。


最初のブロックには、複合型のおなじみの宣言が含まれています。 メッセージ」 お気づきかと思いますが、「」に含まれる各単純型には メッセージ"、新しい明確な属性が追加されました" 分発生" そして " 最大発生数」 名前から推測できるように、最初の ( 分発生) このシーケンスには、タイプ「」の要素が少なくとも 1 つ含まれている必要があることを示します。 電話», « 文章», « 日付" そして " タイプ"、次の ( 最大発生数) 属性は、シーケンス内にそのような要素が最大 1 つしか存在しないことを宣言します。 その結果、任意のデータに対して独自のスキーマを作成する場合、その構成方法について最も幅広い選択肢が与えられます。

図の 2 番目のブロックは要素を宣言します。 メッセージリスト" タイプ " メッセージリスト」 それは明らかです」 メッセージリスト" は少なくとも 1 つの要素を含む複合型です。" メッセージ」とありますが、そのような要素の最大数には制限がありません。

4 WSDL を作成する

WSDL が当社の Web サービスであることを覚えていますか? 覚えておいてください! これを作成すると、小さな Web サービスがその上で実行されます。 したがって、いじらないことをお勧めします。

一般に、すべてが正しく機能するためには、正しい MIME タイプの WSDL ファイルをクライアントに転送する必要があります。 これを行うには、それに応じて Web サーバーを設定する必要があります。つまり、「*.wsdl」拡張子を持つファイルの MIME タイプを次の行に設定します。

アプリケーション/wsdl+xml
しかし実際には、通常は PHP 経由で HTTP ヘッダーを送信しました。 テキスト/xml»:

Header("Content-Type: text/xml; charset=utf-8");
そしてすべてがうまくいきました!

私たちの単純な Web サービスにはかなり印象的な説明が含まれることをすぐに警告したいと思います。心配しないでください。なぜなら... テキストのほとんどは義務的なもので、一度書いてしまえば、それをある Web サービスから別の Web サービスにいつでもコピーできます。

WSDL は XML であるため、これについて最初の行に直接記述する必要があります。 ファイルのルート要素は常に「」という名前にする必要があります。 定義»:


通常、WSDL は 4 ~ 5 つのメイン ブロックで構成されます。 一番最初のブロックは Web サービスの定義、つまりエントリ ポイントです。


ここには、「」というサービスがあると書かれています。 SMSサービス」 原則として、WSDL ファイル内のすべての名前は任意に変更できます。 彼らはまったく何の役割も果たしません。

この後、Webサービス「 SMSサービス" というエントリ ポイント ("ポート") があります。 SMSサービスポート」 クライアントからサーバーへのすべてのリクエストはこのエントリ ポイントに送信されます。 そして要素に「 住所» リクエストを受け入れるハンドラー ファイルへのリンク。

Web サービスを定義し、そのエントリ ポイントを指定したら、サポートされているプロシージャをそれにバインドする必要があります。


これを行うために、どの操作がどのような形式で呼び出されるかをリストします。 それらの。 ポート用 " SMSサービスポート" バインディングは次の名前で定義されます " Smsサービスバインディング"、呼び出しタイプが " RPC」と送信プロトコルとして HTTP が使用されます。 したがって、ここでは HTTP 経由で RPC 呼び出しを行うことを示しました。 この後、どのような手順かを説明します( 手術) は Web サービスでサポートされています。 私たちがサポートする手順は 1 つだけです。 SMSを送信」 この手順により、素晴らしいメッセージがサーバーに送信されます。 手順を宣言した後、データがどのような形式で送信されるかを示す必要があります。 この場合、標準の SOAP エンベロープが使用されることが示されています。

その後、プロシージャをメッセージにバインドする必要があります。


これを行うには、バインディングのタイプを「」に指定します。 SmsServicePortType" そして要素内で" ポートタイプ"同じタイプの名前を使用して、プロシージャとメッセージのバインドを示します。 したがって、受信メッセージ (クライアントからサーバーへ) は「」と呼ばれます。 sendSmsRequest" および送信 (サーバーからクライアント) " sendSmsResponse」 WSDL 内のすべての名前と同様、受信メッセージと送信メッセージの名前は任意です。

次に、メッセージ自体を説明する必要があります。 受信と送信:


これを行うには、要素を追加します。 メッセージ「名前付き」 sendSmsRequest" そして " sendSmsResponse" それぞれ。 これらの中で、入力はデータ型に対応する構造を持つエンベロープである必要があることを示しています。 リクエスト」 その後、データ型「」を含むエンベロープがサーバーから返されます。 応答».

次に、これらのタイプの説明を WSDL ファイルに追加する必要があります。 また、WSDL は受信データと送信データをどのように記述すると思いますか? あなたはとっくの昔にすでにすべてを理解しており、XML スキーマを使用することを自分に言い聞かせていたと思います。 そしてあなたは絶対に正しいでしょう!


おめでとうございます! 最初の WSDL が作成されました。 そして私たちは目標の達成にまた一歩近づいています。
次に、独自の分散アプリケーションを開発するために PHP が何を提供してくれるのかを見ていきます。

5 最初の SOAP サーバー

先ほど、PHP で SOAP サーバーを作成するには、組み込みの SoapServer クラスを使用すると書きました。 これ以降のすべてのアクションを私と同じように実行するには、PHP を少し調整する必要があります。 さらに正確に言うと、「php-soap」拡張機能がインストールされていることを確認する必要があります。 PHP の公式 Web サイトで Web サーバーにインストールする方法を読むことをお勧めします (参考文献のリストを参照)。

すべてのインストールと構成が完了したら、ホスティングのルート フォルダーにファイルを作成する必要があります。 SMSサービス.php» 次の内容:

setClass("SoapSmsGateWay"); //サーバーを起動 $server->handle();
「ini_set」関数の境界より上にあるものについては説明する必要がないと思います。 なぜなら そこで、どの HTTP ヘッダーをサーバーからクライアントに送信するかが決定され、環境が構成されます。 「ini_set」の行では、WSDL ファイルのキャッシュを無効にして、その変更がクライアントにすぐに反映されるようにします。

さあ、サーバーに来ます! ご覧のとおり、SOAP サーバー全体にはわずか 3 行しかかかりません。 最初の行では、SoapServer オブジェクトの新しいインスタンスを作成し、Web サービスの WSDL 記述のアドレスをそのコンストラクターに渡します。 これで、ホスティングのルートに、わかりやすい名前のファイルとして配置されることがわかりました。 smsservice.wsdl.php」 2 行目では、クライアントから受信したエンベロープを処理し、応答でエンベロープを返すためにどのクラスを取得する必要があるかを SOAP サーバーに伝えます。 ご想像のとおり、このクラスで唯一のメソッドが説明されます。 SMSを送信。 3 行目でサーバーを起動します。 以上で、サーバーの準備が整いました。 私たち全員を祝福します。

次に、WSDL ファイルを作成する必要があります。 これを行うには、前のセクションから内容を単純にコピーするか、自由に少し「テンプレート化」することができます。

"; ?> /" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:soap12="http://schemas.xmlsoap.org/wsdl/soap12/" xmlns:http="http:// schemas.xmlsoap.org/wsdl/http/" name="SmsWsdl" xmlns="http://schemas.xmlsoap.org/wsdl/"> /"> /smsservice.php" />
この段階では、結果として得られるサーバーに完全に満足しているはずです。 受信する封筒を記録し、受信データを冷静に分析できます。 サーバー上で何かを受信するには、クライアントが必要です。 それでは早速始めましょう!

6 SOAP クライアントが途中です

まず最初に、クライアントを記述するファイルを作成する必要があります。 いつものように、これをホストのルートに作成し、「」という名前にします。 client.php" そして、その中に次のように書きます。

メッセージリスト = 新しいメッセージリスト(); $req->messageList->message = new Message(); $req->messageList->message->phone = "79871234567"; $req->messageList->message->text = "テストメッセージ 1"; $req->messageList->message->date = "2013-07-21T15:00:00.26"; $req->messageList->message->type = 15; $client = new SoapClient("http://($_SERVER["HTTP_HOST"])/smsservice.wsdl.php", array("soap_version" => SOAP_1_2)); var_dump($client->sendSms($req));
オブジェクトについて説明しましょう。 WSDL を作成したとき、サーバーに受信するエンベロープの 3 つのエンティティが記述されました。 リクエスト, メッセージリストそして メッセージ。 それに応じたクラス リクエスト, メッセージリストそして メッセージこれらは、PHP スクリプト内のこれらのエンティティを反映しています。

オブジェクトを定義したら、オブジェクトを作成する必要があります( $req)、サーバーに送信します。 この後には、私たちにとって最も大切な 2 つのセリフが続きます。 私たちのSOAPクライアントです! 信じられないかもしれませんが、サーバーがクライアントからメッセージの受信を開始し、サーバーがメッセージを正常に受信して処理するにはこれで十分です。 最初の部分では、SoapClient クラスのインスタンスを作成し、WSDL ファイルの場所のアドレスをそのコンストラクターに渡します。また、パラメーターでは、SOAP プロトコル バージョン 1.2 を使用して動作することを明示的に示します。 次の行でメソッドを呼び出します SMSを送信物体 $クライアントすぐに結果をブラウザに表示します。
実行して、最終的に何が得られるか見てみましょう。

次のオブジェクトがサーバーから返されました。

オブジェクト(stdClass) public "ステータス" => ブール値 true
そして、これは素晴らしいことです。なぜなら... これで、サーバーが動作しており、動作しているだけでなく、クライアントに値を返すこともできることがわかりました。

次に、サーバー側に慎重に保存されているログを見てみましょう。 最初の部分では、サーバーに到着した生データが表示されます。

79871234567 テストメッセージ1 2013-07-21T15:00:00.26 15
これが封筒です。 これで、それがどのようなものであるかがわかりました。 ただし、常にそれを確認することに興味があるとは考えにくいため、ログ ファイルからオブジェクトを逆シリアル化して、すべてが正常かどうかを確認してみましょう。

Object(stdClass) public "messageList" => object(stdClass) public "message" => object(stdClass) public "phone" => string "79871234567" (length=11) public "text" => string "テストメッセージ 1 " (長さ = 37) パブリック "日付" => 文字列 "2013-07-21T15:00:00.26" (長さ = 22) パブリック "タイプ" => 文字列 "15" (長さ = 2)
ご覧のとおり、オブジェクトは正しく逆シリアル化されました。これを皆さんに祝福したいと思います。 次はもっと面白いことが私たちを待っています! つまり、クライアントを 1 つの SMS メッセージだけでなく、パック全体 (より正確には 3 つ) をサーバーに送信します。

7 複雑なオブジェクトの送信

大量のメッセージを 1 つのパケットでサーバーに転送する方法を考えてみましょう。 おそらく最も簡単な方法は、messageList 要素内で配列を整理することです。 これをやろう:

// サーバーに送信するオブジェクトを作成 $req = new Request(); $req->messageList = 新しい MessageList(); $msg1 = 新しいメッセージ(); $msg1->電話 = "79871234567"; $msg1->text = "テストメッセージ 1"; $msg1->date = "2013-07-21T15:00:00.26"; $msg1->タイプ = 15; $msg2 = 新しいメッセージ(); $msg2->電話 = "79871234567"; $msg2->text = "テストメッセージ 2"; $msg2->date = "2014-08-22T16:01:10"; $msg2->タイプ = 16; $msg3 = 新しいメッセージ(); $msg3->電話 = "79871234567"; $msg3->text = "テストメッセージ 3"; $msg3->date = "2014-08-22T16:01:10"; $msg3->タイプ = 17; $req->messageList->message = $msg1; $req->messageList->message = $msg2; $req->messageList->message = $msg3;
ログには、次のパケットがクライアントから受信されたことが示されています。

79871234567 テストメッセージ1 2013-07-21T15:00:00.26 15 79871234567 テストメッセージ2 2014-08-22T16:01:10 16 79871234567 テストメッセージ3 2014-08-22T16:01:10 17
なんてナンセンスだと思いますか? そして、あなたはある意味では正しいでしょう、なぜなら... オブジェクトがクライアントから出たことを知るとすぐに、それはまったく同じ形でエンベロープの形でサーバーに届きました。 確かに、SMS メッセージは必要な方法で XML にシリアル化されておらず、要素でラップする必要がありました。 メッセージ、 ありませんで 構造体。 では、そのようなオブジェクトがどのような形式でメソッドに渡されるかを見てみましょう。 SMSを送信:

オブジェクト(stdClass) public "messageList" => object(stdClass) public "message" => object(stdClass) public "Struct" => 配列 (size=3) 0 => object(stdClass) public "phone" => 文字列"79871234567" (長さ=11) パブリック "テキスト" => 文字列 "テスト メッセージ 1" (長さ = 37) パブリック "日付" => 文字列 "2013-07-21T15:00:00.26" (長さ = 22) パブリック " type" => 文字列 "15" (length=2) 1 => object(stdClass) public "phone" => 文字列 "79871234567" (length=11) public "text" => string "テスト メッセージ 2" (length= 37) public "date" => string "2014-08-22T16:01:10" (length=19) public "type" => string "16" (length=2) 2 => object(stdClass) public "phone " => 文字列 "79871234567" (長さ=11) パブリック "テキスト" => 文字列 "テストメッセージ 3" (長さ=37) パブリック "日付" => 文字列 "2014-08-22T16:01:10" (長さ= 19) パブリック "タイプ" => 文字列 "17" (長さ = 2)
この知識は私たちに何をもたらすのでしょうか? ただ、選択したパスが正しくなく、「サーバー上で正しいデータ構造を取得するにはどうすればよいですか?」という質問に対する答えが得られていません。 しかし、絶望しないで、配列を型に変換してみることをお勧めします。 オブジェクト:

$req->messageList->message = (オブジェクト)$req->messageList->message;
この場合、別の封筒を受け取ります。

79871234567 テストメッセージ1 2013-07-21T15:00:00.26 15 79871234567 テストメッセージ2 2014-08-22T16:01:10 16 79871234567 テストメッセージ3 2014-08-22T16:01:10 17
メソッドに入ってきた SMSを送信オブジェクトは次の構造を持っています。

オブジェクト(stdClass) public "messageList" => object(stdClass) public "message" => object(stdClass) public "BOGUS" => 配列 (size=3) 0 => object(stdClass) public "phone" => 文字列"79871234567" (長さ=11) パブリック "テキスト" => 文字列 "テスト メッセージ 1" (長さ = 37) パブリック "日付" => 文字列 "2013-07-21T15:00:00.26" (長さ = 22) パブリック " type" => 文字列 "15" (length=2) 1 => object(stdClass) public "phone" => 文字列 "79871234567" (length=11) public "text" => string "テスト メッセージ 2" (length= 37) public "date" => string "2014-08-22T16:01:10" (length=19) public "type" => string "16" (length=2) 2 => object(stdClass) public "phone " => 文字列 "79871234567" (長さ=11) パブリック "テキスト" => 文字列 "テストメッセージ 3" (長さ=37) パブリック "日付" => 文字列 "2014-08-22T16:01:10" (長さ= 19) パブリック "タイプ" => 文字列 "17" (長さ = 2)
私の場合、「項の位置を変えても合計は変わらない」(c)。 何 インチキ、 何 構造体– まだ目標を達成していません! それを達成するには、これらの理解できない名前の代わりに、ネイティブの名前が表示されるようにする必要があります。 メッセージ。 しかし、著者はこれを達成する方法をまだ知りません。 したがって、私たちができる唯一のことは、余分なコンテナを取り除くことです。 言い換えれば、代わりに次のことを確認します。 メッセージなりました インチキ! これを行うには、次のようにオブジェクトを変更します。

// サーバーに送信するオブジェクトを作成 $req = new Request(); $msg1 = 新しいメッセージ(); $msg1->電話 = "79871234567"; $msg1->text = "テストメッセージ 1"; $msg1->date = "2013-07-21T15:00:00.26"; $msg1->タイプ = 15; $msg2 = 新しいメッセージ(); $msg2->電話 = "79871234567"; $msg2->text = "テストメッセージ 2"; $msg2->date = "2014-08-22T16:01:10"; $msg2->タイプ = 16; $msg3 = 新しいメッセージ(); $msg3->電話 = "79871234567"; $msg3->text = "テストメッセージ 3"; $msg3->date = "2014-08-22T16:01:10"; $msg3->タイプ = 17; $req->messageList = $msg1; $req->messageList = $msg2; $req->messageList = $msg3; $req->messageList = (オブジェクト)$req->messageList;
運が良くて、図から正しい名前が出てきたらどうなるでしょうか? これを行うために、届いた封筒を見てみましょう。

79871234567 テストメッセージ1 2013-07-21T15:00:00.26 15 79871234567 テストメッセージ2 2014-08-22T16:01:10 16 79871234567 テストメッセージ3 2014-08-22T16:01:10 17
はい、奇跡は起こりませんでした! インチキ– 勝てないよ! に来た SMSを送信この場合のオブジェクトは次のようになります。

オブジェクト(stdClass) public "messageList" => object(stdClass) public "BOGUS" => 配列 (size=3) 0 => object(stdClass) public "phone" => string "79871234567" (length=11) public " text" => 文字列 "テスト メッセージ 1" (長さ = 37) public "date" => 文字列 "2013-07-21T15:00:00.26" (長さ = 22) public "type" => 文字列 "15" (長さ=2) 1 => object(stdClass) public "phone" => string "79871234567" (length=11) public "text" => string "テストメッセージ 2" (length=37) public "date" => string " 2014-08-22T16:01:10" (length=19) public "type" => string "16" (length=2) 2 => object(stdClass) public "phone" => string "79871234567" (length= 11) public "text" => string "テストメッセージ 3" (length=37) public "date" => string "2014-08-22T16:01:10" (length=19) public "type" => string " 17インチ (長さ=2)
彼らが言うように、「ほぼ」! この (少し悲しい) メモについて、ゆっくりと話をまとめて、自分たちでいくつかの結論を導き出すことを提案します。

8 結論

ついにここに到着しました! 今何ができるかを考えてみましょう。
  • Web サービスに必要な WSDL ファイルを作成できます。
  • SOAP 経由でサーバーと通信できる独自のクライアントを簡単に作成できます。
  • SOAP 経由で外部と通信する独自​​のサーバーを作成できます。
  • 同じタイプのオブジェクトの配列をクライアントからサーバーに送信できます (いくつかの制限があります)。
また、ちょっとした調査中にいくつかの発見がありました。
  • ネイティブ SoapClient クラスは、XML 内の同じタイプのデータ構造を正しくシリアル化しません。
  • 配列を XML にシリアル化すると、という追加の要素が作成されます。 構造体;
  • オブジェクトを XML にシリアル化すると、と呼ばれる追加の要素が作成されます。 インチキ;
  • インチキ~よりも悪気が少ない 構造体エンベロープがよりコンパクトになるという事実によるものです (エンベロープの XML ヘッダーに余分な名前空間が追加されません)。
  • 残念ながら、SoapServer クラスは、XML スキーマを使用してエンベロープ データを自動的に検証しません (おそらく他のサーバーも検証しません)。

創作の歴史

出現に伴い パソコンそれらを団結させる必要もありました。 最初は単純なケーブル接続がありましたが、その後登場しました。 ネットワークプロトコル同じOSで動作するコンピュータを統合すること、テクノロジーの発展により、すべてのコンピュータに1つのOSを搭載する必要がなくなり、異なるOSで動作するコンピュータを統合することが可能になりました。 インターネットは統一への道に沿った動きの速度を変えました。

しかし、残念なことに、現在でも統合の問題がすべて解決されているわけではありません。インターネット アプリケーションとサービスの間の通信に単一のプロトコルはありませんでした。 この問題を解決するために、Microsoft、DevelopMentor、UserLand Software、IBM、Lotus Development などの企業が協力し、その共同活動の結果として、リモート プロシージャ コールの標準を記述する Simple Object Access Protocol が作成されました。 XML (Extensible Markup Language) - 拡張可能なマークアップ言語) に基づいています。 SOAP は、言語をまたいだアプリケーションやビジネス統合ツールの開発を大幅に簡素化するように設計されています。 始まりは SOAP 1.0 であり、動作するには HTTP プロトコルが必要でした。

登場後 初期バージョンすでに述べたように、SOAP は Microsoft、DevelopMentor、UserLand の共同作業によって作成され、IBM と Lotus が製品の開発に参加しました。 その結果、異種環境の統合により適した仕様にするために、仕様が大幅に見直されました。 SOAP 1.1 の次のバージョンと最初のバージョンの主な違いは、Microsoft の XML データから XML スキーマへの移行でした。 さらに、新しいバージョンでは、仕様はトランスポート プロトコルに依存しなくなりました。 SOAP 1.0 では HTTP プロトコルが必要でしたが、SOAP 1.1 ではトランスポートの種類は関係ありません。電子メールまたはメッセージ キューイング リンクを使用してメッセージを転送できます。 すでに SOAP 1.0 を採用していた企業は、Microsoft の非標準テクノロジーに縛られていることに気づきました。 ただし、この企業からは、BizTalk Server や SQLサーバー 7.0 は XML データにも依存します。 バージョン 1.1 の出現により、SOAP プロトコルの支持者の輪が拡大しています

SOAP 1.1 の初期バージョンがタスクフォースに提出されました テクニカルサポートインターネット IETF は、1998 年 1 月に Microsoft によって提案された XML データ テクノロジに基づいています。しかし、W3C コンソーシアムでの標準の検討中に、基本構造は XML スキーマに置き換えられました。 World Wide Web Consortium は、SOAP 1.1 を標準の候補として検討するよう求められました。

Simple Object Access Protocol (SOAP) 仕様の最新バージョンは、MSDN™ Developer Program メンバーにサービスを提供する Web サーバー (http://msdn.microsoft.com/) で入手できます。 SOAP は、XML (Extensible Markup Language) を定義するオープンな標準ベースのプロトコルです。 一般的なフォーマットインターネット アプリケーションとサービス間の通信用。 このバージョンでは、SOAP の非同期通信機能が拡張され、HTTP だけでなく、SMTP、FTP、TCP/IP などのインターネット プロトコルのサポートも含まれます。 SOAP 仕様の最新バージョンは、ActiveState Tool Corp.、Ariba Inc.、BORN Information Services Inc.、Commerce One Inc.、Compaq Computer Corp.、DevelopMentor Inc.、Extensibility Inc.、IBM、 IONA Technologies PLC、Intel Corp.、Lotus Development Corp.、ObjectSpace Inc.、Rogue Wave Software Inc.、Scriptics Corp.、Secret Labs AB、UserLand Software、および Zveno Pty. 株式会社 SOAP 仕様は、基盤となるものに関係なく、インターネットやイントラネット全体でサービスを統合するための共通メカニズムを提供します。 オペレーティング·システム、オブジェクトモデルまたはプログラミング言語。 SOAP は、インターネット標準の XML と HTTP に基づいて、新しい 既存のアプリケーション。 SOAP をサポートする Web サイトは、純粋にプログラム的にアクセスでき、人間の介入を必要としない Web サービスになります。 インターネットに接続されたアプリケーション間の直接対話を可能にする単一のインフラストラクチャにより、サービスとデバイスがインターネット上のどこにあるかに関係なく、サービスとデバイスを統合する新たな機会が開かれます。

WebサービスとSOAP

Web サービスと SOAP は、クロスプラットフォームのアプリケーション通信の問題を解決するように設計されています。 この記事は、これらの新しい有望なテクノロジーについての洞察を得るのに役立ちます。

石鹸とは

現在、リモート メソッド呼び出しに使用されているテクノロジ (DCOM、CORBA/IIOP、および RMI) は、対話を構成および整理するのが非常に困難です。 これにより、操作や機能に問題が発生します。 分散システム(セキュリティの問題、ファイアウォールを通過する転送など)。 既存の問題は、SOAP (Simple Object Access Protocol) の作成によって首尾よく解決されました。 単純なプロトコル、XML に基づいており、分散環境 (WWW) でのメッセージングに使用されます。 これは、Web サービスを作成し、メソッドをリモートで呼び出すために設計されています。 SOAP は、HTTP、SMTP などのさまざまなトランスポート プロトコルで使用できます。

Webサービスとは

Web サービスは、サービスと対話する外部アプリケーションで使用するために公開される機能とデータです。 標準プロトコルそしてデータ形式。 Web サービスは、実装言語やプラットフォームから完全に独立しています。 Webサービス技術というのは、 礎石 プログラムモデル Microsoft .NET。 SOAP の機能を実証するために、Microsoft から最近リリースされた SOAP Toolkit バージョン 2.0 の実装を使用しました。 注意すべきこと 現行版 Toolkit は、以前のツールキット (Microsoft SOAP Toolkit for Visual Studio 6.0) や SOAP Toolkit 2.0 のベータ版とは大きく異なります。

クライアントとサーバー間の対話のメカニズム

  1. クライアント アプリケーションは SOAPClient オブジェクトをインスタンス化します。
  2. SOAPClient は、Web サービス メソッド記述ファイル (WSDL および Web サービス メタ言語 - WSML) を読み取ります。 これらのファイルはクライアントに保存することもできます。
  3. クライアント アプリケーションは、SOAPClient オブジェクトの遅延バインディング機能を使用して、サービス メソッドを呼び出します。 SOAPClient はリクエスト パケット (SOAP エンベロープ) を生成し、サーバーに送信します。 任意のトランスポート プロトコルを使用できますが、通常は HTTP が使用されます。
  4. パケットはリスナー サーバー アプリケーション (ISAPI アプリケーションまたは ASP ページの可能性があります) を受け取り、SOAPServer オブジェクトを作成し、それに要求パケットを渡します。
  5. SOAPServer は Web サービスの説明を読み取り、その説明とリクエスト パケットを XML DOM ツリーにロードします。
  6. SOAPServer は、サービスを実装するオブジェクト/アプリケーションのメソッドを呼び出します。
  7. メソッドの実行結果またはエラーの説明は、SOAPServer オブジェクトによって応答パケットに変換され、クライアントに送信されます。
  8. SOAPClient オブジェクトは、受信したパケットを解析し、サービスの結果または発生したエラーの説明をクライアント アプリケーションに返します。

WSDL ファイルは次のドキュメントです。 XML形式では、Web サービスによって提供されるメソッドについて説明します。 また、メソッドのパラメータ、そのタイプ、名前、サービス リスナーの場所。 SOAP Toolkit ウィザードはこのドキュメントを自動的に生成します。

SOAP エンベロープ (パッケージ) - メソッドを実行するためのリクエスト/レスポンスを含む XML ドキュメント。 情報が封入された郵便封筒と考えるのが最も便利です。 Envelope タグはパッケージのルート要素である必要があります。 Header 要素はオプションですが、Body 要素は存在し、Envelope 要素の直接の子である必要があります。 メソッド実行エラーの場合、サーバーは Body タグに Fault 要素を含むパッケージを生成します。 詳細な説明エラー。 高レベル インターフェイス SOAPClient および SOAPServer を使用する場合、パッケージ形式の複雑な部分に入る必要はありませんが、必要に応じて、低レベル インターフェイスを使用したり、手動でパッケージを作成したりすることもできます。

SOAP Toolkit オブジェクト モデルを使用すると、低レベルの API オブジェクトを操作できるようになります。

  • SoapConnector - SOAP パケットを交換するためのトランスポート プロトコルとの連携を提供します。
  • SoapConnectorFactory - WSDL ファイル (タグ) で指定されたトランスポート プロトコルのコネクタを作成するメソッドを提供します。
  • SoapReader - 読み取り SOAPメッセージ XML DOM ツリーを構築します
  • SoapSerializer - SOAP メッセージを作成するためのメソッドが含まれています
  • IsoapTypeMapper、SoapTypeMapperFactory - 複雑なデータ型を操作できるようにするインターフェイス

高レベルの API オブジェクトを使用すると、データの転送のみが可能になります 単純なタイプ(int、srting、float...) ですが、SOAP 1.1 仕様では、配列、構造体、リスト、およびそれらの組み合わせなど、より複雑なデータ型が許可されています。 このような型を操作するには、IsoapTypeMapper インターフェイスと SoapTypeMapperFactory インターフェイスを使用する必要があります。