从SOAP消息的组成可以看出,SOAP的消息其实是有了约束的XML的消息。我们可以用TCPMon工具来观察SOAP消息的请求和回应来帮助我们理解这一‘请求/回应’过程。
TCPMon是apache下的一个项目,可以拦截客户和服务之间的HTTP请求和HTTP相应信息,并查看在WebService服务器和客户机之间传递SOAP消息过程,有时我们需要得到这些消息以便调试,而Apache的TCPMon可以帮助我们做到这一点(顺便说下,eclipse自带的web service explorer也可以查看soap消息,但没有TCPMon的更详细)。TCPMon的下载地址在http://ws.apache.org/commons/tcpmon/download.cgi,找到Binary Distribution,下载后会得到一个tcpmon-1.0-bin.zip的包,解开后进去\tcpmon-1.0-bin\build目录,双击tcpmon.bat就可以执行程序了。这里有必要对tcpmon说明一下,它实际上是个代理,起一个消息转发的作用,监视的是转发出去的消息。最终,消息还是要送到具体的地址和端口,否则响应就不正确了。也就是说,TCPMon是一个消息的二传手,它的前后都应该配置正确才行。使用TCPMon监控web service的流程大致是如下图这样的:
服务地址:
<soap:address location="http://localhost:8089/na" />
现在我们的客户端是如下代码:
URL url=new URL("http://localhost:7777/na?wsdl"); QName sname=new QName("http://service.ljfbest.com/", "MyServiceImplService"); Service service=Service.create(url, sname); IMyService ms=service.getPort(IMyService.class); System.out.println(ms.add(2, 3));
从第一行可以看出我们提交的端口是7777,而服务的地址是:http://localhost:8089/na
那么我们的TCPMon就应该是如下这样的配置:
点击add按钮,将会出现一个名为Port 7777的窗口,这个界面将监听客户端与服务器SOAP消息的交换。运行客户端,然后就会在port 7777窗口中得到‘请求/回应’消息,那么本例得到的就是如下的信息:
POST /na HTTP/1.1 Content-type: text/xml;charset="utf-8" Soapaction: "" Accept: text/xml, multipart/related, text/html, image/gif, image/jpeg, *; q=.2, */*; q=.2 User-Agent: JAX-WS RI 2.1.6 in JDK 6 Host: 127.0.0.1:7777 Connection: keep-alive Content-Length: 203 <?xml version="1.0" ?> <S:Envelope xmlns:S="http://schemas.xmlsoap.org/soap/envelope/"> <S:Body> <ns2:add xmlns:ns2="http://service.ljfbest.com/"> <arg0>2</arg0> <arg1>3</arg1> </ns2:add> </S:Body> </S:Envelope> HTTP/1.1 200 OK Transfer-encoding: chunked Content-type: text/xml;charset="utf-8" 5e <?xml version="1.0" ?> <S:Envelope xmlns:S="http://schemas.xmlsoap.org/soap/envelope/"> <S:Body>73 <ns2:addResponse xmlns:ns2="http://service.ljfbest.com/"> <return>5</return> </ns2:addResponse> </S:Body> </S:Envelope>0
下面通过上面的结果来分析下SOAP消息的传递。
上面的消息通信是建立在HTTP之上的,而HTTP在 TCP/IP之上进行通信。HTTP客户机使用TCP连接到HTTP服务器,在建立连接之后,客户机可向服务器发送 HTTP 请求消息:
POST /na HTTP/1.1
Host: 127.0.0.1
Content-Type: text/html;charset=”utf-8”
Content-Length: 203
随后服务器会处理此请求,然后向客户机发送一个 HTTP响应。此响应包含了可指示请求状态的状态代码:200 OK
Content-Type: text/html;charset=”utf-8”
在上面的例子中,服务器返回了一个200的状态代码,这是 HTTP 请求成功的标准代码。
假如服务器无法对请求进行解码,它可能会返回类似这样的信息:
400 Bad Request
Content-Length: 0
可以看出SOAP是和HTTP绑定在一起的,即:SOAP HTTP Binding。SOAP 方法指的是遵守 SOAP 编码规则的 HTTP 请求/响应:
HTTP + XML = SOAP
SOAP 请求可能是 HTTP POST或HTTP GET 请求,HTTP POST请求规定至少两个 HTTP 头:Content -Type和 Content –Length:
Content-Type:SOAP 的请求和响应的 Content-Type 头可定义消息的 MIME 类型,以及用于请求或响应的XML 主体的字符编码(可选)。(MIME 是描述消息内容类型的因特网标准。) 语法:
Content-Type: MIMEType; charset=character -encoding
Content–Length:头规定请求或响应主体的字节数。语法:
Content-Length: bytes
根本上来讲,SOAP消息是从发送方到接受方的一种传输方法,而且,SOAP消息一般会和实现模式相结合,如请求/响应。SOAP的实现由特殊网络系统的特有特征来优化。例如,通过HTTP:Biding将SOAP响应消息通过HTTP响应来传输,请求和响应使用同一连接,当然SOAP也可以与其它协议绑定。
然而,无论SOAP是与哪种协议绑定,消息都可以通过消息路径Message Path来指定路径发送,消息路径机制使消息在到达最终目的地之前可以在一个或多个中介上处理。这是一个非常有用、且极其适合分布式计算环境的一个机制。例如,一个申请订单的消息可以首先到达帐户服务确认身份获取权限,然后到达商品价格查询服务获得所需产品的最新价格,最后进入订单服务根据所得的最新价格产生订单并响应调用者。通过这样一种机制可以实现基于模块化服务设计基础的:B2B商务流程实现,通过低耦合模块的统一集成获得良好的系统体系和功能实现。
了解了SOAP的实现,也就知道了web service的一些特性是如何实现的了,web service的跨防火墙,消息的传递等特性正是基于SOAP。
另外,通过eclipse自带的“Web Services Explorer”也可以粗略察看soap的消息……