`
huainansto
  • 浏览: 27563 次
  • 性别: Icon_minigender_1
  • 来自: 珠海
社区版块
存档分类
最新评论

web service

    博客分类:
  • CXF
阅读更多

CXF提供了wsdl2java方法, 使用wsdl文件生成java code

首先打开IDE创建个项目:

在项目文件夹中创建个目录wsdl, 把外来的wsdl放到里面去

打开命令行, cd 到wsdl文件的位置 运行wsdl2java -d ../src wsdl文件名 命令来生成java code

由于wsdl文件可以生成基础的java code, 也就是说客户端和服务器是可以解耦合的, 在客户端和服务器都可以生成相同的java code, 我们可以用这个wsdl文件作为通信的标准。

首先是hello_world.wsdl文件

 

<?xml version="1.0" encoding="UTF-8"?>
<wsdl:definitions name="HelloWorld" targetNamespace="http://apache.org/hello_world_xml_http/bare" 
		  xmlns="http://schemas.xmlsoap.org/wsdl/"
		  xmlns:http="http://schemas.xmlsoap.org/wsdl/http/"
		  xmlns:xformat="http://cxf.apache.org/bindings/xformat" 
		  xmlns:tns="http://apache.org/hello_world_xml_http/bare"
		  xmlns:x1="http://apache.org/hello_world_xml_http/bare/types"
		  xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/" 
		  xmlns:xsd="http://www.w3.org/2001/XMLSchema">
    
    <wsdl:types>
	<schema targetNamespace="http://apache.org/hello_world_xml_http/bare/types" 
		xmlns="http://www.w3.org/2001/XMLSchema" 
		elementFormDefault="qualified">

	    <element name="responseType" type="xsd:string"/>
	    <element name="requestType" type="xsd:string"/>      
	    <element name="myComplexStruct" type="x1:myComplexStructType"/>     
	    
	    <complexType name="myComplexStructType">
		<sequence>
		    <element name="elem1" type="xsd:string"/>
		    <element name="elem2" type="xsd:string"/>
		    <element name="elem3" type="xsd:int"/>
		</sequence>
	    </complexType>
	</schema>
    </wsdl:types>
    
    <wsdl:message name="sayHiRequest"/>
    
    <wsdl:message name="sayHiResponse">
	<wsdl:part type="xsd:string" name="out"/>
    </wsdl:message>
    
    <wsdl:message name="greetMeRequest">
	<wsdl:part element="x1:requestType" name="me"/>
    </wsdl:message>
    
    <wsdl:message name="greetMeResponse">
	<wsdl:part element="x1:responseType" name="theResponse"/>
    </wsdl:message>
    
    <wsdl:message name="sendReceiveDataRequest">
	<wsdl:part type="x1:myComplexStructType" name="in"/>
    </wsdl:message>
    
    <wsdl:message name="sendReceiveDataResponse">
	<wsdl:part type="x1:myComplexStructType" name="out"/>
    </wsdl:message>

    <wsdl:message name="multiParamPartRequest">
	<wsdl:part element="x1:requestType" name="in1"/>
	<wsdl:part element="x1:myComplexStruct" name="in2"/>
    </wsdl:message>
    
    <wsdl:message name="multiParamPartResponse">
	<wsdl:part element="x1:responseType" name="out1"/>
    </wsdl:message>

    <wsdl:portType name="Greeter">
	<wsdl:operation name="sayHi">
	    <wsdl:input message="tns:sayHiRequest" name="sayHiRequest"/>
	    <wsdl:output message="tns:sayHiResponse" name="sayHiResponse"/>
	</wsdl:operation>
	<wsdl:operation name="greetMe">
	    <wsdl:input message="tns:greetMeRequest" name="greetMeRequest"/>
	    <wsdl:output message="tns:greetMeResponse" name="greetMeResponse"/>
	</wsdl:operation>
	<wsdl:operation name="sendReceiveData">
	    <wsdl:input message="tns:sendReceiveDataRequest" name="SendReceiveDataRequest"/>
	    <wsdl:output message="tns:sendReceiveDataResponse" name="SendReceiveDataResponse"/>
	</wsdl:operation>
	<wsdl:operation name="testMultiParamPart" parameterOrder="in2 in1">
	    <wsdl:input message="tns:multiParamPartRequest" name="multiParamPartRequest"/>
	    <wsdl:output message="tns:multiParamPartResponse" name="multiParamPartResponse"/>
	</wsdl:operation>
    </wsdl:portType>
    
    <wsdl:binding name="Greeter_XMLBinding" type="tns:Greeter">

	<xformat:binding/>

	<wsdl:operation name="sayHi">
	    <wsdl:input>
		<xformat:body rootNode="tns:sayHi"/>
	    </wsdl:input>
	    <wsdl:output/>
	</wsdl:operation>
	
	<wsdl:operation name="greetMe">
	    <wsdl:input/>
	    <wsdl:output/>
	</wsdl:operation>
	
	<wsdl:operation name="sendReceiveData">
	    <wsdl:input/>
	    <wsdl:output/>
	</wsdl:operation>

	<wsdl:operation name="testMultiParamPart">
	    <wsdl:input>
		<xformat:body rootNode="tns:multiParamRootReq"/>
	    </wsdl:input>
	    <wsdl:output/>
	</wsdl:operation>

    </wsdl:binding>
    
    <wsdl:service name="XMLService">
	<wsdl:port binding="tns:Greeter_XMLBinding" name="XMLPort">
	    <http:address location="http://localhost:9000/XMLService/XMLPort"/>
	</wsdl:port>
    </wsdl:service>
</wsdl:definitions>

 

从这个wsdl中可以看到,需要把它发布成XMLService的服务,port为:XMLPort

这样就可以用QName来获得关于Greeter接口的实例在客户端就可以访问这个接口中的方法, 如同在服务器端访问一样。

 

接着就是编写服务器程序, 然后把它发布出去。

GreeterImpl.java 实现了Greeter接口

 

package demo.server;

import javax.jws.WebService;
import javax.xml.ws.BindingType;

import org.apache.hello_world_xml_http.bare.Greeter;
import org.apache.hello_world_xml_http.bare.types.MyComplexStructType;

@WebService(serviceName="XMLService",
		portName="XMLPort",
		endpointInterface="org.apache.hello_world_xml_http.bare.Greeter",
		targetNamespace="http://apache.org/hello_world_xml_http/bare")
		
@BindingType(value="http://cxf.apache.org/bindings/xformat")
public class GreeterImpl implements Greeter
{

	@Override
	public String greetMe(String me) 
	{
		System.out.println("received calling greetMe!");
		return "Hello " + me;
	}

	@Override
	public String sayHi() 
	{
		System.out.println("received calling sayHi");
		return "say Hi to Bonjour";
	}

	@Override
	public MyComplexStructType sendReceiveData(MyComplexStructType in) 
	{
		System.out.println("received calling sendReceiveData");
		return in;
	}

	@Override
	public String testMultiParamPart(MyComplexStructType in2, String in1) 
	{
		System.out.println("received calling testMultiParamPart");
		in2.setElem1(in1);
		return "Bonjour";
	}

}

  通过j2se的 Endpoint来发布这个web service

 package demo.server;

import javax.xml.ws.Endpoint;

public class Server {

	protected Server() throws Exception
	{
		System.out.println("Starting Server");
		
		Object implementor = new GreeterImpl();
		String address = "http://localhost:9000/XMLService/XMLPort";
		Endpoint.publish(address, implementor);
	}
	
	public static void main(String[] args) throws Exception
	{
		new Server();
		System.out.println("Server ready...");
		
		Thread.sleep(5*60*1000);
		System.out.println("Server exiting");
		System.exit(0);
	}
}

 

  web service发布成功,我们可以通过http://localhost:9000/XMLService/XMLPort?wsdl来看看发布出来的wsdl,然后编写客户端程序来测试是否能成功调用发布的web service服务。

 

package demo.client;

import java.io.File;
import java.net.URL;

import javax.xml.namespace.QName;

import org.apache.hello_world_xml_http.bare.Greeter;
import org.apache.hello_world_xml_http.bare.XMLService;
import org.apache.hello_world_xml_http.bare.types.MyComplexStructType;

public class Client 
{
	private static final QName SERVICE_NAME = new QName("http://apache.org/hello_world_xml_http/bare", "XMLService");
	private static final QName PORT_NAME = new QName("http://apache.org/hello_world_xml_http/bare", "XMLPort");
	
	public static void main(String[] args) throws Exception
	{
		File wsdlFile = new File("wsdl/hello_world.wsdl");
		URL wsdlURL = wsdlFile.toURL();
		System.out.println(wsdlURL);
		
		XMLService service = new XMLService(wsdlURL, SERVICE_NAME);
		Greeter greeter = (Greeter) service.getPort(PORT_NAME, Greeter.class);
		
		System.out.println("Invoking sayHi...");
        System.out.println("server responded with: " + greeter.sayHi());
        System.out.println();

        System.out.println("Invoking greetMe...");
        System.out.println("server responded with: " + greeter.greetMe(System.getProperty("user.name")));
        System.out.println();

        MyComplexStructType argument = new MyComplexStructType();
        MyComplexStructType retVal = null;

        String str1 = "this is element 1";
        String str2 = "this is element 2";
        int int1 = 42;

        argument.setElem1(str1);
        argument.setElem2(str2);
        argument.setElem3(int1);
        System.out.println("Invoking sendReceiveData...");

        retVal = greeter.sendReceiveData(argument);

        System.out.println("Response from sendReceiveData operation :");
        System.out.println("Element-1 : " + retVal.getElem1());
        System.out.println("Element-2 : " + retVal.getElem2());
        System.out.println("Element-3 : " + retVal.getElem3());
        System.out.println();

        System.exit(0);
	}
}

 

运行客户端程序,我们可以看到程序输出:

服务器端:

Server ready... received calling sayHi received calling greetMe! received calling sendReceiveData

客户端:

 

Invoking sayHi...

server responded with: say Hi to Bonjour

 

Invoking greetMe...

server responded with: Hello fengye

 

Invoking sendReceiveData...

Response from sendReceiveData operation :

Element-1 : this is element 1

Element-2 : this is element 2

Element-3 : 42

 

这里面还涉及到对象的传递,这个迟点再讨论。

在这里传递的非基础类型MyComplexStructType

首先看看wsdl文件中的定义,

 

 <element name="myComplexStruct" type="x1:myComplexStructType"/>     
	    
	    <complexType name="myComplexStructType">
		<sequence>
		    <element name="elem1" type="xsd:string"/>
		    <element name="elem2" type="xsd:string"/>
		    <element name="elem3" type="xsd:int"/>
		</sequence>
	    </complexType>

 

 以及命名空间x1的定义,xmlns:x1="http://apache.org/hello_world_xml_http/bare/types"

 在生成的java code中 在包org.apache.hello_world_xml_http.types下的MyComplexStructType.java类

 

 

@XmlAccessorType(XmlAccessType.FIELD)         -------JAXB 绑定类中的每个非静态、非瞬态字段将会自动绑定到 XML,除非由 XmlTransient
注释
@XmlType(name = "myComplexStructType", propOrder = {
    "elem1",
    "elem2",
    "elem3"
})
public class MyComplexStructType {

    @XmlElement(required = true)
    protected String elem1;
    @XmlElement(required = true)
    protected String elem2;
    protected int elem3;
    
    ...get set方法     //通过get set方法设置类成员字段
}
再看看@XmlType这个注释,在jdk API文档中有个例子
@XmlType(propOrder={"street", "city" , "state", "zip", "name" })
   public class USAddress {
     String getName() {..};
     void setName(String) {..};
 
     String getStreet() {..};
     void setStreet(String) {..};

     String getCity() {..}; 
     void setCity(String) {..};
 
     String getState() {..};
     void setState(String) {..};

     java.math.BigDecimal getZip() {..};
     void setZip(java.math.BigDecimal) {..};
   }
对应的映射xml为
<!-- XML Schema mapping for USAddress -->
   <complextype name="USAddress"><sequence><element name="street" type="xs:string"></element><element name="city" type="xs:string"></element><element name="state" type="xs:string"></element><element name="zip" type="xs:decimal"></element><element name="name" type="xs:string"></element></sequence></complextype>
再看CXF的文档, JAXB is the default data binding for CXF。这样MyComplexStructType对象就可以按照xml来传递了。
分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics