一、客户端
1、生成客户端代码
(1)wsimport是jdk自带的,可以根据wsdl文档生成客户端调用代码的工具。当然,无论服务器端的WebService是用什么语言写的,都将在客户端生成java代码。服务器端用什么写不重要。
(2)wsimport.exe位于JAVA_HOME\bin目录下。
常用参数:
-d<目录> -将生成.class文件。默认参数。
-s<目录> -将生成.java文件和class文件
-p<生成的新包名> -将生成的类,放与指定的包下。
(wsdlurl) -http://server:port/service?wsdl,必须的参数。
示例:
C:/> wsimport –s . http://192.168.0.120/one?wsdl
(3)注意:-s不能分开,-s后面有个小点,用于指定源代码生成的目录。点即当前目录。当我们使用-s参数则会在目录下生成class和java文件。.class,可以经过打包以后使用,.java代码可以直接copy到我们的项目中运行。
调用webservice步骤
- 打开WSDL文档
- 从下往上读WSDL文档,先找到Services(服务访问点集合),根据Services里面binding属性找到binding元素,再根据binding元素的type属性找到绑定的portType(服务类)
- 根据WSDL的地址生成客户端代码wsimport -s . -p com.rl.trans d:/wsCode/EnglishChinese.wsdl
- 把客户端代码拷贝到项目中
- 创建服务访问点集合对象
- 根据服务访问点获得服务类
- 调用服务类的方法
2、客户端调用的方法:
(1)用产生java类的形式调用
使用wsimport的形式产生客户端代码,以http://ws.webxml.com.cn/WebServices/MobileCodeWS.asmx?WSDL为例产生,wsimport -s . http://ws.webxml.com.cn/WebServices/MobileCodeWS.asmx?WSDL
,然后看到产生的文件,
,将其java文件结尾的放在工程中,并且编写测试类:
package com.testCliet;
import com.webxml.MobileCodeWS;
import com.webxml.MobileCodeWSSoap;
public class TestClient {
public static void main(String[] args) {
MobileCodeWS mw=new MobileCodeWS();
MobileCodeWSSoap mws= mw.getMobileCodeWSSoap();
//此处填写自己的电话号码测试即可
String data=mws.getMobileCodeInfo("136086*****","");
System.out.println(data);
}
}
(2)ajax调用:
var xhr;
function invoke(){
if(window.ActiveXObject){
xhr = new ActiveXObject("Microsoft.XMLHTTP");
}else{
xhr = new XMLHttpRequest();
}
//指定请求地址
var url = "http://127.0.0.1:7777/hello?wsdl";
//定义请求类型和地址和异步
xhr.open("POST", url, true);
//设置Content-Type
xhr.setRequestHeader("Content-Type", "text/xml;charset=UTF-8");
//指定回调方法
xhr.onreadystatechange = back;
var textVal = document.getElementById("mytext").value;
//组装消息体的数据
var data = '<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:q0="http://server.hm.com/" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">'
+'<soapenv:Body>'
+'<q0:sayHello>'
+'<arg0>'+textVal+'</arg0>'
+'</q0:sayHello>'
+'</soapenv:Body>'
+'</soapenv:Envelope>';
xhr.send(data);
}
function back(){
if(xhr.readyState == 4){
if(xhr.status == 200){
var doc = xhr.responseXML;
alert(doc);
alert(xhr.responseText);
var tag = doc.getElementsByTagName("return")[0];
alert(tag)
}
}
}
使用这种方法不需要使用wsimport的形式产生代码,只需要读wsdl的形式,将其连接和方法组装,并且直接的进行调用即可。
(3)URLConnection调用
//创建url地址
URL url = new URL("http://192.168.1.104:8080/hello");
//打开连接
URLConnection conn = url.openConnection();
//转换成HttpURL
HttpURLConnection httpConn = (HttpURLConnection) conn;
//打开输入输出的开关
httpConn.setDoInput(true);
httpConn.setDoOutput(true);
//设置请求方式
httpConn.setRequestMethod("POST");
//设置请求的头信息
httpConn.setRequestProperty("Content-type", "text/xml;charset=UTF-8");
//拼接请求消息
String data = "<soapenv:Envelope xmlns:soapenv=" +
"\"http://schemas.xmlsoap.org/soap/envelope/\" " +
"xmlns:q0=\"http://server.rl.com/\" " +
"xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\" " +
"xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\">"
+"<soapenv:Body>"
+"<q0:sayHello>"
+"<arg0>renliang</arg0> "
+"</q0:sayHello>"
+"</soapenv:Body>"
+"</soapenv:Envelope>";
//获得输出流
OutputStream out = httpConn.getOutputStream();
//发送数据
out.write(data.getBytes());
//判断请求成功
if(httpConn.getResponseCode() == 200){
//获得输入流
InputStream in = httpConn.getInputStream();
//使用输入流的缓冲区
BufferedReader reader = new BufferedReader(new InputStreamReader(in));
StringBuffer sb = new StringBuffer();
String line = null;
//读取输入流
while((line = reader.readLine()) != null){
sb.append(line);
}
//创建sax的读取器
SAXReader saxReader = new SAXReader();
//创建文档对象
Document doc = saxReader.read(new StringReader(sb.toString()));
//获得请求响应return元素
List<Element> eles = doc.selectNodes("//return");
for(Element ele : eles){
System.out.println(ele.getText());
}
2、服务器端
(1)jdk发布WebService服务
注意:用jdk1.6.0_21以后的版本发布一个WebService服务。
说明:在jdk1.6中JAX-WS规范定义了如何发布一个WebService服务。
JAX-WS是指java api for XML–Webservice
与web服务相关的类,都位于javax.xml.ws.*包中。
主要类有:
1)@WebService --它是一个注解,用在类上指定将此类发布成一个WebService服务。
2)EndPoint–此类为端点服务类,他的方法publish用于将一个已经添加了@WebService注解对象绑定到一个地址的端口上。EndPoint是jdk提供的一个专门用于发布服务的类,他的publish方法接收两个参数,一个是本地的服务地址,二是提供服务的类。
static EndPoint.punlish(String address,Object implementor)在给定地址处针对指定的实现者对象创建并发布端点。stop方法用于停止服务。
其他注意事项:
a)给类添加@WebService注解后,类中所有的非静态方法都将会对外公布。不支持静态方法,final方法。
b)如果希望某个方法(非static,非final)不对外公开,可以在方法上添加@WebMethod(exclude=true),阻止对外公开。
c)如果一个类上,被添加了@WebService注解,则必须此类至少一个可以公开的方法,否则将会启动失败
d)服务类中不能没有方法
简单示例如下:
package com.testService;
import javax.jws.WebService;
/**
此类是服务类,用于发布的时候进行调用
**/
@WebService
public class ZhouService {
public String sayHello(String name){
return name+",hello!";
}
}
测试发布类:
package com.testService;
import javax.xml.ws.Endpoint;
public class TestService {
public static void main(String[] args) {
Endpoint.publish("http://127.0.0.1:8080/hello",new ZhouService());
}
}
测试:用浏览器打开http://127.0.0.1:8080/hello?wsdl
扩展:使用@WebService的注解形式更改示例:
package com.rl.server;
import javax.jws.WebMethod;
import javax.jws.WebParam;
import javax.jws.WebResult;
import javax.jws.WebService;
@WebService(
serviceName="MyHelloServerService",
portName="MyHelloServer",
name="MyHelloServer",
targetNamespace="hello.ren.liang"
)
public class HelloServer {
/**
* 1.需要方法权限是public
* 2.不能是final类型
* 3.方法不能是静态的
* 4.服务类至少有一个方法
* @param name
* @return
*/
@WebMethod(exclude=true)
public String sayHello(String name){
return name + " hello!";
}
@WebMethod(exclude=false)
public @WebResult(name="byeResult") String sayBye(@WebParam(name="personName") String name){
return name + " bye!";
}
}