自定义WebService和客户端调用《二》
来源:互联网 发布:结婚路线图制作软件 编辑:程序博客网 时间:2024/04/27 13:42
问题?自定义WebService和客户端调用《二》,客户端调用有几种方式
一、JDK创建WebService服务和使用
Oracle前身sun公司,早就意识到WebService的强大,和它的未来前景,所以在JDK中早就封装了这样的创建WebService服务。
查看DJK-API文档:
1.新建Java或web工程,建一个类(这个类作为服务端):
<span style="font-family:Microsoft YaHei;font-size:18px;"><span style="font-family:Microsoft YaHei;font-size:18px;">package com.itcast.ws;import javax.jws.WebService;import javax.xml.ws.Endpoint;@WebService //表示这个类,代表的是启动服务,ServiceName名字可以改,默认不写的话,名字为类名加Servicepublic class HelloService {public String sayhello(String name){//能够访问的借口方法,必须是public方法System.out.println("Hello: "+name);return "Hello: "+name;}public String sayhello1(){return "成功调用第二个服务器方法";} public static void main(String[] args) { /* * 调用静态的方法Endpoint.publish创建一个服务 * 1.address:URI,指定要使用的地址和传输/协议,也就是服务地址 * 2.implementor:实现者,也就是服务端 */ <pre name="code" class="java"><span style="white-space:pre"></span>//使用自建端口号之前,cmd中使用netstat -a 检查一下端口是否被占用</span></span>Endpoint.publish("http://localhost:9090/hello", new HelloService());System.out.println("启动服务:new HelloService");}}
/**如果改成private方法的话就会出现以下错误,我们做这个webservcie服务就是为了,*公布数据给别人用的,给成私有的,就达不到目的了,自然就会出错。Static、finally也不行
*Exception in thread "main"com.sun.xml.internal.ws.model.RuntimeModelerException: The web *service definedby the class com.itcast.ws.HelloService does not contain any valid WebMethods.
*/
运行:如果出现错:Exception in thread "main" com.sun.xml.internal.ws.model.RuntimeModelerException:解决办法将jdk升级到1.7版本,MyEclispe的preference下java install(一般情况下,MyEclispe用的而是自身带的JDK,而不是安装得JDK,需要配置一下)
否则就运行成功:
或者网页调用:http://localhost:9090/hello或http://localhost:9090/hello?wsdl 看看wsdl服务描述文档
2.新建客户端,并且调用该服务,在调用过程中,该服务必须一直开启
用wsimport -s . http://localhost:9090/hello?wsdl来生成本地代码,在上一文章中已经说过怎么做了。
把生成的文件夹拷入到客户端项目src下,并且新建一个测试调用类:
<span style="font-family:Microsoft YaHei;font-size:18px;"><span style="font-family:Microsoft YaHei;font-size:18px;">package com.itcast.test;import org.junit.Test;import com.itcast.ws.HelloService;import com.itcast.ws.HelloServiceService;public class test1 {@Testpublic void testService(){HelloServiceService helloServiceService = new HelloServiceService();HelloService service = helloServiceService.getHelloServicePort();String name = service.sayhello("李*****");System.out.println("成功获取数据包: "+name+" "+service.sayhello1());}}</span></span>
这里的HelloServiceService是来自访问网网址?wsdl文件中的,所以不需要去看wsdl文档。
说到这里了,我们就会忍不住提出,那么通过wsimport -s .生成的代码,导入到工程中,我怎么知道,调用哪个服务,调用哪个接口呢?就需要深入看看WebService的深入理解了。
二、深入了解WebService配置
1.注解声明类为@WebService,不然就会报错。
不然报这个错误:class cn.itcast.ws.HelloService has neither @WebService nor @WebServiceProvider annotation
必须有至少一个public方法,且这个方法不能是static,final
不然就hi报这个错误:cn.itcast.ws.HelloService does not contain any valid WebMethods.
/**如果改成private方法的话就会出现以下错误,我们做这个webservcie服务就是为了,*公布数据给别人用的,给成私有的,就达不到目的了,自然就会出错。Static、finally也不行
*Exception in thread "main" com.sun.xml.internal.ws.model.RuntimeModelerException: The web *service defined by the class com.itcast.ws.HelloService does not contain any valid WebMethods.
*/
2.如何查看说明wsdl?
前面提到,怎么知道调用哪个服务,怎么知道调用哪个接口,这里就会讲到了。
端口
方法
参数
访问看看:http://localhost:9080/hello?xsd=1
返回值
3.MyEclipes提供WebService工具
它有两个作用:
1.第一个作用可以用来测试服务端的数据。
2.第二个作用可以获取发出SAOP请求的代码,(它会返回WSDL代码,在AJAX市级开发中使用特别多)和返回SAOP结果的代码,在AJAX之中用得比较多。比如以下:
注意:这个工具有一个最不好的缺点,就是它不支持SAOP1.2,它只支持1.1版本。
三、Ajax调用WebService服务
响应的一样,首先WebService服务的搭建,有服务接口,与接口中的方法,开启服务。
然后用MyEclipes提供WebService工具获取到接口的SAOP请求的代码,如以上那张图片。
首先你得有AJAX的基础才能做这一块哈。
<span style="font-family:Microsoft YaHei;font-size:18px;"><!DOCTYPE html><html><head><meta charset="UTF-8"><title>Insert title here</title><script type="text/javascript">/*思路:1.创建一个XMLHTTP对象2.打开链接open("POST",url)3.设置请求头Content-Type4.设置回调函数,处理返回值5.从返回的XML中解析我们要的内容*/var xmlHttpReqquest = new ActiveXObject("Microsoft.XMLHTTP");//alert(xmlHttpReqquest);//发送SOAP请求function sendMsg(){//获取用户输入的内容var name = document.getElementById("name").value;var url = "http://localhost:9080/hello";var requestBody = "<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>";xmlHttpReqquest.open("POST", url);xmlHttpReqquest.setRequestHeader("Content-Type","text/xml;charset=utf-8");xmlHttpReqquest.onreadystatechange = _back;xmlHttpReqquest.send(requestBody);}//接收SOAP返回,从返回XML中解析function _back(){//处理完毕,处理成功if(xmlHttpReqquest.readystate==4){//处理完if(xmlHttpReqquest.status==200){//成功var xml = xmlHttpReqquest.responseXML;//alert(xml);//获取return标签的第一个var ele = xml.getElementsByTagName("return")[0];alert(ele.text);}}}</script></head><body><input type="text" id="name" name="name" value=""/><input type="button" name="send" value="send" onclick="sendMsg();"/></body></html></span>
启动tomcate或者其他服务器,测试一下是否调用得了。
四、HttpURLConnection方式调用WebService服务
同样的这种方式,也需要SAOP请求的消息。同样用MyEclispe工具获取
如:
<span style="font-family:Microsoft YaHei;font-size:18px;">package com.itcast.test;import java.io.IOException;import java.io.InputStream;import java.io.OutputStream;import java.net.HttpURLConnection;import java.net.URL;import org.junit.Test;public class RequestUrlConnectionTest {@Testpublic void uriTest() throws IOException{/* *1.创建一个url *2.打开一个连接 *3.设置相关参数 *4.创建输出流,用来发送SAOP请求 *5.发送完,接收数据 *6.用输入流获取webservice中的内容 */URL url = new URL("http://localhost:9090/hello");HttpURLConnection connection = (HttpURLConnection)url.openConnection();connection.setRequestMethod("POST");//必须设置为POST方式,而且必须是大写的connection.setDoInput(true);//因为有输入参数也有输出参数所以都为真connection.setDoOutput(true);connection.setRequestProperty("Content-Type", "text/xml;charset=utf-8");OutputStream out = connection.getOutputStream();String argo="<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\">"+"xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"><soapenv:Body><q0:sayhello><arg0>jack</arg0></q0:sayhello></soapenv:Body></soapenv:Envelope>";out.write(argo.getBytes());//发送SAOP请求InputStream stream = connection.getInputStream();byte[] b = new byte[1024];int len=0;StringBuffer buffer = new StringBuffer();while((len=stream.read(b))!=-1){String s = new String(b, 0, len, "utf-8");buffer.append(s);}System.out.println(buffer.toString());}}</span>
五、QName调用WebService方式
这个QName的链接地址要WSDL说明书
用cmd打包好的本地调用代码,复制到客户端项目中,只留下服务接口(那个是服务的接口,参照说明书),其他都删掉,里面的错的可以删掉。
<span style="font-family:Microsoft YaHei;font-size:18px;">package com.itcast.test;import java.net.MalformedURLException;import java.net.URL;import javax.xml.namespace.QName;import javax.xml.ws.Service;import org.junit.Test;import com.itcast.ws.HelloService;public class QnameTest {/* * 1.创建service对象,service.create(wsdlDocumentLocation, serviceName) * wsdlDocumentLocation:URL服务地址,而且需要wsmdl描述 * serviceName:Qname,这就是用这个方式的核心,因为他只用到service接口 * Qname:需要两个参数,一个是打包的空间,另外一个是这个服务名称(描述文件中的的服务名) * * 2.通过service对象调用接口 * 3.通过接口对象来调用服务端方法 */@Testpublic void qnametest1() throws MalformedURLException{URL url = new URL("http://localhost:9090/hello?wsdl");QName serviceName = new QName("http://ws.itcast.com/", "HelloServiceService");Service service = Service.create(url, serviceName );HelloService helloService = service.getPort(HelloService.class);String name = helloService.sayhello("Mr_Li");String naem1 = helloService.sayhello1();System.out.println("调用service成功:"+name+"\n"+naem1);}}</span>
六、注解开发
前面我用的调用接口服务,需要知道说明书上写明那个服务,然后我们才去写,因为那些服务名称都是它自动加上的基本结构为:服务名+Service,还有命名空间是跟建得包是烦着过来的。如果采取注解的形式去开发,那么就不需要知道服务名称(针对于程序猿)。
@WebService(serviceName="MyService")
修改产生的服务的名称
@WebService(serviceName="MyService",targetNamespace="http://cn.itcast.ws/")
修改命名空间
@WebMethod(operationName="hello")
修改方法名称
@WebParam(name="name")
修改参数名称
@WebResult(name="returnMsg")
修改返回名称
@WebMethod(exclude=true)
将指定的public方法排除,用户不能访问
如:
<span style="font-family:Microsoft YaHei;font-size:18px;">package com.itcast.ws;import javax.jws.WebMethod;import javax.jws.WebParam;import javax.jws.WebResult;import javax.jws.WebService;import javax.xml.ws.Endpoint;@WebService(serviceName="MyService",targetNamespace="http://com.itcast.ws/") //表示这个类,代表的是启动服务,ServiceName名字可以改,默认不写的话,名字为类名加Servicepublic class HelloService {@WebMethod(operationName="Hello1")@WebResult(name="returnResult")public String sayhello(@WebParam(name="name")String name){System.out.println("Hello: "+name);return "Hello: "+name;}@WebMethod(operationName="Hello2",exclude=true)public String sayhello1(){return "成功调用第二个服务器方法";} public static void main(String[] args) { /* * 调用静态的方法Endpoint.publish创建一个服务 * 1.address:URI,指定要使用的地址和传输/协议,也就是服务地址 * 2.implementor:实现者,也就是服务端 */Endpoint.publish("http://localhost:9090/hello", new HelloService());System.out.println("启动服务:new HelloService");}}</span>
执行命令看看是不是这样的:
http://localhost:9090/hello?wsdl
http://localhost:9090/hello?xsd=1
七、监控工具TCP/IP监控
有时候我们需要监听整个webservice的调用状态,需要用到MyEclipse的一个监听工具(只有高版本才有这个工具)
采用的是TCP/IP的方式来监听的。需要监听的端口号和被监听的端口号不同。
八、总结
1.UDDI/WSDL/SOAP的概念
2.wsimport –s . http::///// 生产本地调用代码
3.注意:支持soap1.0协议
4.发布服务 Endpoint.publish静态方法
参数1访问地址,参数2实现类。
5.Service类,它有静态方法create可以创建一个Web服务
6.调用方式:
A. 客户端的方式
B. MyEclipse自带工具WebService Expolor 帮助测试,直接获取到发送和接收的SOAPxml
C. Ajax ,不需生成本地调用代码,可以直接访问,在实际项目中使用比较多
D. HttpURLConnection对象,是以流方式
E. QName方式,内部使用方式,实际开发中常采用实际开发中可以选择其中一种
7.对象封装
业务比较复杂,按原有的方式写po类,按原有的方式写Service层,在Server服务端调用业务层service。实现业务逻辑。
总结:还没完呢,请看下一篇文章点击打开文章链接
- 自定义WebService和客户端调用《二》
- 自定义WebService和客户端调用《二》
- 用AXIS2发布WebService和客户端调用
- Android调用WebService之客户端实现(二)
- ASP.NET Ajax学习笔记(二)客户端调用WebService
- WebService之CXF(二、客户端的生成与调用)
- 二、CXF与springMVC整合的webService客户端调用
- webservice的axis2客户端调用方式和xfire调用方式
- 客户端调用webservice
- 客户端调用(webservice)
- axis 调用webservice (客户端)
- 客户端xmlhttp调用webservice
- webservice 异步调用客户端
- Webservice客户端调用Bug
- HttpClient-调用webservice客户端
- RPCServiceClient-调用webservice客户端
- webservice客户端调用方式
- java客户端调用webservice
- 2016年五·一劳动节广州国际生物岛10公里环岛跑策划方案
- Android中的dp,px,sp互转问题以及 View.setLayoutParams, 以及网络相关工具类
- PHP 时间戳转化为日期格式
- hibernate主键生成机制
- ViewPager 详解(五)-----使用Fragment实现ViewPager滑动
- 自定义WebService和客户端调用《二》
- word-wrap和word-break的区别
- Android SDK在线更新
- Java内存泄露原因详解
- UML类图
- Oracle kill inactive 线程
- 文档去重算法:SimHash和MinHash
- 搜索后再分页
- Exercise(8):单色汉诺塔