CXF-07: CXF 的本质,解析 SOAP 文档

 - Web Service的调用的本质:

        (1)客户端把需要调用的参数,转换为XML文档片段(SOAP消息,input);

        (2)客户端通过网络把XML文档片段传给远程服务器;
        (3)服务器接收XML文档片段;
        (4)服务器解析XML文档片段,提取其中的数据,并把数据转换为调用所需的参数;
        (5)服务器执行方法;
        (6)得到方法返回值,服务器把方法返回值,转换为XML文档片段(SOAP消息,output);
        (7)服务器通过网络把XML文档片段传给远程客户端;
        (8)客户端接收XML文档片段;
        (9)客户端解析XML文档片段,提取其中的数据,并把数据转换为调用返回值;
 - Web Service的三个技术基础:
        - WSDL
                Web Service接口
                        1 . types元素(标准的Schema)
                        2 . 2N个message元素
                        3 . portType元素 - N个operation
                Web Service实现
                        1 . binding元素 - N个更详细的operation
                        2 . service元素 - 指定Web Service的服务地址
        - SOAP
                Header元素
                        Header元素不是强制出现的,由程序员控制添加;
                Body元素
                        Body元素总是默认的。Body元素里有两种情况:
                        ——当Web Service交互正确时,Body元素里的内容由WSDL控制;

                        ——当Web Service交互出错时,Body元素的内容将是Fault子元素;

         

        

         

        1 . 如果调用正确(Web Service交互成功),Body元素的内容应该遵守WSDL所要求的格式。

传入消息Inbound Message:
<?xml version="1.0" ?>
<S:Envelope xmlns:S="http://schemas.xmlsoap.org/soap/envelope/">
	<S:Body>
		<ns2:getAllFoods xmlns:ns2="http://ws.cxf.fjava.org/"/>
	</S:Body>
</S:Envelope>
传出消息Outbound Message:
<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">
	<soap:Body>
		<ns2:getAllFoodsResponse xmlns:ns2="http://ws.cxf.fjava.org/">
			<return>
				<entries>
					<key>蟹王汉堡</key>
					<value>
						<describe>橙色,亮金色,我的宝贝,我的爱!</describe>
						<id>3</id>
						<name>蟹王汉堡</name>
					</value>
				</entries>
				<entries>
					<key>海绵金币</key>
					<value>
						<describe>吃着金币样的甜甜饼,想着海绵宝宝赚的钱被扣了,哈哈哈,爽气!</describe>
						<id>4</id>
						<name>海绵金币</name>
					</value>
				</entries>
				<entries>
					<key>一个汉堡</key>
					<value>
						<describe>是三层的,有夹层哦!</describe>
						<id>1</id>
						<name>一个汉堡</name>
					</value>
				</entries>
				<entries>
					<key>火腿肠</key>
					<value>
						<describe>这是章鱼哥从岸上偷运来的,据说很美味!</describe>
						<id>2</id>
						<name>火腿肠</name>
					</value>
				</entries>
			</return>
		</ns2:getAllFoodsResponse>
	</soap:Body>
</soap:Envelope>
         2 . 若调用错误(Web Service交互出错),Body元素的内容就是Fault子元素

调用结果:http://192.168.0.159:6786/sayHello
<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">
	<soap:Body>
		<soap:Fault>
			<faultcode>soap:Server</faultcode>
			<faultstring>
					No such operation: (HTTP GET PATH_INFO: /sayHello)
			</faultstring>
		</soap:Fault>
	</soap:Body>
</soap:Envelope>
调用错误:下面异常不是服务端异常,是想调用这个操作,没有这个操作
警告: Interceptor for {http://impl.ws.cxf.fjava.org/}HelloWorldWs has thrown exception, unwinding now
org.apache.cxf.interceptor.Fault: No such operation:  (HTTP GET PATH_INFO: /sayHello)
	at org.apache.cxf.interceptor.URIMappingInterceptor.handleMessage(URIMappingInterceptor.java:88)
	at org.apache.cxf.phase.PhaseInterceptorChain.doIntercept(PhaseInterceptorChain.java:263)
	at org.apache.cxf.transport.ChainInitiationObserver.onMessage(ChainInitiationObserver.java:118)
	at org.apache.cxf.transport.http_jetty.JettyHTTPDestination.serviceRequest(JettyHTTPDestination.java:318)
	at org.apache.cxf.transport.http_jetty.JettyHTTPDestination.doService(JettyHTTPDestination.java:286)
	at org.apache.cxf.transport.http_jetty.JettyHTTPHandler.handle(JettyHTTPHandler.java:72)
	at org.eclipse.jetty.server.handler.ContextHandler.doHandle(ContextHandler.java:939)
	at org.eclipse.jetty.server.handler.ContextHandler.doScope(ContextHandler.java:875)
	at org.eclipse.jetty.server.handler.ScopedHandler.handle(ScopedHandler.java:117)
	at org.eclipse.jetty.server.handler.ContextHandlerCollection.handle(ContextHandlerCollection.java:247)
	at org.eclipse.jetty.server.handler.HandlerWrapper.handle(HandlerWrapper.java:110)
	at org.eclipse.jetty.server.Server.handle(Server.java:346)
	at org.eclipse.jetty.server.HttpConnection.handleRequest(HttpConnection.java:589)
	at org.eclipse.jetty.server.HttpConnection$RequestHandler.headerComplete(HttpConnection.java:1048)
	at org.eclipse.jetty.http.HttpParser.parseNext(HttpParser.java:601)
	at org.eclipse.jetty.http.HttpParser.parseAvailable(HttpParser.java:214)
	at org.eclipse.jetty.server.HttpConnection.handle(HttpConnection.java:411)
	at org.eclipse.jetty.io.nio.SelectChannelEndPoint.handle(SelectChannelEndPoint.java:535)
	at org.eclipse.jetty.io.nio.SelectChannelEndPoint$1.run(SelectChannelEndPoint.java:40)
	at org.eclipse.jetty.util.thread.QueuedThreadPool$3.run(QueuedThreadPool.java:529)
	at java.lang.Thread.run(Thread.java:745)

        对比WSDL发现,SOAP(Simple Object Access Protocol - 简单对象协议)实际就是WSDL(Web Service Definition Language  - Web Service 定义语言)传入消息、传出消息的具体实现,好比是WSDL是接口,SOAP是实现类!

希望对你有帮助,祝你有一个好心情,加油!

若有错误、不全、可优化的点,欢迎纠正与补充;转载请注明出处!



  • 2
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
您好,将CXF SOAP消息中的Header转换成SOAP-ENV:Header可以通过以下步骤实现: 1. 获取CXF SOAP消息的Header部分。 2. 创建一个新的SOAP消息,并设置命名空间为“http://schemas.xmlsoap.org/soap/envelope/”。 3. 创建一个SOAP-ENV:Header元素,并将其添加到新创建的SOAP消息中。 4. 将CXF SOAP消息的Header部分添加到SOAP-ENV:Header元素中。 5. 将新创建的SOAP消息作为输出,即可得到将CXF SOAP消息中的Header转换成SOAP-ENV:Header的结果。 下面是一个示例代码: ```java // 获取CXF SOAP消息的Header部分 SOAPMessage cxfSoapMessage = ...; SOAPHeader cxfSoapHeader = cxfSoapMessage.getSOAPHeader(); // 创建新的SOAP消息 MessageFactory messageFactory = MessageFactory.newInstance(SOAPConstants.SOAP_1_1_PROTOCOL); SOAPMessage newSoapMessage = messageFactory.createMessage(); newSoapMessage.getSOAPPart().getEnvelope().addNamespaceDeclaration("soapenv", "http://schemas.xmlsoap.org/soap/envelope/"); // 创建SOAP-ENV:Header元素 SOAPHeaderElement soapHeaderElement = newSoapMessage.getSOAPHeader().addHeaderElement(new QName("http://schemas.xmlsoap.org/soap/envelope/", "Header", "soapenv")); // 将CXF SOAP消息的Header部分添加到SOAP-ENV:Header元素中 Iterator<SOAPElement> iterator = cxfSoapHeader.getChildElements(); while (iterator.hasNext()) { SOAPElement soapElement = iterator.next(); soapHeaderElement.addChildElement(soapElement); } // 输出SOAP消息 newSoapMessage.writeTo(System.out); ``` 希望能帮到您!

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值