QName HelloWorld ---记CXF中QName的使用

一. 什么是QName


1 .来历:qname是qualifiedname的简写
2 .构成:由名字空间(namespace)前缀(prefix)以及冒号(:),还有一个元素名称构成
3 .举例:
<wsdl:definitions name="Helloworld" targetNamespace="http://server.com/" xmlns:ns1="http://schemas.xmlsoap.org/soap/http" xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/" xmlns:tns="http://server.com/" xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
.....
<wsdl:portTypename="IHelloWorldService">
<wsdl:operation name="sayHello">
<wsdl:inputmessage="tns:sayHello" name="sayHello" />
<wsdl:outputmessage="tns:sayHelloResponse" name="sayHelloResponse" />
</wsdl:operation>
</wsdl:portType>
</wsdl:definitions>
wsdl:portType 为例:wsdl是名字空间前缀,portTpye是元素名称,wsdl:portType就是一个qname,其namespace是:http://server.com/

二. QName在CXF中的使用

直接上代码,我使用的是apache-cxf-2.4.6.

服务器端(注意我测试的时候service接口,service实现类 和发布service的类放在同一包里,实际使用过程中可以放在不同的包里)

1. 服务器端代码:

1.1 service接口

package com.server; import javax.jws.WebParam; import javax.jws.WebService; @WebService public interface IHelloWorldService { public String sayHello(@WebParam(name="text") String name); }1.2 service 实现类package com.server; import javax.jws.WebService; @WebService(serviceName="Helloworld") public class HelloWorldService implements IHelloWorldService{ public String sayHello( String name){ return name + "say : Hello Service."; } }1.3 发布service的类<pre class="java" name="code">package com.server; import javax.xml.ws.Endpoint; public class DeployHelloWorldService { public static void main(String[] args) throws Exception{ IHelloWorldService service = new HelloWorldService(); String address = "http://localhost:9000/helloWorld"; Endpoint.publish(address, service); System.out.println("service ready ..."); } }</pre>1.4 运行发布的类后,在IE中输入:<a href="http://localhost:9000/helloWorld?wsdl" mce_href="http://localhost:9000/helloWorld?wsdl">http://localhost:9000/helloWorld?wsdl</a>就可以看到如下wsdl:

<?xml version="1.0" encoding="UTF-8" ?> - <wsdl:definitions name="Helloworld" targetNamespace="http://server.com/" xmlns:ns1="http://schemas.xmlsoap.org/soap/http" xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/" xmlns:tns="http://server.com/" xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/" xmlns:xsd="http://www.w3.org/2001/XMLSchema"> - <wsdl:types> - <xs:schema elementFormDefault="unqualified" targetNamespace="http://server.com/" version="1.0" xmlns:tns="http://server.com/" xmlns:xs="http://www.w3.org/2001/XMLSchema"> <xs:element name="sayHello" type="tns:sayHello" /> <xs:element name="sayHelloResponse" type="tns:sayHelloResponse" /> - <xs:complexType name="sayHello"> - <xs:sequence> <xs:element minOccurs="0" name="text" type="xs:string" /> </xs:sequence> </xs:complexType> - <xs:complexType name="sayHelloResponse"> - <xs:sequence> <xs:element minOccurs="0" name="return" type="xs:string" /> </xs:sequence> </xs:complexType> </xs:schema> </wsdl:types> - <wsdl:message name="sayHelloResponse"> <wsdl:part element="tns:sayHelloResponse" name="parameters" /> </wsdl:message> - <wsdl:message name="sayHello"> <wsdl:part element="tns:sayHello" name="parameters" /> </wsdl:message> - <wsdl:portType name="IHelloWorldService"> - <wsdl:operation name="sayHello"> <wsdl:input message="tns:sayHello" name="sayHello" /> <wsdl:output message="tns:sayHelloResponse" name="sayHelloResponse" /> </wsdl:operation> </wsdl:portType> - <wsdl:binding name="HelloworldSoapBinding" type="tns:IHelloWorldService"> <soap:binding style="document" transport="http://schemas.xmlsoap.org/soap/http" /> - <wsdl:operation name="sayHello"> <soap:operation soapAction="" style="document" /> - <wsdl:input name="sayHello"> <soap:body use="literal" /> </wsdl:input> - <wsdl:output name="sayHelloResponse"> <soap:body use="literal" /> </wsdl:output> </wsdl:operation> </wsdl:binding> - <wsdl:service name="Helloworld"> - <wsdl:port binding="tns:HelloworldSoapBinding" name="HelloWorldServicePort"> <soap:address location="http://localhost:9000/helloWorld" /> </wsdl:port> </wsdl:service> </wsdl:definitions>


 

2. 客户端使用QName调用WebService的代码

package client; import javax.xml.namespace.QName; import javax.xml.ws.Service; import javax.xml.ws.soap.SOAPBinding; import com.server.IHelloWorldService; public class HelloWorldServiceClient { /** * namespaceURI即为:wsdl:definitions name="Helloworld" targetNamespace="http://server.com/"... * 中的targetNamespace. * 如果服务器端的service接口和类不在同一个包中时: * namespaceURI即为wsdl:import中的namespace * <wsdl:import location="http://localhost:9000/helloWorld?wsdl=IHelloWorldService.wsdl" namespace="http://inter.server.com/" /> */ private static String namespaceURI = "http://server.com/"; private static final QName SERVICE_NAME = new QName(namespaceURI,"IHelloWorldService"); private static final QName PORT_NAME = new QName(namespaceURI,"IHelloWorldServicePort"); public static void main(String[] args) { Service service = Service.create(SERVICE_NAME); String endpointAddress = "http://localhost:9000/helloWorld"; service.addPort(PORT_NAME, SOAPBinding.SOAP11HTTP_BINDING, endpointAddress); IHelloWorldService clientService = service.getPort(IHelloWorldService.class); String result = clientService.sayHello("hello QName"); System.out.println(result); } }


运行该类就可以通过QName调用到Server端的service

 

注意以下几点:

2.1 namespaceURI 为:wsdl:definitions中的targetNamespace的值,在本例中就是http://server.com/

2.2.serviceName 为: wdsl中的IHelloWorldService对对应的portType 的name ,使用<wsdl:service name="Helloworld">中的Helloworld也可以,具体原因也说不上来。serviceName使用其他错误的值,该程序

也可以正常运行,搞不懂了。

2.3.protName 为wdsl中的IHelloWorldService对对应的portType 的name + “Port”即IHelloWorldServicePort,我估计之所以这么使用是因为客户端是通过IHelloWorldService调用的原因。
使用Helloworld
Port会抛异常:

“Caused by: java.net.MalformedURLException: Invalid address. Endpoint address cannot be null.”
这个PortName也不是<wsdl:port binding="tns:HelloworldSoapBinding" name="HelloWorldServicePort"> 中的HelloWorldServicePort,如果使用HelloWorldServicePort也回抛出上面的异常。

总结一点,在使用QName的过程中nameSpaceUrl 和PortName 不能写错,否则会导致调用时抛异常。

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
CXF,可以使用JAX-WS规范提供的Handler机制在客户端对SOAP请求包注入header。具体步骤如下: 1. 创建一个类实现javax.xml.ws.handler.Handler接口,该接口定义了处理SOAP消息的方法,其最重要的方法是handleMessage()方法。 2. 在handleMessage()方法,可以使用Java提供的SOAP API为SOAP消息添加header。 3. 在CXF客户端的配置文件,通过配置文件指定handler链,将创建的handler添加到handler链。 下面是一个示例代码: ```java public class HeaderHandler implements SOAPHandler<SOAPMessageContext> { public boolean handleMessage(SOAPMessageContext context) { Boolean outboundProperty = (Boolean) context.get(MessageContext.MESSAGE_OUTBOUND_PROPERTY); if (outboundProperty.booleanValue()) { try { SOAPEnvelope envelope = context.getMessage().getSOAPPart().getEnvelope(); SOAPHeader header = envelope.getHeader(); if (header == null) { header = envelope.addHeader(); } // 添加header内容 QName qname = new QName("http://www.example.org/header", "auth", "ns"); SOAPHeaderElement headerElement = header.addHeaderElement(qname); headerElement.setActor(SOAPConstants.URI_SOAP_ACTOR_NEXT); headerElement.addTextNode("username:password"); } catch (Exception e) { e.printStackTrace(); } } return true; } public Set<QName> getHeaders() { return null; } public boolean handleFault(SOAPMessageContext context) { return true; } public void close(MessageContext context) { } } ``` 在CXF客户端的配置文件添加handler链: ```xml <jaxws:client id="helloClient" serviceClass="com.example.HelloWorld" address="http://localhost:9000/helloWorld"> <jaxws:handlers> <bean class="com.example.HeaderHandler"/> </jaxws:handlers> </jaxws:client> ``` 在上面的示例,HeaderHandler类实现了javax.xml.ws.handler.Handler接口,并在handleMessage()方法添加了header内容。在客户端的配置文件,通过添加handler链,将HeaderHandler添加到handler链。这样,当客户端发送SOAP请求时,CXF会将SOAP消息传递给handler链的每个handler进行处理,最终将处理后的SOAP消息发送给服务端。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值