一、概述
1.是什么
// 来自百度百科
提供webService的参考网址:http://www.webxml.com.cn/zh_cn/web_services.aspx
主要作用是使不同软件系统之间实现互联互通!
2.必会基础知识
名词1:XML. Extensible Markup Language -扩展性标记语言
XML,用于传输格式化的数据,是Web服务的基础。
namespace-命名空间。
xmlns=“http://itcast.cn” 使用默认命名空间。
xmlns:itcast=“http://itcast.cn”使用指定名称的命名空间。
名词2:WSDL – WebService Description Language – Web服务描述语言。
通过XML形式说明服务在什么地方-地址。
通过XML形式说明服务提供什么样的方法 – 如何调用。
重点掌握的关系图:——拿到一个WSDL读取方式是从后往前读
名词3:SOAP-Simple Object Access Protocol(简单对象访问协议)
SOAP作为一个基于XML语言的协议用于有网上传输数据。
SOAP = 在HTTP的基础上+XML数据。
SOAP是基于HTTP的。
SOAP的组成如下:
Envelope – 必须的部分。以XML的根元素出现。
Headers – 可选的。
Body – 必须的。在body部分,包含要执行的服务器的方法。和发送到服务器的数据。
其中,WSDL的教程(以及SOAP教程)可以参考:菜鸟教程
二、基本入门操作
1.生成客户端代码
使用的是JDK1.6+的wsimport命令,其中两个参数的含义是:
-d<目录> - 将生成.class文件。默认参数。
-s<目录> - 将生成.java文件和class文件。
-p<生成的新包名> -将生成的类,放于指定的包下。
示例:
// 1表示当前目录,2表示WSDL的地址(当然不限于网络地址,可以另存为.wsdl的本地文件,然后使用本地路径D:/...)
2.webService客户端调用
步骤如下:
调用webservice步骤 1)打开WSDL文档 2)从下往上读WSDL文档,先找到Services(服务访问点集合),根据Services里面binding属性找到binding元素,再根据binding元素的type属性找到绑定的portType(服务类) 3)根据WSDL的地址生成客户端代码wsimport -s . -p com.rl.trans d:/wsCode/EnglishChinese.wsdl 4)把客户端代码拷贝到项目中 5)创建服务访问点集合对象 6)根据服务访问点获得服务类 7)调用服务类的方法
示例:
先把上面生成的代码复制到工程
再在工程中建立测试的类:
public static void main(String[] args) {
// 创建服务访问点集合
MobileCodeWS mc = new MobileCodeWS();
// 根据服务访问点获得绑定的类
MobileCodeWSSoap serviceClass = mc.getMobileCodeWSSoap();
// 调用具体业务逻辑
String info = serviceClass.getMobileCodeInfo("13407966980", null);
System.out.println("info = " + info);
}
结果:
另外一个含有mp3(字节流)的示例如下:
public static void main(String[] args) throws Exception { //创建服务访问点集合 EnglishChinese ec = new EnglishChinese(); //获得服务类 EnglishChineseSoap serviceClass = ec.getEnglishChineseSoap(); //调用服务方法 ArrayOfString aos = serviceClass.translatorString("hello"); List<String> strList = aos.getString(); for(String result : strList){ System.out.println(result); } //调用服务方法 byte[] mp3 = serviceClass.getMp3("1059.mp3"); OutputStream out = new FileOutputStream(new File("d:/wsCode/hello.mp3")); out.write(mp3); out.flush(); out.close(); }
3.使用jdk发布webService服务的发布
步骤如下:
a)@WebService - 它是一个注解,用在类上指定将此类发布成一个webservice服务. b)Endpoint – 此类为端点服务类,它的方法publish用于将一个已经添加了@WebService注解对象绑定到一个地址的端口上。Endpoint是jdk提供的一个专门用于发布服务的类,它的publish方法接收两个参数,一个是本地的服务地址,二是提供服务的类。它位于javax.xml.ws.*包中。 static Endpoint.publish(String address, Object implementor) 在给定地址处针对指定的实现者对象创建并发布端点。stop方法用于停止服务。 其他注意事项: 1)给类添加上@WebService注解后,类中所有的非静态方法都将会对外公布。不支持静态方法,final方法。 2)如果希望某个方法(非static,非final)不对外公开,可以在方法上添加@WebMethod(exclude=true),阻止对外公开。 3)如果一个类上,被添加了@WebService注解,则必须此类至少有一个可以公开的方法,否则将会启动失败。 4)服务类中不能没有方法 5)@WebMethod(exclude=true)屏蔽方法
示例:
服务类:
@WebService public class HelloServer { public String sayHello(String name) { return "hello "+name+" welcome to webService Server"; } }
发布服务:
public class ServerPublish {
public static void main(String[] args) {
// 使用JDK发布ws服务,包含发布地址与服务类的两个参数
Endpoint.publish("http://127.0.0.1:8080/hello", new HelloServer());
}
}
结果:请注意访问地址!
//可以使用第二点客户端的调用进行测试
4.其它调用webService的方式
使用原生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) } }
使用JQuery封装的AJAX调用:http://www.cnblogs.com/2013likong/p/3472144.html
使用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()); }
5.复杂数据类型传输
@WebService
public class TestComplexServer {
List<Person> pList = new ArrayList<Person>();
public void addPerson(Person person){
pList.add(person);
}
public List<Person> getPersonList(){
return pList;
}
public static void main(String[] args) {
Endpoint.publish("http://192.168.1.104:8888/person", new TestComplexServer());
}
}
测试代码:
public static void main(String[] args) { //创建服务访问点集合 PersonServerService pss = new PersonServerService(); //根据服务访问点获得绑定的类 PersonServer server = pss.getPersonServerPort(); //调用具体业务逻辑 Person person = new Person(); person.setId(1); person.setName("zhaoliu"); person.setAge(20); person.setAddress("xiangyashan"); Person person1 = new Person(); person1.setId(2); person1.setName("tianqi"); person1.setAge(25); person1.setAddress("gaolaozhang"); //调用添加人的webservice服务方法 /*server.addPerson(person); server.addPerson(person1);*/ //调用查询所有人的webservice服务方法 List<Person> pList = server.getPersonAll(); for(Person p : pList){ System.out.println("id: "+p.getId()+" name:"+p.getName() + " age:"+p.getAge() + " address:"+p.getAddress()); } }
7.修改WSDL文档
WSDL文档并非一经发布便不可更改,可供修改项如下:
自动生成的文档的名字有时不规范,可以手动进行修改。
@WebService(
portName="myHelloService",修改端口名字
serviceName="HelloServices",修改服务访问点集合名字
name="HelloService",修改服务类的名字
targetNamespace="hello.rl.com" 修改命名空间名字
)
@WebResult(name="sirHello")修改返回值的元素的父标签名字——在方法返回值前加注解修改
@WebParam(name="sir")修改传入参数的元素的父标签名字——在方法参数前加注解修改
webService参考教程:http://www.cnblogs.com/yangang2013/p/5708647.html