從Java6開始原生支援WebService的開發,這篇我們就來研究通過JDK内置JAX-WS實作SOAP WebService。
下面以執行個體來展開研究:
服務端--釋出WebService
1、服務端-服務提供類和方法
package ws.service;
import javax.jws.WebMethod;
import javax.jws.WebParam;
import javax.jws.WebService;
import javax.jws.WebResult;
/**
* WebService
* @WebService将Java類标記為實作 Web Service
* 1、serviceName :指定對外釋出的服務名稱;如不指定,則預設為類名+Service(即HelloServiceService)
* 2、targetNamespace :指定服務的命名空間,名稱自定義(uri格式);如不指定,則預設為目前類的命名空間的倒序(即http://service.ws/)
*/
@WebService(serviceName="MyService",targetNamespace="http://www.tgb.edu")
public class HelloService {
/**
* sayHello
* @param name
* @return
*/
public String sayHello(@WebParam(name="name") String name){
return "hello: " + name;
}
/**
* sayHello1
* @param name
* @return
*/
@WebMethod(operationName="TGBsayHello")
@WebResult(name="myReturn")
public String sayHello1(@WebParam(name="name") String name){
return "hello: " + name;
}
@WebMethod(exclude=true) //目前方法不被釋出出去
public String sayHello2(@WebParam(name="name") String name){
return "hello: " + name;
}
public String sayGoodbye(@WebParam(name="name") String name){
return "goodbye: " + name;
}
}
2、服務釋出類
package ws.service;
import javax.xml.ws.Endpoint;
public class HelloMain {
public static void main(String[] args) {
System.out.println("準備啟動服務");
/**
* 參數1:服務的釋出位址
* 參數2:服務的實作者
* Endpoint 會重新啟動一個線程
*/
Endpoint.publish("http://127.0.0.1:8086/helloService", new HelloService());
System.out.println("服務啟動完畢");
}
}
3、釋出結果
打開http://127.0.0.1:8086/helloService?wsdl
wsdl格式的xml,如下
<!-- Published by JAX-WS RI at http://jax-ws.dev.java.net. RI's version is
JAX-WS RI 2.2.4-b01. --><!-- Generated by JAX-WS RI at http://jax-ws.dev.java.net. RI's version is
JAX-WS RI 2.2.4-b01. -->
<definitions targetNamespace="http://www.tgb.edu" name="MyService">
<types>
<xsd:schema>
<xsd:import namespace="http://www.tgb.edu"
schemaLocation="http://127.0.0.1:8086/helloService?xsd=1" />
</xsd:schema>
</types>
<message name="sayHello">
<part name="parameters" element="tns:sayHello" />
</message>
<message name="sayHelloResponse">
<part name="parameters" element="tns:sayHelloResponse" />
</message>
<message name="sayGoodbye">
<part name="parameters" element="tns:sayGoodbye" />
</message>
<message name="sayGoodbyeResponse">
<part name="parameters" element="tns:sayGoodbyeResponse" />
</message>
<portType name="HelloService">
<operation name="sayHello">
<input wsam:Action="http://www.tgb.edu/HelloService/sayHelloRequest"
message="tns:sayHello" />
<output wsam:Action="http://www.tgb.edu/HelloService/sayHelloResponse"
message="tns:sayHelloResponse" />
</operation>
<operation name="sayGoodbye">
<input wsam:Action="http://www.tgb.edu/HelloService/sayGoodbyeRequest"
message="tns:sayGoodbye" />
<output wsam:Action="http://www.tgb.edu/HelloService/sayGoodbyeResponse"
message="tns:sayGoodbyeResponse" />
</operation>
</portType>
<binding name="HelloServicePortBinding" type="tns:HelloService">
<soap:binding transport="http://schemas.xmlsoap.org/soap/http"
style="document" />
<operation name="sayHello">
<soap:operation soapAction="" />
<input>
<soap:body use="literal" />
</input>
<output>
<soap:body use="literal" />
</output>
</operation>
<operation name="sayGoodbye">
<soap:operation soapAction="" />
<input>
<soap:body use="literal" />
</input>
<output>
<soap:body use="literal" />
</output>
</operation>
</binding>
<service name="MyService">
<port name="HelloServicePort" binding="tns:HelloServicePortBinding">
<soap:address location="http://127.0.0.1:8086/helloService" />
</port>
</service>
</definitions>
用戶端--請求WebService
1、請求類和方法
package ws.client;
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.RequestWrapper;
import javax.xml.ws.ResponseWrapper;
@WebService(name = "MyService", targetNamespace = "http://www.tgb.edu")
public interface HelloClient {
//@WebMethod(operationName="TGBsayHello")
//@WebResult(name = "myReturn")
//@RequestWrapper(localName = "TGBsayHello")
//@ResponseWrapper(localName = "TGBsayHelloResponse")
public String sayHello(@WebParam(name = "name") String arg0);
}
2、發起請求類
package ws.client;
import java.net.MalformedURLException;
import java.net.URL;
import javax.xml.namespace.QName;
import javax.xml.ws.Service;
public class AppMain {
public static void main(String[] args) throws Exception {
//建立通路wsdl服務位址的url
URL wsdlUrl = new URL("http://127.0.0.1:8086/helloService");
/* 建立服務
* 通過Qname指明服務的具體資訊
* QName第一個參數:服務位址
* QName第二個參數:serviceName(如不指定則是:實作類名+Service)
*/
QName qname = new QName("http://www.tgb.edu","MyService");
Service s = Service.create(wsdlUrl, qname);
HelloClient hs = s.getPort(new QName("http://www.tgb.edu","HelloServicePort"), HelloClient.class);
String ret = hs.sayHello("zhang");
System.out.println(ret);
}
}
3、請求結果
輸出:hello: zhang
總結
注解的形式,使得服務的釋出和通路更加靈活,也讓服務端對外更加安全。
ps:如何了解各個注解的含義,和服務端的wsdl互相對照就清楚了。