聽說SOAP Action header在SOAP 1.1規範中着實讓很多開發者喝了一壺。真的有那麼難理解麼?我想這應該是由於SOAP有兩種很是不一樣的使用方式,而SOAP Action主要是被用來支持其中應用較少的一種方式的緣由。在我看來,這種方式也很是有價值。java
讓咱們先看看SOAP 1.1規範是怎麼定義HTTP SOAP Action header的:工具
SOAP Action HTTP request header被用來標識SOAP HTTP請求的目的地,其值是個URI地址。SOAP發送並步限制格式、URI特徵或其必須可解析,那麼在這種狀況下,發送一個HTTP SOAP請求時,其HTTP客戶端必須使用/指明SOAP Action HTTP request header。spa
SOAP Action header的內容能夠被用在服務端,諸如:防火牆適當的過濾基於HTTP的SOAP請求消息等場景。SOAP Action header的值爲空串("")表示SOAP消息的目的地由HTTP請求的URI標識;無值則表示沒有指定這條消息的目的地。code
看了官方的定義,相信你們也迷糊了,迷糊在「目的地」這個詞上吧?那麼,給它一個準確的說法吧——「肯定執行某一行爲的路徑」。xml
看一個SOAP消息的例子:對象
<SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/" SOAP-ENV:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"> <SOAP-ENV:Body> <m:GetLastTradePrice xmlns:m="Some-URI"> <symbol>XYS</symbol> </m:GetLastTradePrice> </SOAP-ENV:Body> </SOAP-ENV:Envelope>
很明顯的,這條消息指明瞭要去執行服務端的「GetLastTradePrice」這個方法,開發者不會對此沒有疑問,這樣看來,SOAP Action也許顯得多餘了?blog
然而,在另外一種SOAP消息的發送場景種,卻少不了SOAP Action。在這種場景中,SOAP消息並無顯示的指定要調用的服務方法名,而是利用低層的傳輸協議發送(這樣的化,通常會被Web services忽視),例如使用HTTP的Post方式發送的SOAP消息。索引
拿AWT組件容器來舉個例子吧,咱們知道有不少AWT容器,例如:Panel,Box,Window等等,不少狀況下,開發者知道他們建立的泛型容器對象下真正是什麼對象。那麼,假設下面兩段代碼裏的java.awt.Container對象實際上是一個Box吧:開發
1.io
comp = new TextField( "test" ); java.awt.Container c = Foo.bar(); c.add( comp );
2.
comp = new TextField( "test" ); java.awt.Container c = Foo.bar(); ((java.awt.Panel)c).add( comp );
以上兩段代碼產生兩種不一樣的結果。「add()」方法對二者彷佛有着相同的意義,可是在代碼2中其被擴展爲「做爲一個Panel對象去add」。因此很明顯的,代碼2會拋出一個異常,由於咱們知道這個對象其實是Box,而咱們的代碼期待的是Panel。
HTTP POST的意義正如這個例子中的「add()」方法同樣,HTTP POST提供一個關於SOAP Action如何被使用的索引;而SOAP Action header的值則應該被用來指明這個「擴展」的目的地——這條SOAP/HTTP消息發送者所期待的處理容器的名稱(能夠這樣理解:即相應的API方法)。那麼,正如上面那個AWT例子同樣,若是這種期待沒有被知足,就會產生一個錯誤。
注意:在SOAP 1.2規範中,SOAP Action header這個屬性被「action」所取代,但其做用和工做原理都沒有變化。
有意思的是,在Tibco的EAI工具BW中,使用SOAP服務端活動必須指定SOAP Action屬性,若是引用的原始WSDL沒有使用這個屬性的話,也必須明顯的指明;所以,相應的,其客戶端也要注意啦——必須爲SOAP Action屬性填入期待的URI。