`

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接口

Java代码 复制代码
  1. package com.server;   
  2.   
  3. import javax.jws.WebParam;   
  4. import javax.jws.WebService;   
  5.   
  6. @WebService  
  7. public interface IHelloWorldService {   
  8.        
  9.     public String sayHello(@WebParam(name="text") String name);   
  10.        
  11. }  

Java代码 复制代码
  1.   

Java代码 复制代码
  1. 1.2 service 实现类  

Java代码 复制代码
  1. package com.server;   
  2. import javax.jws.WebService;   
  3.   
  4. @WebService(serviceName="Helloworld")   
  5. public class HelloWorldService implements IHelloWorldService{   
  6.        
  7.     public String sayHello( String name){   
  8.         return name + "say : Hello Service.";   
  9.     }   
  10. }  

Java代码 复制代码
  1. 1.3 发布service的类  

Java代码 复制代码
  1. <pre class="java" name="code">package com.server;   
  2. import javax.xml.ws.Endpoint;   
  3.   
  4. public class DeployHelloWorldService {   
  5.        
  6.     public static void main(String[] args) throws Exception{   
  7.             IHelloWorldService service = new HelloWorldService();   
  8.             String address = "http://localhost:9000/helloWorld";   
  9.             Endpoint.publish(address, service);   
  10.             System.out.println("service ready ...");   
  11.     }   
  12. }</pre>  

Java代码 复制代码
  1.   

Java代码 复制代码
  1. 1.4 运行发布的类后,在IE中输入:<a href="http://localhost:9000/helloWorld?wsdl" mce_href="http://localhost:9000/helloWorld?wsdl">http://localhost:9000/helloWorld?wsdl</a>就可以看到如下wsdl:  

Java代码 复制代码
  1.   

 

Html代码 复制代码
  1. <?xml version="1.0" encoding="UTF-8" ?>    
  2. <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">  
  3. <wsdl:types>  
  4. <xs:schema elementFormDefault="unqualified" targetNamespace="http://server.com/" version="1.0" xmlns:tns="http://server.com/" xmlns:xs="http://www.w3.org/2001/XMLSchema">  
  5.   <xs:element name="sayHello" type="tns:sayHello" />    
  6.   <xs:element name="sayHelloResponse" type="tns:sayHelloResponse" />    
  7. <xs:complexType name="sayHello">  
  8. <xs:sequence>  
  9.   <xs:element minOccurs="0" name="text" type="xs:string" />    
  10.   </xs:sequence>  
  11.   </xs:complexType>  
  12. <xs:complexType name="sayHelloResponse">  
  13. <xs:sequence>  
  14.   <xs:element minOccurs="0" name="return" type="xs:string" />    
  15.   </xs:sequence>  
  16.   </xs:complexType>  
  17.   </xs:schema>  
  18.   </wsdl:types>  
  19. <wsdl:message name="sayHelloResponse">  
  20.   <wsdl:part element="tns:sayHelloResponse" name="parameters" />    
  21.   </wsdl:message>  
  22. <wsdl:message name="sayHello">  
  23.   <wsdl:part element="tns:sayHello" name="parameters" />    
  24.   </wsdl:message>  
  25. <wsdl:portType name="IHelloWorldService">  
  26. <wsdl:operation name="sayHello">  
  27.   <wsdl:input message="tns:sayHello" name="sayHello" />    
  28.   <wsdl:output message="tns:sayHelloResponse" name="sayHelloResponse" />    
  29.   </wsdl:operation>  
  30.   </wsdl:portType>  
  31. <wsdl:binding name="HelloworldSoapBinding" type="tns:IHelloWorldService">  
  32.   <soap:binding style="document" transport="http://schemas.xmlsoap.org/soap/http" />    
  33. <wsdl:operation name="sayHello">  
  34.   <soap:operation soapAction="" style="document" />    
  35. <wsdl:input name="sayHello">  
  36.   <soap:body use="literal" />    
  37.   </wsdl:input>  
  38. <wsdl:output name="sayHelloResponse">  
  39.   <soap:body use="literal" />    
  40.   </wsdl:output>  
  41.   </wsdl:operation>  
  42.   </wsdl:binding>  
  43. <wsdl:service name="Helloworld">  
  44. <wsdl:port binding="tns:HelloworldSoapBinding" name="HelloWorldServicePort">  
  45.   <soap:address location="http://localhost:9000/helloWorld" />    
  46.   </wsdl:port>  
  47.   </wsdl:service>  
  48.   </wsdl:definitions>  

 


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

Java代码 复制代码
  1. package client;   
  2.   
  3. import javax.xml.namespace.QName;   
  4. import javax.xml.ws.Service;   
  5. import javax.xml.ws.soap.SOAPBinding;   
  6.   
  7. import com.server.IHelloWorldService;   
  8.   
  9. public class HelloWorldServiceClient {   
  10.     /**  
  11.      * namespaceURI即为:wsdl:definitions name="Helloworld" targetNamespace="http://server.com/"...  
  12.      * 中的targetNamespace.   
  13.      * 如果服务器端的service接口和类不在同一个包中时:  
  14.      * namespaceURI即为wsdl:import中的namespace  
  15.      *  <wsdl:import location="http://localhost:9000/helloWorld?wsdl=IHelloWorldService.wsdl"      namespace="http://inter.server.com/" />   
  16.      */  
  17.     private static String namespaceURI = "http://server.com/";    

Java代码 复制代码
  1. private static final QName SERVICE_NAME = new QName(namespaceURI,"IHelloWorldService");   

Java代码 复制代码
  1.   private static final QName PORT_NAME = new QName(namespaceURI,"IHelloWorldServicePort");    
  2.   public static void main(String[] args) {   
  3. Service service = Service.create(SERVICE_NAME);      
  4. String endpointAddress = "http://localhost:9000/helloWorld";   
  5. service.addPort(PORT_NAME, SOAPBinding.SOAP11HTTP_BINDING, endpointAddress);   
  6. IHelloWorldService clientService = service.getPort(IHelloWorldService.class);   
  7. String result = clientService.sayHello("hello QName");   
  8. System.out.println(result);   
  9.   }   

 


运行该类就可以通过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 不能写错,否则会导致调用时抛异常。

分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics