使用JDK自帶的WebService

WebService是個好東西,話很少說,乾淨利落java

服務器端web

來看下服務器端的結構:shell

先定義一個接口,用於暴露:
瀏覽器

package com.abc.webservice;
/**
 * 對外暴露的接口。
 */
public interface IWebService {
    public String hello(String who);
}

再定義這個接口的實現類:
服務器

package com.abc.webservice.impl;

import javax.jws.WebService;
import com.abc.webservice.IWebService;

/**
 * wsdl:portType: MyService
 * wsdl:service: MyWebService
 */
@WebService(name="MyService",
            serviceName="MyWebService",
            targetNamespace="http://www.abc.com")
public class WebServiceImpl implements IWebService {
    @Override
    public String hello(String who) {
        return "Hello " + who + "!";
    }
}

注意這裏的name,它表示app

The name of the Web Service. Used as the name of the wsdl:portType when mapped to WSDL 1.1.ide

serviceName,它表示spa

The service name of the Web Service. Used as the name of the wsdl:service when mapped to WSDL 1.1. 命令行

targetNamespace,就是你爲Java客戶端生成的代碼的包名啦,生成的包名會自動反過來寫,好比上面的是www.abc.com,生成的包名則會爲package com.abc.* 。代理

最後將WebService發佈出去:

package com.abc.webservice;

import javax.xml.ws.Endpoint;
import com.abc.webservice.impl.WebServiceImpl;

/**
 * 發佈WebService
 */
public class Publisher {
    public static void main(String[] args) {
        System.out.println("Start publish service");
        Endpoint.publish("http://localhost:8080/MyService", new WebServiceImpl());
        System.out.println("End publish service");
    }
}

這以後,能夠打開瀏覽器,輸入剛剛發佈的URL:http://localhost:8080/MyService,去看看效果了:

點擊上圖中的超連接,能夠看到生成的wsdl,如下是生成的wsdl:

<?xml version="1.0" encoding="UTF-8"?>
<definitions
	xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd"
	xmlns:wsp="http://www.w3.org/ns/ws-policy" 
	xmlns:wsp1_2="http://schemas.xmlsoap.org/ws/2004/09/policy"
	xmlns:wsam="http://www.w3.org/2007/05/addressing/metadata" 
	xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/"
	xmlns:tns="http://www.abc.com" 
	xmlns:xsd="http://www.w3.org/2001/XMLSchema"
	xmlns="http://schemas.xmlsoap.org/wsdl/" 
	targetNamespace="http://www.abc.com"
	name="MyWebService">
	<types>
		<xsd:schema>
			<xsd:import namespace="http://www.abc.com"
				schemaLocation="http://localhost:8080/MyService?xsd=1" />
		</xsd:schema>
	</types>
	<message name="hello">
		<part name="parameters" element="tns:hello" />
	</message>
	<message name="helloResponse">
		<part name="parameters" element="tns:helloResponse" />
	</message>
	<portType name="MyService">
		<operation name="hello">
			<input wsam:Action="http://www.abc.com/MyService/helloRequest"
				message="tns:hello" />
			<output wsam:Action="http://www.abc.com/MyService/helloResponse"
				message="tns:helloResponse" />
		</operation>
	</portType>
	<binding name="MyServicePortBinding" type="tns:MyService">
		<soap:binding transport="http://schemas.xmlsoap.org/soap/http"
			style="document" />
		<operation name="hello">
			<soap:operation soapAction="" />
			<input>
				<soap:body use="literal" />
			</input>
			<output>
				<soap:body use="literal" />
			</output>
		</operation>
	</binding>
	<service name="MyWebService">
		<port name="MyServicePort" binding="tns:MyServicePortBinding">
			<soap:address location="http://localhost:8080/MyService" />
		</port>
	</service>
</definitions>

看不懂不要緊啦,這是WSDL,屬於另外一個範疇了,須要瞭解的朋友能夠去搜一搜相關的資料。這裏只是想說明如何使用JDK自帶的WebService啦。

Java客戶端

固然,WebServices能夠被Java客戶端調用,也能夠被非Java語言的程序調用,這裏咱們只看Java客戶端是如何調用的。

新建一個Poject,用於模擬在另外一臺機器上的客戶端,並打開命令行:

>cd D:\Workspace\WebServiceClient\src

使用JDK自帶的wsimport命令,生成Java客戶端(注意中間有個點,表示當前目錄):

>wsimport -keep . http://localhost:8080/MyService?wsdl

這句話表示生成客戶端代碼,保存在當前文件夾下。

會生成如下結構的客戶端代碼(圖中選中的部分,那個webservice包是本身建的),剛剛有提到生成的Java客戶端代碼會放在com.abc包下

至於生成的這些類裏面是什麼東西,大家本身去看啦。

而後編寫客戶端代碼(com.abc.webservice.WebServiceClient.java):

package com.abc.webservice;

import com.abc.MyWebService;

public class WebServiceClient {
    public static void main(String[] args) {
        MyWebService myWebService = new MyWebService();
        // 注意下面這句
        MyService myService = myWebService.getMyServiePort();
        System.out.println(myService.hello("Alvis"));
    }
}

這裏的MyWebService類就是wsimport命令根據WebService的WSDL生成的類啦。下面是WSDL中的一段:

<service name="MyWebService">
	<port name="MyServicePort" binding="tns:MyServicePortBinding">
		<soap:address location="http://localhost:8080/MyService" />
	</port>
</service>

從WSDL中能夠看出,有個<service>的name爲MyWebService,裏面包含了一個<port>,所以代碼中的

myWebService.getMyServicePort();

這句話獲得的其實是獲得了MyService這個類的實例了,這個類實際上是遠端WebService實現類的代理對象。能夠看看這個生成的MyWebService類中這個方法的定義:

@WebEndpoint(name = "MyServicePort")
public MyService getMyServicePort() {
    return super.getPort(new QName("http://www.abc.com", "MyServicePort"), MyService.class);
}

獲得這個MyService的實例後,就可使用該實例調用遠程端的方法啦:

myService.hello("Alvis")

我們再來看看MyService類中都有哪些東東:

package com.abc;

import javax.jws.WebMethod;
import javax.jws.WebParam;
import javax.jws.WebResult;
import javax.jws.WebService;
import javax.xml.bind.annotation.XmlSeeAlso;
import javax.xml.ws.Action;
import javax.xml.ws.RequestWrapper;
import javax.xml.ws.ResponseWrapper;

/**
 * This class was generated by the JAX-WS RI.
 * JAX-WS RI 2.2.4-b01
 * Generated source version: 2.2
 */
@WebService(name = "MyService", targetNamespace = "http://www.abc.com")
@XmlSeeAlso({
    ObjectFactory.class
})
public interface MyService {
    /**
     * @param arg0
     * @return
     *     returns java.lang.String
     */
    @WebMethod
    @WebResult(targetNamespace = "")
    @RequestWrapper(localName = "hello", 
        targetNamespace = "http://www.abc.com", className = "com.abc.Hello")
    @ResponseWrapper(localName = "helloResponse", 
        targetNamespace = "http://www.abc.com", className = "com.abc.HelloResponse")
    @Action(input = "http://www.abc.com/MyService/helloRequest", 
        output = "http://www.abc.com/MyService/helloResponse")
    public String hello(
        @WebParam(name = "arg0", targetNamespace = "")
        String arg0);
}

能夠看到,MyService是一個接口,由於真正的實如今遠端。其實裏面就一個方法,就是咱們在遠端定義的hello啦。

運行客戶端代碼便可:


這裏是項目源代碼,供須要的朋友參考。

相關文章
相關標籤/搜索