SOAP消息的格式

WebService 使用HTTP 协议传输消息,消息格式使用SOAP,那么在客户端和服务器端传输的SOAP 消息是什么样子的呢?下面我们将服务端SoapServer.java 的代码改为如下的形式:

package JASWS;


import org.apache.cxf.interceptor.LoggingInInterceptor;
import org.apache.cxf.interceptor.LoggingOutInterceptor;
import org.apache.cxf.jaxws.JaxWsServerFactoryBean;


public class SoapServer1 {


public static void main(String[] args){
JaxWsServerFactoryBean soapFactoryBean = new JaxWsServerFactoryBean();
soapFactoryBean.getInInterceptors().add(new LoggingInInterceptor());
soapFactoryBean.getOutInterceptors().add(new LoggingOutInterceptor());
// 注意这里是实现类不是接口
soapFactoryBean.setServiceClass(HelloServiceImpl.class);
soapFactoryBean.setAddress("http://127.0.0.1:8090/helloService");
soapFactoryBean.create();
}

}


我们注意到这里将javax.xml.ws.EndPoint 改为CXF 特有的API---JaxWsServerFactoryBean,并且我们对服务端工厂Bean 的输入拦截器集合、输出拦截器集合中分别添加了日志拦截器(拦截器是CXF 的一项扩展功能,CXF 提供了很多拦截器实现,你也可以自己实现一种拦截器),这样可以在Web 服务端发送和接收消息时输出信息。
现在我们再次运行服务器端和客户端,你会看到控制台输出如下信息:
2009-6-17 22:35:57 org.apache.cxf.interceptor.LoggingInInterceptor
logging
信息: Inbound Message
----------------------------
ID: 2
Address: /helloService
Encoding: UTF-8
Content-Type: text/xml; charset=UTF-8
Headers: {content-type=[text/xml; charset=UTF-8],
connection=[keep-alive], Host=[127.0.0.1:8080], Content-Length=[367],
SOAPAction=[""], User-Agent=[Apache CXF 2.2.2], Content-Type=[text/xml;

charset=UTF-8], Accept=[*/*], Pragma=[no-cache],
Cache-Control=[no-cache]}
Payload: <soap:Envelope
xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/"><soap:Body><ns
2:selectMaxAgeStudent
xmlns:ns2="http://server.soap.ilkj.net/"><c1><birthday>1989-01-28T00:
00:00.000+08:00</birthday><id>1</id><name>A</name></c1><c2><birthday>
1990-01-28T00:00:00.000+08:00</birthday><id>2</id><name>B</name></c2>
</ns2:selectMaxAgeStudent></soap:Body></soap:Envelope>
--------------------------------------
2009-6-17 22:35:57
org.apache.cxf.interceptor.LoggingOutInterceptor$LoggingCallback
onClose
信息: Outbound Message
---------------------------
ID: 2
Encoding: UTF-8
Content-Type: text/xml
Headers: {}
Payload: <soap:Envelope
xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/"><soap:Body><ns
2:selectMaxAgeStudentResponse
xmlns:ns2="http://server.soap.ilkj.net/"><return><birthday>1989-01-28
T00:00:00+08:00</birthday><id>1</id><name>A</name></return></ns2:sele
ctMaxAgeStudentResponse></soap:Body></soap:Envelope>
--------------------------------------
Inbound Message 输出的是服务器端接收到的SOAP 信息,Outbound Message 输出的服务器端响应的SOAP 信息,SOAP 的Headers:{}的前面是SOAP 消息的标识、编码方式、MIME类型,Headers:{}熟悉HTTP 应该很容易看懂这里面的消息报头的作用,Headers:{}后面的Payload(有效负载,也叫净荷)的XML 就是SOAP 消息的真正内容,我们看到SOAP 消息内容被封装为<soap:Envelope …SOAP 信封,在信封之间的内容就是SOAP 消息正文,这个元素还有一个子元素<soap:Header …,如果你的某些注解的header=true,那么它将被放到<soap:Header …中传输,而不是SOAP 消息正文。
例如我们把服务端的IHelloService 接口改为如下的形式:

package JASWS;


import javax.jws.WebParam;
import javax.jws.WebService;
@WebService
public interface IHelloService1 {


Customer selectMaxAgeStudent(
@WebParam(name = "c1", header = true) Customer c1,
@WebParam(name = "c2") Customer c2);
Customer selectMaxLongNameStudent(Customer c1, Customer c2);

}


我们注意第一个方法的第一个参数的header=true,也就是放在SOAP 的消息头中传输。然后我们重新生成客户端的代码,SoapClient 的调用代码改为如下的形式:

package JASWS;


import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.GregorianCalendar;
import org.apache.cxf.jaxws.JaxWsProxyFactoryBean;


public class SoapClient1 {
public static void main(String[] args) throws ParseException {
JaxWsProxyFactoryBean soapFactoryBean = new JaxWsProxyFactoryBean();
soapFactoryBean.setAddress("http://127.0.0.1:8090/helloService");
soapFactoryBean.setServiceClass(IHelloService.class);
Object o = soapFactoryBean.create();
IHelloService helloService = (IHelloService) o;
Customer c1 = new Customer();
c1.setId(1);
c1.setName("A");
Customer c2 = new Customer();
c2.setId(2);
c2.setName("B");
/*
SelectMaxAgeStudent sms = new SelectMaxAgeStudent();
sms.setC2(c2);
*/
System.out.println(helloService.selectMaxAgeStudent(c1, c2).getName());
}
}


我们注意到现在客户端的IHelloService 的第一个方法的第一个参数是SelectMaxAgeStudent,
而不是Customer,运行之后控制台输出如下语句:
2009-6-17 23:02:29 org.apache.cxf.interceptor.LoggingInInterceptor
logging
信息: Inbound Message
----------------------------
ID: 2
Address: /helloService
Encoding: UTF-8
Content-Type: text/xml; charset=UTF-8
Headers: {content-type=[text/xml; charset=UTF-8],
connection=[keep-alive], Host=[127.0.0.1:8080], Content-Length=[443],
SOAPAction=[""], User-Agent=[Apache CXF 2.2.2], Content-Type=[text/xml;
charset=UTF-8], Accept=[*/*], Pragma=[no-cache],
Cache-Control=[no-cache]}
Payload: <soap:Envelope
xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/"><soap:Header><
ns2:c1
xmlns:ns2="http://server.soap.ilkj.net/"><birthday>1989-01-28T00:00:0
0.000+08:00</birthday><id>1</id><name>A</name></ns2:c1></soap:Header>
<soap:Body><ns2:selectMaxAgeStudent
xmlns:ns2="http://server.soap.ilkj.net/"><c2><birthday>1990-01-28T00:
00:00.000+08:00</birthday><id>2</id><name>B</name></c2></ns2:selectMa
xAgeStudent></soap:Body></soap:Envelope>
--------------------------------------

2009-6-17 23:02:29
org.apache.cxf.interceptor.LoggingOutInterceptor$LoggingCallback
onClose
信息: Outbound Message
---------------------------
ID: 2
Encoding: UTF-8
Content-Type: text/xml
Headers: {}
Payload: <soap:Envelope
xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/"><soap:Body><ns
2:selectMaxAgeStudentResponse

xmlns:ns2="http://server.soap.ilkj.net/"><return><birthday>1989-01-28
T00:00:00+08:00</birthday><id>1</id><name>A</name></return></ns2:sele
ctMaxAgeStudentResponse></soap:Body></soap:Envelope>
--------------------------------------
我 们注意到Inbound Message 中的SOAP 信封将第一个方法的第一个参数放在
<soap:Header … 中传输。

你可能感兴趣的:(SOAP消息的格式)