CXF系列之SOAP消息格式

来源:互联网 发布:大数据脱敏技术 编辑:程序博客网 时间:2024/05/29 13:55

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

package com.test.server;import org.apache.cxf.interceptor.LoggingInInterceptor;import org.apache.cxf.interceptor.LoggingOutInterceptor;import org.apache.cxf.jaxws.JaxWsServerFactoryBean;import com.test.impl.service.HelloServiceImpl;public class SoapServer1 {public static void main(String[] args) {JaxWsServerFactoryBean factory = new JaxWsServerFactoryBean();//添加输入拦截器factory.getInInterceptors().add(new LoggingInInterceptor());//添加输出拦截器factory.getOutInterceptors().add(new LoggingOutInterceptor());//设置Service,注意这里是实现类,不是接口factory.setServiceClass(HelloServiceImpl.class);//设置访问地址factory.setAddress("http://localhost:8080/helloService");factory.create();}}
我们注意到这里将 javax.xml.ws.EndPoint 改为 CXF 特有的 API---JaxWsServerFactoryBean,并且我们对服务端工厂 Bean 的输入拦截器集合、输出拦截器集合中分别添加了日志拦截器(拦截器是 CXF 的一项扩展功能,CXF 提供了很多拦截器实现,你也可以自己实现一种拦截器),这样可以在 Web 服务端发送和接收消息时输出信息。

现在我们再次运行服务器端和客户端,你会看到控制台输出如下信息:

信息: Inbound Message----------------------------ID: 1Address: http://localhost:8080/helloServiceEncoding: UTF-8Http-Method: POSTContent-Type: text/xml; charset=UTF-8Headers: {Accept=[*/*], Cache-Control=[no-cache], connection=[keep-alive], Content-Length=[371], content-type=[text/xml; charset=UTF-8], Host=[localhost:8080], Pragma=[no-cache], SOAPAction=[""], User-Agent=[Apache CXF 3.0.10]}Payload: <soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/"><soap:Body><ns2:selectMaxAgeCustomer xmlns:ns2="http://service.inter.test.com/"><arg0><birthday>1993-03-06T00:00:00+08:00</birthday><id>1</id><name>A</name></arg0><arg1><birthday>1993-04-06T00:00:00+08:00</birthday><id>2</id><name>B</name></arg1></ns2:selectMaxAgeCustomer></soap:Body></soap:Envelope>--------------------------------------十一月 24, 2016 2:58:29 下午 org.apache.cxf.services.HelloServiceImplService.HelloServiceImplPort.IHelloService信息: Outbound Message---------------------------ID: 1Response-Code: 200Encoding: UTF-8Content-Type: text/xmlHeaders: {}Payload: <soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/"><soap:Body><ns2:selectMaxAgeCustomerResponse xmlns:ns2="http://service.inter.test.com/"><return><birthday>1993-03-06T00:00:00+08:00</birthday><id>1</id><name>A</name></return></ns2:selectMaxAgeCustomerResponse></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 com.test.inter.service;import javax.jws.WebParam;import javax.jws.WebService;import com.test.bean.Customer;@WebServicepublic interface IHelloService1 {public Customer selectMaxAgeCustomer(@WebParam(name = "c1", header = true) Customer c1,@WebParam(name = "c2") Customer c2);public Customer selectLongNameCustomer(Customer c1, Customer c2);}
我们注意第一个方法的第一个参数的 header=true,也就是放在 SOAP 的消息头中传输。然
后我们重新生成客户端的代码,SoapClient 的调用代码改为如下的形式:

package com.test.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.XMLGregorianCalendarImpl;import com.test.bean.Customer;public class SoapClient1 {public static void main(String[] args) throws ParseException {JaxWsProxyFactoryBean factory = new JaxWsProxyFactoryBean();factory.setAddress("http://localhost:8080/helloService");factory.setServiceClass(IHelloService1.class);Object o = factory.create();IHelloService1 service = (IHelloService1)o;Customer c1 = new Customer();c1.setId(1L);c1.setName("A");GregorianCalendar calendar = (GregorianCalendar) GregorianCalendar.getInstance();calendar.setTime(new SimpleDateFormat("yyyy-MM-dd").parse("1993-03-06"));c1.setBirthday(new XMLGregorianCalendarImpl(calendar));Customer c2 = new Customer();c2.setId(2L);c2.setName("B");calendar.setTime(new SimpleDateFormat("yyyy-MM-dd").parse("1993-04-06"));c2.setBirthday(new XMLGregorianCalendarImpl(calendar));SelectMaxAgeCustomer sma = new SelectMaxAgeCustomer();sma.setC2(c2);System.out.println(service.selectMaxAgeCustomer(sma,c1).getReturn().getName());}}

注意:

(1)IHelloService是生成客户端中包含的类,而不是我们自己创建的。

(2)客户端的IHelloService的第一个方法的第一个参数是SelectMaxAgeStudent,而不是 Customer

运行之后控制台输出如下语句:

信息: Inbound Message----------------------------ID: 1Address: http://localhost:8080/helloServiceEncoding: UTF-8Http-Method: POSTContent-Type: text/xml; charset=UTF-8Headers: {Accept=[*/*], Cache-Control=[no-cache], connection=[keep-alive], Content-Length=[449], content-type=[text/xml; charset=UTF-8], Host=[localhost:8080], Pragma=[no-cache], SOAPAction=[""], User-Agent=[Apache CXF 3.0.10]}Payload: <soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/"><soap:Header><ns2:c1 xmlns:ns2="http://service.inter.test.com/"><birthday>1993-03-06T00:00:00.000+08:00</birthday><id>1</id><name>A</name></ns2:c1></soap:Header><soap:Body><ns2:selectMaxAgeCustomer xmlns:ns2="http://service.inter.test.com/"><c2><birthday>1993-04-06T00:00:00.000+08:00</birthday><id>2</id><name>B</name></c2></ns2:selectMaxAgeCustomer></soap:Body></soap:Envelope>--------------------------------------十一月 24, 2016 3:36:14 下午 org.apache.cxf.services.HelloServiceImplService.HelloServiceImplPort.IHelloService1信息: Outbound Message---------------------------ID: 1Response-Code: 200Encoding: UTF-8Content-Type: text/xmlHeaders: {}Payload: <soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/"><soap:Body><ns2:selectMaxAgeCustomerResponse xmlns:ns2="http://service.inter.test.com/"><return><birthday>1993-03-06T00:00:00.000+08:00</birthday><id>1</id><name>A</name></return></ns2:selectMaxAgeCustomerResponse></soap:Body></soap:Envelope>--------------------------------------
我们注意到 Inbound Message 中的 SOAP 信封将第一个方法的第一个参数放在
<soap:Header … 中传输。








0 0
原创粉丝点击