加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 综合聚焦 > 服务器 > 安全 > 正文

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

发布时间:2020-12-17 01:01:27 所属栏目:安全 来源:网络整理
导读:一. 什么是QName 1 .来历:qname是qualified?name?的简写 2 .构成:由名字空间(namespace)前缀(prefix)以及冒号(:),还有一个元素名称构成 3 .举例: wsdl:definitions name =" Helloworld " targetNamespace =" http://server.com/ " xmlns:ns1 =" http://sc

一. 什么是QName


1 .来历:qname是qualified?name?的简写
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的类
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 ...");
	}
}
?
1.4 运行发布的类后,在IE中输入:http://localhost:9000/helloWorld?wsdl就可以看到如下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 不能写错,否则会导致调用时抛异常。

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读