JAVA的WebService规范(支持)

转载于:http://blog.csdn.net/qiailin/article/details/6177064


SOA(Service-Oriented Architecture)面向服务架构是一种思想,它将应用程序的不同功能单元通过中立的契约(独立于硬件平台、操作系统和编程语言)联系起来,使得各种形式的功能单元更好的集成。目前来说,WebService 是SOA 的一种较好的实现方WebService 采用HTTP 作为传输协议,SOAP(Simple Object Access Protocol)作为传输消息的格式。但WebService 并不是完全符合SOA 的概念,因为SOAP 协议是WebService 的特有协议,并未符合SOA 的传输协议透明化的要求。SOAP 是一种应用协议,早期应用于RPC 的实现,传输协议可以依赖于HTTP、SMTP 等。SOA 的产生共经历了如下过程:

 

 

 

通常采用SOA 的系统叫做服务总线(BUS),结构如下图所示:

 

 

----------------------------------------------------------------------------------------------------------------------------------------

JAVA中的Web服务规范:
JAVA 中共有三种WebService 规范,分别是JAXM&SAAJ、JAX-WS(JAX-RPC)、JAX-RS。
下面来分别简要的介绍一下这三个规范。
(1.)JAX-WS:
JAX-WS(Java API For XML-WebService),JDK1.6 自带的版本为JAX-WS2.1,其底层支

持为JAXB。早期的基于SOAP 的JAVA 的Web 服务规范JAX-RPC(Java API For
XML-Remote Procedure Call)目前已经被JAX-WS 规范取代,JAX-WS 是JAX-RPC 的演进
版本,但JAX-WS 并不完全向后兼容JAX-RPC,二者最大的区别就是RPC/encoded 样式的
WSDL,JAX-WS 已经不提供这种支持。JAX-RPC 的API 从JAVA EE5 开始已经移除,如
果你使用J2EE1.4,其API 位于javax.xml.rpc.*包。
JAX-WS(JSR 224)规范的API 位于javax.xml.ws.*包,其中大部分都是注解,提供API 操
作Web 服务(通常在客户端使用的较多,由于客户端可以借助SDK 生成,因此这个包中的
API 我们较少会直接使用)。
WS-MetaData(JSR 181)是JAX-WS 的依赖规范,其API 位于javax.jws.*包,使用注解配
置公开的Web 服务的相关信息和配置SOAP 消息的相关信息。
(2.)JAXM&SAAJ:
JAXM(JAVA API For XML Message)主要定义了包含了发送和接收消息所需的API,相当
于Web 服务的服务器端,其API 位于javax.messaging.*包,它是JAVA EE 的可选包,因此
你需要单独下载。
SAAJ(SOAP With Attachment API For Java,JSR 67)是与JAXM 搭配使用的API,为构建
SOAP 包和解析SOAP 包提供了重要的支持,支持附件传输,它在服务器端、客户端都需要
使用。这里还要提到的是SAAJ 规范,其API 位于javax.xml.soap.*包。
JAXM&SAAJ 与JAX-WS 都是基于SOAP 的Web 服务,相比之下JAXM&SAAJ 暴漏了SOAP
更多的底层细节,编码比较麻烦,而JAX-WS 更加抽象,隐藏了更多的细节,更加面向对
象,实现起来你基本上不需要关心SOAP 的任何细节。那么如果你想控制SOAP 消息的更
多细节,可以使用JAXM&SAAJ,目前版本为1.3。
(3.)JAX-RS:
JAX-RS 是JAVA 针对REST(Representation State Transfer)风格制定的一套Web 服务规范,
由于推出的较晚,该规范(JSR 311,目前JAX-RS 的版本为1.0)并未随JDK1.6 一起发行,
你需要到JCP 上单独下载JAX-RS 规范的接口,其API 位于javax.ws.rs.*包。
这里的JAX-WS 和JAX-RS 规范我们采用Apache CXF 作为实现,CXF 是Objectweb Celtix
和Codehaus XFire 合并而成。CXF 的核心是org.apache.cxf.Bus(总线),类似于Spring 的
ApplicationContext,Bus 由BusFactory 创建,默认是SpringBusFactory 类,可见默认CXF
是依赖于Spring 的,Bus 都有一个ID,默认的BUS 的ID 是cxf。你要注意的是Apache CXF
2.2 的发行包中的jar 你如果直接全部放到lib 目录,那么你必须使用JDK1.6,否则会报
JAX-WS 版本不一致的问题。对于JAXM&SAAJ 规范我们采用JDK 中自带的默认实现。
------------------------------------------------------------------------------------
1.JAVA的WebService规范JAX-WS:
Web 服务从前面的图中不难看出自然分为Server、Client 两部分,Server 公开Web 服务,
Client 调用Web 服务,JAX-WS 的服务端、客户端双方传输数据使用的SOAP 消息格式封
装数据,在后面我们会看到其实SOAP 信封内包装的就是一段XML 代码。

 

 I.服务端示例:
我们先看一个服务器端示例:
(1.)公开Web 服务的接口IHelloService:

 

  1. package net.ilkj.soap.server;  
  2. import javax.jws.WebService;  
  3. @WebService  
  4. public interface IHelloService {  
  5. Customer selectMaxAgeStudent(Customer c1, Customer c2);  
  6. Customer selectMaxLongNameStudent(Customer c1, Customer c2);  
  7. }  

我们看到这个接口很简单,仅仅是使用类级别注解@WebService 就标注了这个接口的方法
将公开为Web 服务,使用了这个注解的接口的所有方法都将公开为Web 服务的操作,如果
你想屏蔽某个方法,可以使用方法注解@Method 的exclude=true。我们也通常把公开为Web
服务的接口叫做SEI(Service EndPoint Interface)服务端点接口。

 

(2.)实现类HelloServiceImpl:

 

  1. package net.ilkj.soap.server;  
  2. public class HelloServiceImpl implements IHelloService {  
  3. @Override  
  4. public Customer selectMaxAgeStudent(Customer c1, Customer c2) {  
  5. if (c1.getBirthday().getTime() > c2.getBirthday().getTime())  
  6. return c2;  
  7. else  
  8. return c1;  
  9. }  
  10. @Override  
  11. public Customer selectMaxLongNameStudent(Customer c1, Customer c2)  
  12. {  
  13. if (c1.getName().length() > c2.getName().length())  
  14. return c1;  
  15. else  
  16. return c2;  
  17. }  
  18. }  

 

这个实现类没有任何特殊之处,但是如果你的实现类还实现了其他的接口,那么你需要在实
现类上使用@WebService 注解的endpointInterface 属性指定那个接口是SEI(全类名)。
(3.)Customer 类:

 

  1. package net.ilkj.soap.server;  
  2. import java.util.Date;  
  3. import javax.xml.bind.annotation.XmlRootElement;  
  4. @XmlRootElement(name = "Customer")  
  5. public class Customer {  
  6. private long id;  
  7. private String name;  
  8. private Date birthday;  
  9. public long getId() {  
  10. return id;  
  11. }  
  12. public void setId(long id) {  
  13. this.id = id;  
  14. }  
  15. public String getName() {  
  16. return name;  
  17. }  
  18. public void setName(String name) {  
  19. this.name = name;  
  20. }  
  21. public Date getBirthday() {  
  22. return birthday;  
  23. }  
  24. public void setBirthday(Date birthday) {  
  25. this.birthday = birthday;  
  26. }  
  27. }  

 

这个类是公开为Web 服务的接口中的参数类型和返回值,因此你需要使用JAXB 注解告诉
CXF 如何在XML和Java Object 之间处理,因为前面说过SOAP 消息格式包装的是一段XML
代码,那么无论是服务器端还是客户端在接收到SOAP 消息时都需要将XML 转化为Java
Object,在发送SOAP 消息时需要将Java Object 转化为XML。
(4.)发布Web 服务:

 

  1. package net.ilkj.soap.server;  
  2. import javax.xml.ws.Endpoint;  
  3. public class SoapServer {  
  4. public static void main(String[] args) {  
  5. Endpoint.publish("http://127.0.0.1:8080/helloService",  
  6. new HelloServiceImpl());  
  7. }  
  8. }  

 

注意我们发布Web 服务使用的是javax.xml.ws.*包中的EndPoint 的静态方法publish()。
(5.)查看WSDL:
我们访问http://127.0.0.1:8080/helloService?wsdl 地址,您会看到很长的XML 文件(由于浏
览器的问题,如果你看到的是空白页面,请查看源代码),这就是WSDL(WebService Definition
Language),对于你要访问的Web 服务,只要在其地址后加上,就可以在浏览器中查看用于
描述Web 服务的WSDL,这也是一种XML,Web 服务能够被各种编程语言书写的程序访
问就是通过WSDL 这种通用的契约来完成的。
如果你已经看到WSDL,那么表示我们的Web 服务发布成功了。你可能会差异,我们没有
借助Tomcat 这样的Web 服务器,直接运行一个main 方法是怎么发布的Web 服务呢?其实
CXF 内置了Jetty(Servlet 容器),因此你不需要将你的程序部署到Tomcat 等Web 服务器
也可以正常发布Web 服务。
------------------------------------------------------------------------------------
II.分析WSDL的构成:
下面我们来解释一下你所看到的WSDL 的结构,你可以对照你所生成WSDL(文件太长,
Word 里实在放不下)。
(1.)<wsdl:definitions …
这个是WSDL 的根元素,我们要关心的是三个属性,name 属性值为公开的Web 服务的接
口的实现类+Service(上例中为name="HelloServiceImplService",不同的JAX-WS
实现名字是不一样的);targetNamespace 指定目标名称空间,targetNamespace 的值被后面
的xmlns:tns 属性作为值, 默认是使用接口实现类的包名的反缀
(targetNamespace="http://server.soap.ilkj.net/" …
xmlns:tns="http://server.soap.ilkj.net/"),
你可以使用@WebService 注解的targetNamespace 属性指定你想要的名称空间。
(2.)<wsdl:types …
这个元素会通过<xs:element … 声明几个复杂数据类型的元素。
一般首先你看到的是Web 服务中的方法参数、返回值所涉及的所有复杂(complex)类型的
元素定义<xs:element …,其中name 属性值是这个复杂类型的JAXB 注解的name 属性值,
type 属性是tns:+JAXB 注解的name 属性值的全小写形式(上例中的方法参数、返回值只涉
及一个复杂类型Customer,Customer 的@XmlRootElement 注解的name 属性值为Customer,
因此你会看到<xs:element name="Customer" type="tns:customer" />)。
再向下你会看到XXX 元素和XXXResponse 元素,其中XXX 是方法名称(你可以使用
@WebMethod 的operationName 属性值指定XXX 的值),XXX 是对方法参数的封装,
XXXResponse 是对返回值的封装,上例中你会看到
<xs:element name="selectMaxAgeStudentMethod"
type="tns:selectMaxAgeStudentMethod" />
<xs:element name="selectMaxAgeStudentMethodResponse"
type="tns:selectMaxAgeStudentMethodResponse" />
<xs:element name="selectMaxLongNameStudent"
type="tns:selectMaxLongNameStudent" />
<xs:element name="selectMaxLongNameStudentResponse"
type="tns:selectMaxLongNameStudentResponse" />
内容,
最 后你会看到一组<xs:complexType … 元素, 这个元素通过name 属性关联到
<xs:element … ,它为前面定义的元素指定封装的具体内容(通过子元素<xs:sequence … 指
定),上例中方法参数的复杂类型指定如下形式:
<xs:complexType name="selectMaxAgeStudentMethod">
<xs:sequence>
<xs:element minOccurs="0" name="arg0" type="tns:customer" />
<xs:element minOccurs="0" name="arg1" type="tns:customer" />
</xs:sequence>
</xs:complexType>
我们看到方法参数名称为arg0、arg1、…,如果你想指定方法参数的名字在方法参数前使用
@WebParam 的name 属性指定值,同样,方法的返回值同样可以使用@WebResult 注解指定
相关的属性值。
例如:
@WebResult(name = "method")
Customer selectMaxAgeStudent(@WebParam(name = "c1") Customer c1,
@WebParam(name = "c2") Customer c2);
(3.)<wsdl:message …
这个元素将输入参数(方法参数)和响应结果(方法返回值)、受检查的异常信息包装为消
息。
(4.)<wsdl:portType …
这个元素指定Web 服务的端口类型(Web 服务会被发布为EndPoint 端点服务),它的name
属性默认为接口名称(你可以使用@WebService 注解的name 属性指定值)。这个元素包含
了一系列的<wsdl:operation …子元素指定该端点服务包含了那些操作( 方法) ,
<wsdl:operation …的子元素<wsdl:input …、<wsdl:output …指定操作的输入输出(通过属性
message 绑定到前面声明过的消息)。
(5.)<wsdl:binding …
这个元素将前面最终的端点服务绑定到SOAP 协议(你可以看出来WSDL 从上到下依次有
着依赖关系),其中的<soap:xxx … 的style、use 分别可以使用SOAPBinding 注解的style、
use 属性指定值、<wsdl:operation … 指定公开的操作(方法)。这部分XML 指定最终发布
的Web 服务的SOAP 消息封装格式、发布地址等。
(6.)<wsdl:service …
这个元素的name 属性指定服务名称(这里与根元素的name 属性相同),子元素<wsdl:port…
的name 属性指定port 名称,子元素<soap:address … 的location 属性指定Web 服务的地址。
------------------------------------------------------------------------------------
III.客户端调用示例:
我们从上面可以知道Web 服务只向客户端暴漏WSDL,那么客户端必须将WSDL 转换为自
己的编程语言书写的代码。JAX-WS 的各种实现都提供相应的工具进行WSDL 与JAVA 之
间的互相转换,你可以在CXF 的运行包中找到bin 目录,其中的wsdl2java.bat 可以将WSDL
转换为JAVA 类,bin 目录的各种bat 的名字可以很容易知道其作用,但要注意JAVA 类转
换为WSDL 最好使用前面的URL?wsdl 的方式获得,因为这样得到的是最准确的。
你可以在命令行将当前目录切换到CXF 的bin 目录,然后运行wsdl2java –h 查看这个批处理
命令的各个参数的作用,常用的方式就是wsdljava –p 包路径 –d 目标文件夹 wsdl 的url
地址。现在我们将前面的WSDL生成客户端代码:
wsdl2java -p net.ilkj.soap.client –d E:/ http://127.0.0.1:8080/helloService?wsdl
你会在E 盘根目录找到生成的客户端代码,然后将它复制到Eclipse 工程即可使用。
如果你使用MyEclipse,可以按照如下步骤从WSDL 生成客户端代码:
New--->Other--->MyEclipse--->Web Services--->Web Services Client,然后依据设置向导即可
完成,但最好还是使用CXF 的wsdl2java 来完成,因为CXF2.2+版本开始支持JAX-WS2.1
规范,而MyEclipse 自带的好像是XFire 的wsdl2java,生成的客户端代码可能不是最新规范
的。
我们上面的WSDL 会生成如下所示的客户端代码:
Customer.java
HelloServiceImplService.java
IHelloService.java
ObjectFactory.java
package-info.java
SelectMaxAgeStudent.java
SelectMaxAgeStudentResponse.java
SelectMaxLongNameStudent.java
SelectMaxLongNameStudentResponse.java
其中package-info.java、ObjectFactory.java 是JAXB 需要的文件;HelloServiceImplService.java
继承自javax.xml.ws.Service 类,用于提供WSDL 的客户端视图,里面使用的是大量
javax.xml.ws.*包中的注解;剩下的类是Web 服务的接口、方法参数、响应值的类。
在 CXF 中使用JaxWsProxyFactoryBean 客户端代理工厂调用Web 服务,代码如下所示:

  1. package net.ilkj.soap.client;  
  2. import java.text.ParseException;  
  3. import java.text.SimpleDateFormat;  
  4. import java.util.GregorianCalendar;  
  5. import org.apache.cxf.jaxws.JaxWsProxyFactoryBean;  
  6. import  
  7. com.sun.org.apache.xerces.internal.jaxp.datatype.XMLGregorianCalendar  
  8. Impl;  
  9. public class SoapClient {  
  10. public static void main(String[] args) throws ParseException {  
  11. JaxWsProxyFactoryBean soapFactoryBean = new  
  12. JaxWsProxyFactoryBean();  
  13. soapFactoryBean.setAddress("http://127.0.0.1:8080/helloService");  
  14. soapFactoryBean.setServiceClass(IHelloService.class);  
  15. Object o = soapFactoryBean.create();  
  16. IHelloService helloService = (IHelloService) o;  
  17. Customer c1 = new Customer();  
  18. c1.setId(1);  
  19. c1.setName("A");  
  20. GregorianCalendar calendar = (GregorianCalendar)  
  21. GregorianCalendar  
  22. .getInstance();  
  23. calendar  
  24. .setTime(new  
  25. SimpleDateFormat("yyyy-MM-dd").parse("1989-01-28"));  
  26. c1.setBirthday(new XMLGregorianCalendarImpl(calendar));  
  27. Customer c2 = new Customer();  
  28. c2.setId(2);  
  29. c2.setName("B");  
  30. calendar  
  31. .setTime(new  
  32. SimpleDateFormat("yyyy-MM-dd").parse("1990-01-28"));  
  33. c2.setBirthday(new XMLGregorianCalendarImpl(calendar));  
  34. System.out.println(helloService.selectMaxAgeStudent(c1,  
  35. c2).getName());  
  36. }  
  37. }  

 

这里要注意的就是Customer 的生日字段JAX-WS 在客户端映射为了XMLGregorianCalendar
类型。我们运行这个客户端,结果输出A,我们的Web 服务调用成功。你还要注意Web 服
务调用可能经常出现超时的问题,但你切不可以为只要WSDL 可以访问,就代表Web 服务
一定可以访问,因为是否可以访问与SEI 的实现类有关,而WSDL 仅是SEI 的一种XML
表示。
------------------------------------------------------------------------------------
IV.SOAP消息的格式:
我们从前面了解WebService 使用HTTP 协议传输消息,消息格式使用SOAP,那么在客户
端和服务器端传输的SOAP 消息是什么样子的呢?下面我们将服务端SoapServer.java 的代
码改为如下的形式:

 

  1. package net.ilkj.soap.server;  
  2. import org.apache.cxf.interceptor.LoggingInInterceptor;  
  3. import org.apache.cxf.interceptor.LoggingOutInterceptor;  
  4. import org.apache.cxf.jaxws.JaxWsServerFactoryBean;  
  5. public class SoapServer {  
  6. public static void main(String[] args) {  
  7. JaxWsServerFactoryBean soapFactoryBean = new  
  8. JaxWsServerFactoryBean();  
  9. soapFactoryBean.getInInterceptors().add(new  
  10. LoggingInInterceptor());  
  11. soapFactoryBean.getOutInterceptors().add(new  
  12. LoggingOutInterceptor());  
  13. // 注意这里是实现类不是接口  
  14. soapFactoryBean.setServiceClass(HelloServiceImpl.class);  
  15. soapFactoryBean.setAddress("http://127.0.0.1:8080/helloService");  
  16. soapFactoryBean.create();  
  17. }  
  18. }  

 

我们注意到这里将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 接口改为如下的形式:

 

  1. package net.ilkj.soap.server;  
  2. import javax.jws.WebParam;  
  3. import javax.jws.WebService;  
  4. @WebService  
  5. public interface IHelloService {  
  6. Customer selectMaxAgeStudent(  
  7. @WebParam(name = "c1", header = true) Customer c1,  
  8. @WebParam(name = "c2") Customer c2);  
  9. Customer selectMaxLongNameStudent(Customer c1, Customer c2);  
  10. }  

 

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

 

package net.ilkj.soap.client;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.GregorianCalendar;
import org.apache.cxf.jaxws.JaxWsProxyFactoryBean;
import
com.sun.org.apache.xerces.internal.jaxp.datatype.XMLGregorianCalendar
Impl;
public class SoapClient {
public static void main(String[] args) throws ParseException {
JaxWsProxyFactoryBean soapFactoryBean = new
JaxWsProxyFactoryBean();
soapFactoryBean.setAddress("http://127.0.0.1:8080/helloService");
soapFactoryBean.setServiceClass(IHelloService.class);
Object o = soapFactoryBean.create();
IHelloService helloService = (IHelloService) o;
Customer c1 = new Customer();
c1.setId(1);
c1.setName("A");
GregorianCalendar calendar = (GregorianCalendar)
GregorianCalendar
.getInstance();
calendar
.setTime(new
SimpleDateFormat("yyyy-MM-dd").parse("1989-01-28"));
c1.setBirthday(new XMLGregorianCalendarImpl(calendar));
Customer c2 = new Customer();
c2.setId(2);
c2.setName("B");
calendar
.setTime(new
SimpleDateFormat("yyyy-MM-dd").parse("1990-01-28"));
c2.setBirthday(new XMLGregorianCalendarImpl(calendar));
SelectMaxAgeStudent sms = new SelectMaxAgeStudent();
sms.setC2(c2);
System.out.println(helloService.selectMaxAgeStudent(sms, c1)
.getReturn().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 … 中传输。

-------------------------------------------------------------------------------------------------------------------------------

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值