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啦。
運行客戶端代碼便可:
這裏是項目源代碼,供須要的朋友參考。