1.基础知识
- 1> 要求
(1) jdK1.6_2.0以上的;引入javax.jws.*包
(2) @WebService:将Java类标记为实现WebService,或者将Java接口标记为定义WebService接口
(3) Endpoint:web端点服务类,它的方法publish用于将一个已经添加了@WebService注解对象绑定到一个地址的端口上。
- 2> 注意事项:
(1) 给类添加@WebService注解后,类中所有的非静态方法都将会对外公布,不支持静态方法,final方法
(2) 如果希望非静态、非final不对外公开,可以在方法上添加@WebMethod(exclude = true),阻止对外公开
(3) 如果一个类添加了@WebService注解,则此类必须至少含有一个可以公开的方法,否则启动失败。
2. 示例步骤
- (1) 依据上面的原则,建立WebService的工程,定义好WebService的类
<pre name="code" class="java">@WebService//将java类标记为实现web Service,或者将java接口标记为定义WebService接口 public class HelloService { //★★静态方法、用final修饰的方法是不能被发布为web服务的 public String sayHello(String name){ return "hello"+name; } @WebMethod(exclude=true) //★★表示:将一个方法隐藏起来不发布 public String sayHello2(String name){ return "hello"+name; } public static void main(String[] args) { /**publish():该方法在执行的时候会启动一个新的线程,在新的线程来监听客户端的请求。底层仍然是基于socket * 第一个参数:服务的发布地址;第二个参数:服务的实现者 */ Endpoint.publish("http://192.168.1.115:1120/hello",new HelloService());//[新启动线程]必须使用本机IP地址 System.out.println("Service ready ... ");//会输出,属于主线程[多线程] } }
(2) 在浏览器中输入:http://192.168.1.115:1120/hello?wsdl,测试服务是否能启动起来
(3) 如果服务能够启动,则在dos窗口通过命令生成本地生成客户端代码。调用WebService服务的命令是:wsimport –s .http://192.168.1.115:1120/hello?wsdl
(4) 通过生成的代码建立客户端工程(原理:通过解析wsdl生成的代码)
public class App { public static void main(String[] args) { //★得到服务对象的名:wsdl中<service>标签name属性的值 HelloServiceService hss = new HelloServiceService(); //★方法得来:wsdl中<service>标签下的<port>标签name属性的值 //★返回值类型( )得来:<port>bingding属性值-->对应<binding>的type属性值 HelloService hs = hss.getHelloServicePort(); String back = hs.sayHello(" jack"); System.out.println(back); //★★proxy:可以知道其实现运用的是jdk的动态代理 System.out.println(hs.getClass().getName()); } }
(5) 补充
客户端代码不使用WebService的包结构,以com.test.ws.client测试命令如下:
wsimport –s . –p com.test.ws.clienthttp://192.168.1.115:1120/hello?wsdl
3. 客户端使用js+xml调用service
<html>
<head>
<title>通过ajax调用WebService服务</title>
<script>
var xhr = new ActiveXObject("Microsoft.XMLHTTP");//获得IE的xmlHttpRequest对象
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请求" οnclick="sendMsg();">
<input type="text" id="name">
<div id="showInfo">
</div>
</body>
</html>
4. 通过URLConnection方式调用WebService
//基本上和ajax差不多,只是表现方式不同
public class App {
public static void main(String[] args) throws Exception {
//服务的地址
URL wsURL = new URL("http://192.168.1.115:1120/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 = "";//略
os.write(soap.getBytes());
InputStream is = conn.getInputStream();
byte[] b = new byte[1024];
int len = 0;
String s = "";
while((len = is.read())!=-1){
String ss = new String(b,0,len,"UTF-8");
s+=ss;
}
System.err.println(s);
is.close();
os.close();
conn.disconnect();
}
}
5. 解读wsdl文件
用注解写WebService的发布报文
5. 附录:本示例服务的wsdl文件
<?xml version="1.0" encoding="UTF-8" ?>
<!-- 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 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://ws.hw.cn/" xmlns:xsd="http://www.w3.org/2001/XMLSchema"
xmlns="http://schemas.xmlsoap.org/wsdl/"
targetNamespace="http://ws.hw.cn/" name="HelloServiceService">
<types>
<xsd:schema>
<xsd:import namespace="http://ws.hw.cn/" schemaLocation="http://192.168.1.115:1120/hello?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>
<portType name="HelloService">
<operation name="sayHello">
<input wsam:Action="http://ws.hw.cn/HelloService/sayHelloRequest" message="tns:sayHello" />
<output wsam:Action="http://ws.hw.cn/HelloService/sayHelloResponse" message="tns:sayHelloResponse" />
</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>
</binding>
<service name="HelloServiceService">
<port name="HelloServicePort" binding="tns:HelloServicePortBinding">
<soap:address location="http://192.168.1.115:1120/hello" />
</port>
</service>
</definitions>