从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相互对照就清楚了。