java 实现WebService 以及不同的调用方式
目录
webservice是什么?
webservice: 是应用程序之间跨语言的调用
www.webxml.com.cn
1.xml
2.wsdl: webservice description language 是一种web服务描述语言,通过xml格式说明调用的地址方法如何调用,可以看做是webservice的说明书
wsdl文件
This XML file does not appear to have any style information associated with it. The document tree is shown below.
<wsdl:definitions xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/"
xmlns:tns="http://model.webservice.xncoding.com/" xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/"
xmlns:ns1="http://schemas.xmlsoap.org/soap/http" name="CommonService"
targetNamespace="http://model.webservice.xncoding.com/">
<wsdl:types>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:tns="http://model.webservice.xncoding.com/"
elementFormDefault="unqualified" targetNamespace="http://model.webservice.xncoding.com/" version="1.0">
<xs:element name="getUser" type="tns:getUser"/>
<xs:element name="getUserResponse" type="tns:getUserResponse"/>
<xs:element name="sayHello" type="tns:sayHello"/>
<xs:element name="sayHelloResponse" type="tns:sayHelloResponse"/>
<xs:complexType name="getUser">
<xs:sequence>
<xs:element minOccurs="0" name="userName" type="xs:string"/>
</xs:sequence>
</xs:complexType>
<xs:complexType name="getUserResponse">
<xs:sequence>
<xs:element minOccurs="0" name="return" type="tns:user"/>
</xs:sequence>
</xs:complexType>
<xs:complexType name="user">
<xs:sequence>
<xs:element minOccurs="0" name="age" type="xs:int"/>
<xs:element minOccurs="0" name="id" type="xs:long"/>
<xs:element minOccurs="0" name="name" type="xs:string"/>
</xs:sequence>
</xs:complexType>
<xs:complexType name="sayHello">
<xs:sequence>
<xs:element minOccurs="0" name="userName" type="xs:string"/>
</xs:sequence>
</xs:complexType>
<xs:complexType name="sayHelloResponse">
<xs:sequence>
<xs:element minOccurs="0" name="return" type="xs:string"/>
</xs:sequence>
</xs:complexType>
</xs:schema>
</wsdl:types>
<wsdl:message name="getUser">
<wsdl:part element="tns:getUser" name="parameters"></wsdl:part>
</wsdl:message>
<wsdl:message name="getUserResponse">
<wsdl:part element="tns:getUserResponse" name="parameters"></wsdl:part>
</wsdl:message>
<wsdl:message name="sayHello">
<wsdl:part element="tns:sayHello" name="parameters"></wsdl:part>
</wsdl:message>
<wsdl:message name="sayHelloResponse">
<wsdl:part element="tns:sayHelloResponse" name="parameters"></wsdl:part>
</wsdl:message>
<wsdl:portType name="CommonService">
<wsdl:operation name="getUser">
<wsdl:input message="tns:getUser" name="getUser"></wsdl:input>
<wsdl:output message="tns:getUserResponse" name="getUserResponse"></wsdl:output>
</wsdl:operation>
<wsdl:operation name="sayHello">
<wsdl:input message="tns:sayHello" name="sayHello"></wsdl:input>
<wsdl:output message="tns:sayHelloResponse" name="sayHelloResponse"></wsdl:output>
</wsdl:operation>
</wsdl:portType>
<wsdl:binding name="CommonServiceSoapBinding" type="tns:CommonService">
<soap:binding style="document" transport="http://schemas.xmlsoap.org/soap/http"/>
<wsdl:operation name="getUser">
<soap:operation soapAction="" style="document"/>
<wsdl:input name="getUser">
<soap:body use="literal"/>
</wsdl:input>
<wsdl:output name="getUserResponse">
<soap:body use="literal"/>
</wsdl:output>
</wsdl:operation>
<wsdl:operation name="sayHello">
<soap:operation soapAction="" style="document"/>
<wsdl:input name="sayHello">
<soap:body use="literal"/>
</wsdl:input>
<wsdl:output name="sayHelloResponse">
<soap:body use="literal"/>
</wsdl:output>
</wsdl:operation>
</wsdl:binding>
<wsdl:service name="CommonService">
<wsdl:port binding="tns:CommonServiceSoapBinding" name="CommonServiceImplPort">
<soap:address location="http://localhost:8092/services/CommonService"/>
</wsdl:port>
</wsdl:service>
</wsdl:definitions>
3.soap simple object access protoacl (简单对象访问协议),限定了xml的格式,soap 在http(因为有请求体,所以必须是post请求)的基础上传输xml数据
请求和响应的xml 的格式如:
<Envelop>
<body>
//....
</body>
</Envelop>
operation name:指服务提供的方法
静态方法不能发布为外部服务
运用jkd自带的代码生成访问服务器的客户端代码 E:/wsimort -s . http://test.cm/?wsdl
如果把webservice看做是web服务器上的一个应用,web服务器则是webservice的容器
JAX-WS是指 java api for xml -WebService
//测试 WebService服务的explorer,Web Service Explorer 可以显示返回的xml格式
targetNamespace 默认为倒置的包名
请求过程分析
- 1.使用get方式获取wsdl文件,称为握手
- 2.使用post发出请求
- 3.服务器响应则服务调用成功
几种监听工具
- http watch
- Web Service explorer
- eclipse 自带工具 TCP/IP Monitor
客户端调用WebService的方式
- 1.通过wximport生成代码
- 2.通过客户端编程方式
- 3.通过ajax调用方式
- 4.通过 URL Connection 方式调用
服务端代码
package com.webservcie;
import javax.jws.WebMethod;
import javax.jws.WebParam;
import javax.jws.WebResult;
import javax.jws.WebService;
import javax.xml.ws.Endpoint;
/**
* @WebService,将类标记为实现 Web Service,或者将接口标记为定义 Web Service 接口
*/
@WebService(serviceName="MyService",targetNamespace="http://www.baidu.com")
public class HelloService {
@WebMethod(operationName="AliassayHello")
@WebResult(name="myReturn")
public String sayHello(@WebParam(name="name") String name){
return "hello: " + name;
}
public String sayGoodbye(String name){
return "goodbye: " + name;
}
//当前方法不被发布出去
@WebMethod(exclude=true)
public String sayHello2(String name){
return "hello " + name;
}
public static void main(String[] args) {
/**
* 参数1:服务的发布地址
* 参数2:服务的实现者
* 发布Endpoint会重新启动一个线程
*/
Endpoint.publish("http://test.cm/", new HelloService());
System.out.println("Server ready...");
}
}
1.客户端调用(wsimport自动生成代码 【推荐】)
package com.wsclient;
public class App {
/**
* 通过wsimport 解析wsdl生成客户端代码调用WebService服务
*/
public static void main(String[] args) {
// TODO Auto-generated method stub
/**
* <service name="MyService">
* 获得服务名称
*/
MyService myWebService = new MyService();
/**
* <port name="HelloServicePort" binding="tns:HelloServicePortBinding">
*/
HelloService hs = myWebService.getHelloServicePort();
/**
* 调用方法
*/
System.out.println(hs.sayGoodbye("sjk"));
System.out.println(hs.aliassayHello("sjk"));
}
}
2.通过ajax+js+xml调用
<html>
<head>
<title>通过ajax调用WebService服务</title>
<script>
var xhr = new ActiveXObject("Microsoft.XMLHTTP");
function sendMsg(){
var name = document.getElementById('name').value;
//服务的地址
var wsUrl = 'http://192.168.1.100:6789/hello';
//请求体
var soap = '<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:q0="http://ws.itcast.cn/" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">' + ' <soapenv:Body> <q0:sayHello><arg0>' + name + '</arg0> </q0:sayHello> </soapenv:Body> </soapenv:Envelope>';
//打开连接
xhr.open('POST',wsUrl,true);
//重新设置请求头
xhr.setRequestHeader("Content-Type","text/xml;charset=UTF-8");
//设置回调函数
xhr.onreadystatechange = _back;
//发送请求
xhr.send(soap);
}
function _back(){
if(xhr.readyState == 4){
if(xhr.status == 200){
//alert('调用Webservice成功了');
var ret = xhr.responseXML;
var msg = ret.getElementsByTagName('return')[0];
document.getElementById('showInfo').innerHTML = msg.text;
//alert(msg.text);
}
}
}
</script>
</head>
<body>
<input type="button" value="发送SOAP请求" onclick="sendMsg();">
<input type="text" id="name">
<div id="showInfo">
</div>
</body>
</html>
3.URL Connection方式
import java.io.InputStream;
import java.io.OutputStream;
import java.net.HttpURLConnection;
import java.net.URL;
/**
* 通过UrlConnection调用Webservice服务
*/
public class App {
public static void main(String[] args) throws Exception {
//服务的地址
URL wsUrl = new URL("http://192.168.1.100:6789/hello");
HttpURLConnection conn = (HttpURLConnection) wsUrl.openConnection();
conn.setDoInput(true);
conn.setDoOutput(true);
conn.setRequestMethod("POST");
conn.setRequestProperty("Content-Type", "text/xml;charset=UTF-8");
OutputStream os = conn.getOutputStream();
//请求体
String soap = "<soapenv:Envelope xmlns:soapenv=\"http://schemas.xmlsoap.org/soap/envelope/\" xmlns:q0=\"http://ws.itcast.cn/\" xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\">" + "<soapenv:Body> <q0:sayHello><arg0>aaa</arg0> </q0:sayHello> </soapenv:Body> </soapenv:Envelope>";
os.write(soap.getBytes());
InputStream is = conn.getInputStream();
byte[] b = new byte[1024];
int len = 0;
String s = "";
while((len = is.read(b)) != -1){
String ss = new String(b,0,len,"UTF-8");
s += ss;
}
System.out.println(s);
is.close();
os.close();
conn.disconnect();
}
}
4.客户单编程方式(和第一种方式一样)
//文件名:HelloService.java
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 = "HelloService", targetNamespace = "http://ws.itcast.cn/")
@XmlSeeAlso({})
public interface HelloService {
@WebMethod
@WebResult(targetNamespace = "")
@RequestWrapper(localName = "sayHello", targetNamespace = "http://ws.itcast.cn/", className = "cn.itcast.ws.client.SayHello")
@ResponseWrapper(localName = "sayHelloResponse", targetNamespace = "http://ws.itcast.cn/", className = "cn.itcast.ws.client.SayHelloResponse")
public String sayHello(
@WebParam(name = "arg0", targetNamespace = "")
String arg0);
}
调用
import java.net.MalformedURLException;
import java.net.URL;
import javax.xml.namespace.QName;
import javax.xml.ws.Service;
import cn.itcast.ws.wsimport.HelloService;
/**
* 通过客户端编程的方式调用Webservice服务
*/
public class App {
public static void main(String[] args) throws Exception {
URL wsdlUrl = new URL("http://192.168.1.100:6789/hello?wsdl");
Service s =
Service.create(wsdlUrl, new QName("http://ws.itcast.cn/","HelloServiceService"));
HelloService hs = s.getPort(new QName("http://ws.itcast.cn/","HelloServicePort"), HelloService.class);
String ret = hs.sayHello("zhangsan");
System.out.println(ret);
}
}