webservice 订阅
Web Service是一个平台独立的,低耦合的,自包含的、基于可编程的web的应用程序,可使用开放的XML(标准通用标记语言下的一个子集)标准来描述、发布、发现、协调和配置这些应用程序,用于开发分布式的交互操作的应用程序。 [1]  Web Service技术, 能使得运行在不同机器上的不同应用无须借助附加的、专门的第三方软件或硬件, 就可相互交换数据或集成。依据Web Service规范实施的应用之间, 无论它们所使用的语言、 平台或内部协议是什么, 都可以相互交换数据。Web Service是自描述、 自包含的可用网络模块, 可以执行具体的业务功能。Web Service也很容易部署, 因为它们基于一些常规的产业标准以及已有的一些技术,诸如标准通用标记语言下的子集XML、HTTP。Web Service减少了应用接口的花费。Web Service为整个企业甚至多个组织之间的业务流程的集成提供了一个通用机制。 展开全文
Web Service是一个平台独立的,低耦合的,自包含的、基于可编程的web的应用程序,可使用开放的XML(标准通用标记语言下的一个子集)标准来描述、发布、发现、协调和配置这些应用程序,用于开发分布式的交互操作的应用程序。 [1]  Web Service技术, 能使得运行在不同机器上的不同应用无须借助附加的、专门的第三方软件或硬件, 就可相互交换数据或集成。依据Web Service规范实施的应用之间, 无论它们所使用的语言、 平台或内部协议是什么, 都可以相互交换数据。Web Service是自描述、 自包含的可用网络模块, 可以执行具体的业务功能。Web Service也很容易部署, 因为它们基于一些常规的产业标准以及已有的一些技术,诸如标准通用标记语言下的子集XML、HTTP。Web Service减少了应用接口的花费。Web Service为整个企业甚至多个组织之间的业务流程的集成提供了一个通用机制。
信息
类    型
应用程序
平    台
独立平台
作    用
交换数据或集成
中文名
Web Service
外文名
Web Service
Web Service历史
web广泛用到的技术:他们的特点是其开放性,跨平台性,开放性正是Web services的基础。近几年来,Internet的迅猛发展使其成为全球信息传递与共享的巨大的资源库。越来越多的网络环境下的Web应用系统被建立起来,利用HTML、CGI等Web技术可以轻松地在Internet环境下实现电子商务、电子政务等多种应用。然而这些应用可能分布在不同的地理位置,使用不同的数据组织形式和操作系统平台,加上应用不同所造成的数据不一致性,使得如何将这些高度分布的数据集中起来并得以充分利用成为急需解决的问题。随着网络技术、网络运行理念的发展,人们提出一种新的利用网络进行应用集成的解决方案——Web Service。Web Service是一种新的Web应用程序分支,其可以执行从简单的请求到复杂商务处理的任何功能。一旦部署以后,其他Web Service应用程序可以发现并调用它部署的服务。因此,Web Service是构造分布式、模块化应用程序和面向服务应用集成的最新技术和发展趋势。
收起全文
精华内容
下载资源
问答
  • webservice

    2015-04-16 14:24:32
    webservice
  • WebService

    2018-03-30 10:17:03
    WebService练习WebService练习WebService练习WebService练习
  • Webservice

    千次阅读 2019-08-30 11:28:43
    webservice有三部分:webservice的介绍、webservice的客户端的实现方式、webservice服务端的实现方式; webservice介绍: webservice是两个系统之间的调用, 实现两个系统间数据交互,如:支付宝调用各个银行的接口...

    webservice有三部分:webservice的介绍、webservice的客户端的实现方式、webservice服务端的实现方式;

    webservice介绍:
    webservice是两个系统之间的调用, 实现两个系统间数据交互,如:支付宝调用各个银行的接口实现支付功能;我们再网站下订单时调用库存与支付系统,完成库存数据减少,同时完成订单记录与支付

    webservice的调用是可以跨语言的,如:c# 、C、java 、php按照一定的约定格式进行解析;

    webservice的网站可以在webxml.com.cn可以查看下一些免费service服务

    Socket实现服务调用:
    socket是可以实现服务之间的调用,socket的服务调用使用的是TCP/IP协议,传递的是流,服务端与客户端之间可以自定义传输规范,适用于并发高,大数据量的传输;

    socket服务调用与webservice的比较:
    传输协议:socket是使用的是TCP/IP协议,而webservice使用的是http协议,TCP/IP协议是在传输层,http协议是在网络层;

    传递对象:socket是传输的是流,而不接受面向对象,而webservice对传输队形进行序列化以流的形式进行传输;
    webservice使用的是soap协议进行传输(soap=http+xml),不需要专门对数据流进行处理,

    处理场景适用: socket适用于高并发,大数据量的传输,但是传输客户端与服务端之间的协议形式需要自己定义;传输数据、格式及解析及发送数据需要程序员自己去定义,接收数据解析数据需要一一对应;socket的灵活性比较大

    webservice遵循soap协议,soap=http+xml 更加适用于边界外系统之间的调用,一般传输量比较小,已经被纳入W3C的管理,更规范;

    webservice是不需要专门针对传输流进行处理的,只要定义好输入就可以;jaxws可以通过面向对象开发webservice;

    webservice客户端的实现方式:

    通过wximport生成代码–wximport生成代码是原始的wsdl的方式实现webservice的调用;

    通过客户端编程方式–客户端编程方式引用httpClient客户端,自己构建发送参数,发送格式,发送数据;
    通过ajax调用方式----构建soap规范的xml发送数据,调用服务返回结果;
    通过 URL Connection 方式调用 —jdk的原生调用

    webservice服务端的发布方式:

    https://wenku.baidu.com/view/48f0bebb804d2b160a4ec0b9.html参考文档:

    cxf方式,目前比较流行的方式:
    xfire方式发布;
    axis2发布
    axis1发布

    展开全文
  • webService

    2011-11-29 12:28:44
    c# webServiceDemo,webService创建、webService发布、webService调用(winForm)
  • WebService入门详解

    万次阅读 多人点赞 2016-05-13 13:41:14
    1.什么是webservice先来考虑一个问题,如果我们要在自己的程序里面展示天气预报,那怎么弄?正确的做法是我们发送一个请求到一个系统,他会给我们返回来天气情况。这个就是一个webservice。天气预报系统就相当于...

    1、什么是webservice

    先来考虑一个问题,如果我们要在自己的程序里面展示天气预报,那怎么弄?正确的做法是我们发送一个请求到一个系统,他会给我们返回来天气情况。这个就是一个webservice。天气预报系统就相当于webservice的服务端,我们的系统就相当于客户端。如http://www.webxml.com.cn这个网站上面就列举了多个webservice服务站点

    2、JAVA中如何调用别人发布的webservice

    2.1、获取webservice的wsdl文档

    2.11、什么是wsdl文档

    wsdl跟java一样,也是一种语言,是通过xml的形式说明该webservice如何调用。

    2.12、如何获取wsdl文档

    通过在webservice的url后面加?wsdl的方式,比如天气预报的的就是http://ws.webxml.com.cn/WebServices/WeatherWS.asmx?wsdl

    2.13、WSDL解析

    Wsdl文档从下往上读
    Types - 数据类型定义的容器,它使用某种类型系统(一般地使用XML Schema中的类型系统)。(入参和出参的数据类型)
    Message - 通信消息的数据结构的抽象类型化定义。使用Types所定义的类型来定义整个消息的数据结构(入参和出参)。
    Operation - 对服务中所支持的操作的抽象描述,一般单个Operation描述了一个访问入口的请求/响应消息对(方法)。
    PortType - 对于某个访问入口点类型所支持的操作的抽象集合,这些操作可以由一个或多个服务访问点来支持(服务类)。
    Binding - 特定服务访问点与具体服务类的绑定(不看内容,看关系)。
    Port - 定义为webservice单个服务访问点。
    Service- 相关服务访问点的集合。

    2.2、通过wsdl文档生成客户端调用代码

    2.21、使用jdk自带的命令生成

    配置java环境变量后在命令窗口中输入wsimport –s . http://xxxx.xx.xx/xxx?wsdl即可生成java代码
    注意:-s不能分开,-s后面有个小点,用于指定源代码生成的目录。点即当前目录。如果使用了-s参数则会在目录下生成两份代码,一份为.class代码。一份为.java代码。.class代码,可以经过打包以后使用。.java代码可以直接Copy到我们的项目中运行
    注意:可能会报错解析组件 ‘s:schema’ 时出错。在该组件中检测到 's:schem’之类的,如果报错这个请移步:这里

    2.3、生成代码后如何调用

    先把生成的代码复制到项目中,然后通过读wsdl文档来调用,整体的调用代码类似于下面这样

    //wsdl文档中service的name
    SayHelloIntefaceService ss = new SayHelloIntefaceService();
    //wsdl文档中portType的name
    SayHelloInteface shf=ss.getSayHelloIntefacePort();
    //wdl文档中complexType的name
    String str=shf.sayhellow("lisi");
    //str即为webservice的服务端返回的信息
    System.out.println(str);
    

    3、一个关于WebService的Demo

    3.1、服务端

    package com.bxoon;
    
    import javax.jws.WebMethod;
    
    
    public interface WebServiceI {
    
        @WebMethod(exclude=true)
        String helloWord(String name);
    
        @WebMethod(exclude=true)
        String helloWord2(String name);
    
    }
    
    
    package com.bxoon;
    
    
    import javax.jws.WebService;
    import javax.xml.ws.Endpoint;
    
    
    @WebService
    public class HelloWebService implements WebServiceI {
    
    
        @Override
        public String helloWord(String name) {
            return"Hello: "+name;
        }
    
        @Override
        public String helloWord2(String name){
            return"Hello: "+name;
        }
    
        public static void main(String[] args) {
            Endpoint.publish("http://127.0.0.1:8080/helloWord",new HelloWebService());
        }
    
    }
    
    

    3.2 客户端

    服务端启动之后通过访问http://127.0.0.1:8080/helloWord?wsdl来得到一个wsdl文档,类似于如下
    在这里插入图片描述
    然后通过命令

    wsimport -s . http://127.0.0.1:8080/helloWord?wsdl
    

    来生成具体的代码,生成的代码类似于
    在这里插入图片描述
    我们把对应的java类copy到客户端项目中,得到这样的目录结构
    在这里插入图片描述
    然后我们编写图中的Client类,代码如下

    package com.bxoon;
    
    public class Client {
    
        public static void main(String[] args) {
            HelloWebServiceService service = new HelloWebServiceService();
            HelloWebService webService = service.getHelloWebServicePort();
            String result = webService.helloWord("11");
            System.out.println(result);
        }
    }
    
    

    运行之后输出结果

    Hello: 11
    

    到此,一个简单的WebService的helloword程序就完成了,下面对具体的代码进行解释。

    用Jdk1.6.0_21以后的版本发布一个WebService服务.与Web服务相关的类,都位于javax.xml.ws.*包中。
    主要类有:
    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)屏蔽方法

    4、其他调用webservice的方式

    这里只写了一种最基本的调用webService的方式,实际上调用webService有很多种方式,下面一一介绍。

    4.11、 使用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)
    			
    		}
    	}
    }
    

    4.12、通过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());
    	}
    }
    

    4.13、使用jquery调用cxf

    $(function(){
    		$("#mybutton").click(function(){
    			var data = '<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:q0="http://server.web.cxf.rl.com/" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">'
    				  +'<soapenv:Body>'
    				  +'<q0:sayHello>'
    				  +'   <arg0>sss</arg0>'
    				  +' </q0:sayHello>'
    				  +'</soapenv:Body>'
    				  +'</soapenv:Envelope>';
    				  
    				$.ajax({
    					url:'http://localhost:8080/cxf-web-server/services/hello',
    					type:'post',
    					dataType:'xml',
    					contentType:'text/xml;charset=UTF-8',
    					data:data,
    					success:function(responseText){
    						alert($(responseText).find('return').text());
    					},
    					error:function(){
    						alert("error");
    					}
    				})
    		})
    	})
    

    5、wsdl文档元素名称修改

    有时,自动生成的WSDL文档的名字可能不规范,我们是可以自定义的。在注解@webservice中可以指定一些属性来完成这个功能。

    @WebService(
    	portName="myHelloService",修改端口名字
    	serviceName="HelloServices",修改服务访问点集合名字
    	name="HelloService",修改服务类的名字
    	targetNamespace="hello.rl.com" 修改命名空间名字
    )
    

    或者使用如下方式

    @WebResult(name="sirHello")修改返回值的元素的父标签名字
    @WebParam(name="sir")修改传入参数的元素的父标签名字
    

    6、其他发布WebService的方式

    其实上面说的使用jdk自带的方式发布WebService只是众多发布WebService的方式中的一种。现阶段发布方式主要有以下5种

    1. CXF(常用)
    2. Xfire(比较古老)
    3. Axis2 (常用)
    4. Axis1
    5. HttpClient
      jws的发布对java webservice框架产生了巨大的影响,经过大浪淘沙,目前java开发webservice的框架主要包括axis2和cxf。
      这篇文章介绍了发布WebService的多种方式以及实现,

    下面对cxf和Axis2的使用方式做基本介绍,其他方式请自行寻找资料

    6.1 CXF

    6.1.1、什么是cxf

    CXF全称Apache CXF,是apache基金会的一个为了简化webService开发的框架,可以让WebService的发布和调用更加简单。

    Apache CXF = Celtix + Xfire

    Apache CXF支持多种协议:
    a) SOAP1.1,1,2
    b) HTTP
    c) CORBA(Common Object Request Broker Architecture公共对象请求代理体系结构,早期语言使用的WS。C,c++,C#)
    d) 并可以与Spring进行快速无缝的整合
    e) 灵活的部署:可以运行有Tomcat,Jboss,Jetty(内置),IBMWS,BeaWS上面。

    6.1.2、cxf目录详解(了解)

    bin(目录)
    bin 目录中是 CXF 框架中所提供的代码生成、校验、管理控制台工具(可执行命令)

    docs(目录)
    CXF 所有类(class)对应的 API 文档,为开发者使用 CXF 完成应用开发提供应有的帮助。

    etc(目录)
    包含一个基本的 Service 暴露所需要的 web.xml 文件,及其它的配置文件。

    lib(目录)
    lib 目录中包含 CXF 及其运行时所需要的和可选的第三方支持类包(.jar 文件),可以根据不同项目所需的 CXF 特性选择所需要的支持类包。如果不想一一去区分的话,可
    以直接在 Web 项目中包含所有的 CXF 及其运行时所需要的第三方支持类包(.jar 文件)即可。
    其中 cxf-2.0.2-incubator.jar 是 CXF 框架的二进制包文件,包含了全部的模块(modules),cxf-manifest-incubator.jar 是列表清单文件 manifest jar 。

    以下的 jar 包是所有 CXF 项目所必需的:
    cxf.jar
    commons-logging.jar
    geronimo-activation.jar (Or the Sun equivalent)
    geronimo-annotation.jar (Or the Sun equivalent)
    geronimo-javamail.jar (Or the Sun equivalent)
    neethi.jar
    jaxb-api.jar
    jaxb-impl.jar
    stax-api.jar
    XmlSchema.jar
    wstx-asl.jar
    xml-resolver.jar

    对于 Java2WSDL 和 WSDL2Java,除了必需的之外,还需要再增加如下 jar 包:
    jaxb-xjc.jar
    veliocity.jar
    velocity-dep.jar

    为了支持 JAX-WS ,除了必需的之外,还需要再增加如下 jar 包:
    jaxws-api.jar
    saaj-api.jar
    saaj-impl.jar
    asm.jar (可选的,但是可以提升包装类型的性能)

    为了支持 XML 配置,除了必需的之外,还需要再增加如下 jar 包:aopalliance.jar
    spring-beans.jar
    spring-context.jar
    spring-core.jar
    spring.web.jar

    为了独立的 HTTP 服务支持,除了必需的之外,还需要再增加如下 jar 包:geronimo-servlet.jar
    jetty.jar
    jetty-sslengine.jar
    jetty-util.jar
    sl4j.jar & sl4j-jdk14.jar (可选的,但是可以提升日志 logging)

    为了支持 Aegis ,除了必需的之外,还需要再增加如下 jar 包:
    jaxen.jar
    jdom.jar
    stax-utils.jar

    为了支持 WS-Security ,除了必需的之外,还需要再增加如下 jar 包:bcprov-jdk14.jar
    wss4j.jar
    xalan.jar
    xmlsec.jar

    为了支持 HTTP Binding ,除了必需的之外,还需要再增加如下 jar 包:jra.jar
    jettison.jar (仅为 JSON 服务所需的)

    licenses(目录)
    列表了引用第三方 jar 包的相关许可协议。

    modules(目录)
    modules 目录中包含了 CXF 框架根据不同特性分开进行编译的二进制包文件。发布基于 CXF 框架的 Web 项目时,可以选择使用该目录下的所有 .jar 文件,也可以选择 lib 目 录中的 cxf-2.0.2-incubator.jar 文件。

    samples(目录)
    samples 目录中包含了所有随 CXF 二进制包发布的示例,包含这些示例的源代码和相关 Web 应用配置文件,可以方便地用 Ant 来编译运行测试这些示例,来了解 CXF 的开发和

    使用的方法。可以通过 samples 目录和它各个子目录下的 README.txt 的文件来详细了解示例的编译与运行的步骤。

    6.1.3、使用cxf发布webservice

    6.1.3.1、把cxf目录下lib下面的包全部加入到项目中

    6.1.3.2、编写代码

    1、创建接口
    @WebService
    @BindingType(value=javax.xml.ws.soap.SOAPBinding.SOAP12HTTP_BINDING)
    public interface SayHelloInteface {
    	public String sayhellow(String name);
    }
    
    2、创建实现类
    @WebService
    public class SayHellowIntefaceImpl implements SayHelloInteface {
    
    	@Override
    	public String sayhellow(String name) {
    		return name+"hello world";
    	}
    }
    
    3、使用cxf类发布
    public static void main(String[] args) {
    	//运行
    	JaxWsServerFactoryBean jwsf=new JaxWsServerFactoryBean();
    	//CXF拦截器
    	jwsf.getInInterceptors().add(new LoggingInInterceptor());
    	jwsf.getOutInterceptors().add(new LoggingOutInterceptor());
    
    	jwsf.setAddress("http://127.0.0.1:8080/sayHello");
    	jwsf.setServiceClass(SayHelloInteface.class);
    	jwsf.setServiceBean(new SayHellowIntefaceImpl());
    	jwsf.create();
    }
    

    6.1.4、使用cxf的wsdl2java命令生成客户端代码

    wsdl2java –d . http://127.0.0.1:6666/helloworld?wsdl

    6.1.5、调用

    调用方式不变

    SayHelloIntefaceService ss = new SayHelloIntefaceService();
    SayHelloInteface shf=ss.getSayHelloIntefacePort();
    String str=shf.sayhellow("lisi");
    System.out.println(str);
    

    6.2使用Axis2创建WebService服务

    http://www.blogjava.net/tianchijiaozi/archive/2013/03/15/396452.html#Post

    7、在web项目中发布webservice

    上面是介绍了如何通过Main方法启动WebService,但在实际项目中不可能是采用main方法来启动的,那么如何在项目启动的时候启动一个WebService呢?下面介绍

    1. 创建服务接口在接口上加@webservice

    2. 创建服务接口的实现类

    3. 在web.xml中配置CXFServlet

      <!DOCTYPE web-app PUBLIC "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN" "http://java.sun.com/dtd/web-app_2_3.dtd">
      <web-app>
          <servlet>
              <servlet-name>cxf</servlet-name>
              <servlet-class>org.apache.cxf.transport.servlet.CXFServlet</servlet-class>
          </servlet>
          <servlet-mapping>
              <servlet-name>cxf</servlet-name>
              <url-pattern>/services/*</url-pattern>
          </servlet-mapping>
          <session-config>
              <session-timeout>60</session-timeout>
          </session-config>
      </web-app>
      
    4. 配置cxf-servlet.xml

      <jaxws:server id="bye" address="/bye" serviceClass="com.rl.cxf.web.inter.ByeInter">
      	<jaxws:serviceBean>
      		<bean class="com.rl.cxf.web.inter.ByeInterImpl"></bean>
      	</jaxws:serviceBean>
      	<jaxws:outInterceptors>
      		<bean class="org.apache.cxf.interceptor.LoggingInInterceptor"></bean>
      	</jaxws:outInterceptors>
      	<jaxws:inInterceptors>
      		<bean class="org.apache.cxf.interceptor.LoggingOutInterceptor"></bean>
      	</jaxws:inInterceptors>
      </jaxws:server>
      
    5. 使用wsdl2java生成客户端代码

    6. 调用webservice

    8.WebService的工作原理

    再说WebService之前这里先说说RPC,什么是RPC呢?

    RPC(Remote Procedure Call),远程过程调用,它是一种通过网络从远程计算机程序上请求服务,而不需要了解底层网络技术的协议。(来自百度百科)
    

    简单来说RPC是java中远程调用的一种技术或者约定,并不是一种具体的解决方案或者框架,而具体的框架有下面这些比较火的(排名不分先后)

    1. SpringCloud(Spring的,基于Socket的,SOA架构的分布式框架)
    2. Dubbo(x)(阿里巴巴的,基于Socket的,SOA架构的分布式框架)
    3. WebService(跨语言的,基于SOAP协议,走xml数据或json数据)
    4. Hessian(跨语言的,基于Binary-RPC协议,走二进制数据)
    5. HttpClient(通常用于RESTful风格的调用,跨语言,基于http和json)
    6. jdk原生(HttpURLConnection)

    我们上面用的就是jdk原生的这种。本文也主要对这种方式的工作原理做简单解析,原理大概分为以下几个步骤

    1. Service端会在程序启动的时候扫描有标注@WebService的类,然后通过反射方法找到这个类的需要发布的方法,然后在用户访问wsdl文档的时候把这些东西组成SOAP协议内容然后返回给用户浏览器,用户就可以得到wsdl文档。同时服务端在启动的时候会启动一个socket用来等待客户端的连接。
    2. 客户端通过wsdl文档生成了代码然后在程序里面调用,实际上是通过了一个socket发送了一个请求给服务端,请求里面有指明客户端需要调用哪个类的哪个方法,以及请求参数,请求报文类似于
    <soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">  
       <soap:Body>  
           <ns1:getWeather xmlns:ns1="http://fixed.adapter.solar2.erayt.com/">  
               <arg0>2013-06-22T18:56:43.808+08:00</arg0>  
           </ns1:getWeather>  
       </soap:Body>  
    </soap:Envelope>  
    

    Webservice的通讯协议是SOAP。

    8.1 SOAP协议

    SOAP=http+xml、下面看一个SOAP的报文示例
    在这里插入图片描述
    可以很清楚的看到SOAP就只是把http的报文体换成了XML。

    1. 上诉XML中描述了客户端需要调用哪个类的那个方法,服务端接收到客户端的请求之后,通过对应的信息以及参数反射调用具体的方法,最后把调用结果返回给客户端。

    自此,整个WebService的调用执行完毕,客户端成功的通过远程调用的方式执行到了服务端的代码并拿到了返回值,这就是RPC
    如果对笔者所述有所不明了,可以看看JAVA高级开发—webservice原理分析视频

    展开全文
  • webservice测试调用工具 WebserviceStudio20 测试调用webservice
  • 我的第一次WebService接口开发

    万次阅读 多人点赞 2019-05-09 16:58:09
    最近项目上需要对接WebService接口,之前从来没有用过,这次都遇见了。记录下基础的使用和我遇见的问题。 正文 概述 WebService接口百度一搜,各个介绍的都非常详细,由于刚开始没接触,看的也不是很懂。首先记住一...

    前言

    最近项目上需要对接WebService接口,之前从来没有用过,这次都遇见了。记录下基础的使用和我遇见的问题。
    如果是报错找答案的,建议直接查看最后 “遇见的问题” 或搜索文章内容查看对应的问题。

    正文

    概述

    WebService接口百度一搜,各个介绍的都非常详细,由于刚开始没接触,看的也不是很懂。首先记住一句话:WebService是一种跨编程语言和跨操作系统平台的远程调用技术。
    跨编程语言和跨操作系统平台:也就是说Asp.net开发的WebService用java代码调用完全没问题,和操作系统也没有关系。
    远程调用技术:也就是说网络是通的就能用。
    那么这个WebService到底是干嘛用的?

    作用

    不同系统之间进行对接!比如现在需要使用第三方公司的短信服务,使用WebService来调用它的服务,只需要第三方公司提供一个接口调用文档和WebService地址,就能根据文档地址编程去调用它开放的短信服务,发送短信。为什么是WebService?

    优缺点

    回到那句话,WebService是一种跨编程语言和跨操作系统平台的远程调用技术。
    优点:
    1.跨语言和跨操作系统:因为WevService是通过Xml语言进行描述的,XML主要的优点在于它既与平台无关,又与厂商无关。
    2.远程调用技术:不用担心防火墙的问题。。。
    缺点:
    1.服务端接口方为webservice则客户端也必须使用webservice。
    2.因为webservice使用xml传输数据,因此性能上不能满足高并发。
    3.有点笨重。。。
    其实WebService并不是非常流行,往往RESTful就能够达到需要,但是遇到了笔记还是要做的。

    使用

    只介绍对接WebService接口,生成请自行百度。
    这次对接了java的WebService接口和C#写的WebService接口。

    CXF 调用java WebService

    首先看看提供的WebService接口地址:http://127.0.0.1:8080/jjh/webService/smsXXX?wsdl
    一般都是给到这种地址,访问地址可以看到这个接口的xml描述,可以通过这个描述来生成java代码到本地来方便使用,比如一些实体类,service方法。
    准确的来说可以使用JDK自带的和CXF提供的命令,直接生成java代码,这里只建议使用Apach的CXF,直接去官网下载最新的cxf包,进入bin目录下,打开命令窗口,使用cxf命令生成java代码,这里提供一个最基础的:wsdl2java -encoding utf-8 http://127.0.0.1:8080/jjh/webService/smsXXX?wsdl
    执行之后你的bin目录下面会生成java文件,有了java文件下面就可以根据java文件和第三方给的文档进行调用了。
    比如,生成了IhalloWorld.java和IService.java文件,发现IhalloWorld接口里面声明了sendSms(args…)方法。

    public static void main(String[] args) {  
            JaxWsProxyFactoryBean factoryBean = new JaxWsProxyFactoryBean();  
            //要得到的对象,是根据本地IService 接口取得的。
            factoryBean.setServiceClass(IService .class);  
            //调用地址
            factoryBean.setAddress("http://127.0.0.1:8080/jjh/webService/smsXXX");  
            //通过webservice取到IService的实现类,这个实现类才是你真正想要的,里面包括了你需要的东西。
            IService service = (IService)factoryBean.create();  
            IhalloWorld hello = service.getHelloWorld("xxx");  
            System.out.println("Hello:"+hello.sendSms("XXX你好..."));  
        }  
    

    参考链接:
    JAVA webservice之CXF
    WebService学习整理-JDK的wsimport命令和cxf的wsdl2java命令的区别和使用
    java接口调用——webservice就是一个RPC而已
    cxf的wsdl2java命令和JDK的wsimport命令的区别和使用

    asmx

    下面又对接了一个C#写的WebService接口,比如链接为:http://127.0.0.1:81/WebServiceCS/service.asmx ,在这个链接后面加上?wsdl,即:
    http://127.0.0.1:81/WebServiceCS/service.asmx?wsdl 也是可以使用cxf生成java代码的,但是注意一点,这接口是C#写的,xml只描述出实体信息,生成类似实体类的文件,没有现成的接口使用。一般其实也用不到cxf来生成,作用不大。参考例子:

    public String sendMail(Object[] params) {
        String soapaction = "http://tempuri.org/"; // 域名,这是在server定义的,在链接里面看得到,下面介绍。
        String operationName = "Mail_Send";// 调用服务名
        Service service = new Service();
        String ret = "";
        try {
            Call call = (Call) service.createCall();
            call.setTargetEndpointAddress(url);
            call.setOperationName(new QName(soapaction, operationName)); // 设置要调用的方法
            call.addParameter(new QName(soapaction, "vvvv"), // 需要传递的参数名
                    org.apache.axis.encoding.XMLType.XSD_STRING,
                    javax.xml.rpc.ParameterMode.IN);
            call.addParameter(new QName(soapaction, "jjj"), // 需要传递的参数名
                    org.apache.axis.encoding.XMLType.XSD_STRING,
                    javax.xml.rpc.ParameterMode.IN);
            call.setReturnType(org.apache.axis.encoding.XMLType.XSD_STRING);// (标准的返回类型)
            call.setUseSOAPAction(true);
            call.setSOAPActionURI(soapaction + operationName);//url,域名加方法名
            ret = (String) call.invoke(params);// 调用方法并传递参数,params包含参数
        } catch (Exception ex) {
            ex.printStackTrace();
        }
        return ret;
    }
    
    

    其中operationName服务名和soapaction域名都在你的链接中可以找到 http://127.0.0.1:81/WebServiceCS/service.asmx
    在这里插入图片描述
    其中参数params数组根据你服务需要的参数来传,比如需要一个规范的xml字符串作为参数,使用dom4j进行操作。

            Document doc = DocumentHelper.createDocument();
            //增加根节点
            Element books = doc.addElement("books");
            //增加子元素
            Element book1 = books.addElement("book");
            Element title1 = book1.addElement("title");
            Element author1 = book1.addElement("author");
    
            Element book2 = books.addElement("book");
            Element title2 = book2.addElement("title");
            Element author2 = book2.addElement("author");
    
            //为子节点添加属性
            book1.addAttribute("id", "001");
            //为元素添加内容
            title1.setText("Harry Potter");
            author1.setText("J K. Rowling");
    
            book2.addAttribute("id", "002");
            title2.setText("Learning XML");
            author2.setText("Erik T. Ray");
    
            OutputFormat format = OutputFormat.createCompactFormat();
            format.setIndent(true); //设置是否缩进
            format.setIndent("    "); //以四个空格方式实现缩进
            format.setNewlines(true); //设置是否换行
    
            //设置输出编码
            format.setEncoding("gb2312");
            StringWriter writer = new StringWriter();
            XMLWriter output = new XMLWriter(writer, format);
            try {
                output.write(doc);
                writer.close();
                output.close();
                System.out.println(writer.toString());//打印xml字符串
            }  catch (IOException e) {
                e.printStackTrace();
            }
    

    打印结果
    在这里插入图片描述

    参考链接:
    Java调用webservice的.asmx后缀接口
    java调用webservice接口(.asmx)

    遇见的问题

    说实话开发起来挺快的,毕竟人家提供接口,东西都是现成的,最要命的问题就是报错了。

    导包

    包没导好,错少不了,可以参考这个博主的包导一导试试java调用webservice接口(.asmx),遇见报错不要慌,参考一下这个解决:WebService几个常见的异常
    我这里遇到的一个问题就是:
    java.lang.NoClassDefFoundError: Could not initialize class org.apache.axis.client.AxisClient
    我是由于commons-logging.jar包依赖版本冲突导致的,commons-discovery.jar包里面依赖了commons-logging包,但是,我自己导了commons-logging包,我的解决是排查commons-discovery对commons-logging的依赖:

            <dependency>
                <groupId>commons-discovery</groupId>
                <artifactId>commons-discovery</artifactId>
                <version>0.5</version>
                <exclusions>
                    <exclusion>
                        <groupId>commons-logging</groupId>
                        <artifactId>commons-logging</artifactId>
                    </exclusion>
                </exclusions>
            </dependency>
            <dependency>
                <groupId>commons-logging</groupId>
                <artifactId>commons-logging</artifactId>
                <version>1.2</version>
            </dependency>
    

    参考的java.lang.NoClassDefFoundError博客。
    接下来我又遇见了新的问题,弄了很久:由于我上面用了CXF,引入了一些包和我现在调.asmx接口axis2引入包又版本冲突了,,,,这个真的没找到,项目一调用CXF的那个接口就报错:
    java.lang.RuntimeException: Cannot create a secure XMLInputFactory
    网上找了找解决办法:
    1.有说缺少包,导入woodstox-core-asl-4.4.1.jar和stax2-api-3.1.4.jar包。
    2.woodstox-core-asl包需要优先被加载,修改tomcat下,这个包在lib文件夹的名字,因为tomcat是按顺序来加载的,woodstox-core-asl改名为awoodstox-core-asl,让它优先加载。
    参考:
    解决 调用报错: “Cannot create a secure XMLInputFactory”
    java.lang.RuntimeException: Cannot create a secure XMLInputFactory解决方案

    但是,上面两个都没解决我的问题,我感觉原因还是版本冲突了,,,
    最后我找到了一个解决方法:
    CXF报安全性错误 Cannot create a secure XMLInputFactory
    大佬就是大佬,然后我就调用之前添加了这行代码:

    	System.setProperty(StaxUtils.ALLOW_INSECURE_PARSER, "true");
    

    完美,但是这个版本冲突估计是没救了,依赖太多了。
    idea插件没解决掉,然后查看maven依赖树来解决:
    我以为的maven依赖图是这样的(一览无余):
    在这里插入图片描述
    实际上是这样的:
    在这里插入图片描述
    对不起,一览无余,打扰了。。。能力有限,版本冲突我干不掉了。
    之前组长是建议我添加一个简单的web项目,里面只部署CXF 对接的接口供我项目调用,这样两个接口依赖的包就不会在一块有版本冲突了,我觉得这个方法还是很赞的!!!

    后续

    后面项目部署到tomcat上面,发现jar包还是冲突啦!!!
    大概错误就是这样

    Caused by: java.lang.NoSuchFieldError: REFLECTION
    
    at com.sun.xml.bind.v2.model.impl.RuntimeModelBuilder.<init>(RuntimeModelBuilder.java:43)
     
    at com.sun.xml.bind.v2.runtime.JAXBContextImpl.getTypeInfoSet(JAXBContextImpl.java:344)
     
    at com.sun.xml.bind.v2.runtime.JAXBContextImpl.<init>(JAXBContextImpl.java:216)
     
    at com.sun.xml.bind.v2.ContextFactory.createContext(ContextFactory.java:76)
     
    at com.sun.xml.bind.v2.ContextFactory.createContext(ContextFactory.java:55)
     
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
     
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
     
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
     
    at java.lang.reflect.Method.invoke(Method.java:498)
     
    at javax.xml.bind.ContextFinder.newInstance(ContextFinder.java:247)
     
    at javax.xml.bind.ContextFinder.newInstance(ContextFinder.java:234)
     
    at javax.xml.bind.ContextFinder.find(ContextFinder.java:441)
     
    at javax.xml.bind.JAXBContext.newInstance(JAXBContext.java:641)
     
    at javax.xml.bind.JAXBContext.newInstance(JAXBContext.java:584)
    
    

    一番搜索后参照:
    stackoverflow
    java.lang.NoSuchFieldError: REFLECTION
    发现是com.sun.xml.bind:jaxb-core和com.sun.xml.bind:jaxb-impl****两个包版本号不一致造成的冲突。首先查看jar包的依赖情况,使用idea查看依赖树,运行maven命令 mvn dependency:tree。
    在这里插入图片描述
    不使用idea也一样,在pom文件位置打开cmd面板,如下图,在路径处输入cmd回车,执行maven命令 mvn dependency:tree。
    在这里插入图片描述
    查看jar包依赖情况:
    在这里插入图片描述
    在这里插入图片描述
    分别搜索jaxb-impljaxb-core,发现它们是jar包axis2-jaxwscxf-rt-frontend-jaxws分别依赖的子包。版本号分别是2.1.7和2.2.11,我这里是取消了axis2-jaxws对jaxb-impl的依赖单独配置jaxb-impl的依赖,指定版本号和jaxb-core一致2.2.11
    在这里插入图片描述
    最后将打包后的jaxb相关包替换在tomcat的包,使得版本一致,到此版本冲突问题解决。

    参考地址集合

    JAVA webservice之CXF
    WebService学习整理-JDK的wsimport命令和cxf的wsdl2java命令的区别和使用
    java接口调用——webservice就是一个RPC而已
    cxf的wsdl2java命令和JDK的wsimport命令的区别和使用

    Java调用webservice的.asmx后缀接口
    java调用webservice接口(.asmx)

    WebService几个常见的异常
    java.lang.NoClassDefFoundError

    解决 调用报错: “Cannot create a secure XMLInputFactory”
    java.lang.RuntimeException: Cannot create a secure XMLInputFactory解决方案

    CXF报安全性错误 Cannot create a secure XMLInputFactory

    stackoverflow
    java.lang.NoSuchFieldError: REFLECTION
    maven dependency:tree中反斜杠的含义
    如何查看Maven项目中的jar包依赖树情况?

    展开全文
  • gambleing webservice

    2018-05-21 00:27:46
    gambleing webservice gambleing webservice gambleing webservice
  • springboot+webservice搭建webservice服务端及使用java客户端两种方式进行调用
  • c# 调用webservice 实例
  • webservice摘录webservice摘录webservice摘录webservice摘录webservice摘录webservice摘录webservice摘录webservice摘录webservice摘录质
  • webservice测试调用工具WebserviceStudio20
  • springboot+webservice搭建webservice服务端及使用java客户端两种方式进行调用webservice接口
  • webservice测试工具,webservice调试工具,非常好用的工具,开发webservice必备工具
  • webService DEMO

    2018-05-29 15:30:54
    webService DEMO,一个超级简单的webservice demo,方便大家交流学习
  • oracle 调用webservice

    2021-04-03 06:00:16
    oracle 调用 webservice 实现 oracle 调用 webservice 实现 oracle 调用 webservice 实现 oracle 调用 webservice 实现
  • WebService技术详解 (一)

    万次阅读 多人点赞 2017-07-25 18:01:18
    WebServiceWebService简介Web Service技术, 能使得运行在不同机器上的不同应用无须借助附加的、专门的第三... 简单的说,WebService就是一种跨编程语言和跨操作系统平台的远程调用技术。所谓跨编程语言和跨操作平台,

    WebService

    WebService简介

    Web Service技术, 能使得运行在不同机器上的不同应用无须借助附加的、专门的第三方软件或硬件, 就可相互交换数据或集成。依据Web Service规范实施的应用之间, 无论它们所使用的语言、 平台或内部协议是什么, 都可以相互交换数据。

    简单的说,WebService就是一种跨编程语言和跨操作系统平台的远程调用技术。所谓跨编程语言和跨操作平台,就是说服务端程序采用java编写,客户端程序则可以采用其他编程语言编写,反之亦然。跨操作系统平台则是指服务端程序和客户端程序可以在不同的操作系统上运行。 远程调用,就是一台计算机的应用可以调用其他计算机上的应用。例如:支付宝,支付宝并没有银行卡等数据,它只是去调用银行提供的接口来获得数据。还有天气预报等,也是气象局把自己的系统服务以webservice服务的形式暴露出来,让第三方网站和程序可以调用这些服务功能。

    WebService原理

    XML,SOAP和WSDL就是构成WebService平台的三大技术 。

    • WebService采用Http协议来在客户端和服务端之间传输数据。WebService使用XML来封装数据,XML主要的优点在于它是跨平台的。

    • WebService通过HTTP协议发送请求和接收结果时,发送的请求内容和结果内容都采用XML格式封装,并增加了一些特定的HTTP消息头,以说明HTTP消息的内容格式,这些特定的HTTP消息头和XML内容格式就是SOAP协议规定的。

    • WebService服务器端首先要通过一个WSDL文件来说明自己有什么服务可以对外调用。简单的说,WSDL就像是一个说明书,用于描述WebService及其方法、参数和返回值。 WSDL文件保存在Web服务器上,通过一个url地址就可以访问到它。客户端要调用一个WebService服务之前,要知道该服务的WSDL文件的地址。WebService服务提供商可以通过两种方式来暴露它的WSDL文件地址:1.注册到UDDI服务器,以便被人查找;2.直接告诉给客户端调用者。

    WebService交互的过程就是,WebService遵循SOAP协议通过XML封装数据,然后由Http协议来传输数据。

    JAVA WebService规范

    Java 中共有三种WebService 规范,分别是JAXM&SAAJ、JAX-WS(JAX-RPC)、JAX-RS。

    (1)JAX-WS:

    JAX-WS(Java API For XML-WebService)。早期的基于SOAP 的JAVA 的Web 服务规范JAX-RPC(java API For XML-Remote Procedure Call)目前已经被JAX-WS 规范取代,JAX-WS 是JAX-RPC 的演进版本,但JAX-WS 并不完全向后兼容JAX-RPC,二者最大的区别就是RPC/encoded 样式的WSDL,JAX-WS 已经不提供这种支持。JAX-RPC 的API 从JAVA EE5 开始已经移除,如果你使用J2EE1.4,其API 位于javax.xml.rpc.包。JAX-WS(JSR 224)规范的API 位于javax.xml.ws.包,其中大部分都是注解,提供API 操作Web 服务(通常在客户端使用的较多,由于客户端可以借助SDK 生成,因此这个包中的API 我们较少会直接使用)。

    (2)JAXM&SAAJ:

    JAXM(JAVA API For XML Message)主要定义了包含了发送和接收消息所需的API,相当于Web 服务的服务器端,其API 位于javax.messaging.*包,它是Java EE 的可选包,因此你需要单独下载。

    SAAJ(SOAP With Attachment API For Java,JSR 67)是与JAXM 搭配使用的API,为构建SOAP 包和解析SOAP 包提供了重要的支持,支持附件传输,它在服务器端、客户端都需要使用。这里还要提到的是SAAJ 规范,其API 位于javax.xml.soap.*包。

    JAXM&SAAJ 与JAX-WS 都是基于SOAP 的Web 服务,相比之下JAXM&SAAJ 暴漏了SOAP更多的底层细节,编码比较麻烦,而JAX-WS 更加抽象,隐藏了更多的细节,更加面向对象,实现起来你基本上不需要关心SOAP 的任何细节。那么如果你想控制SOAP 消息的更多细节,可以使用JAXM&SAAJ。

    (3)JAX-RS:

    JAX-RS 是JAVA 针对REST(Representation State Transfer)风格制定的一套Web 服务规范,由于推出的较晚,该规范(JSR 311,目前JAX-RS 的版本为1.0)并未随JDK1.6 一起发行。

    WebService入门案例

    服务端的实现

    我们来实现一个天气系统的案例,客户端发送城市名称,服务器端回应相应的天气。

    1.  编写SEI(Service Endpoint Interface),SEI在webservice中称为portType,在java中就是普通接口 
    
    public interface WeatherInterface {
        public String queryWeather(String cityName);
    }
    
    2.  编写SEI实现类,此类作为webservice提供服务类 
    
    @WebService     //@WebService表示该类是一个服务类,需要发布其中的public的方法
    public class WeatherInterfaceImpl implements WeatherInterface {
    
        @Override
        public String queryWeather(String cityName) {
            System.out.println("获取城市名"+cityName);
            String weather="暴雨";    
            return weather;
        }
    
    }
    3.  第三步:发布服务,Endpoint类发布服务,publish方法,两个参数:1.服务地址;2.服务实现类 
    
    public class WeatherServer {
        public static void main(String[] args) {
            Endpoint.publish("http://127.0.0.1:12345/weather", new WeatherInterfaceImpl());
        }
    }
    
    4. 测试服务是否发布成功,通过阅读wsdl,确定客户端调用的接口、方法、参数和返回值存在,证明服务发布成功
    
    //我们在浏览器输入 http://127.0.0.1:12345/weather?wsdl 来获取wsdl文件进行阅读
    
    //wsdl,是以XML文件形式来描述WebService的”说明书”,有了说明书,我们才可以知道如何使用或是调用这个服务.
    
    //现在我们还不知道怎么去阅读,后面我们会详解,只要能获取到,就能确定WebService服务发布成功 

    这里写图片描述

    客户端的实现

    //客户端调用服务有很多种方法,我们先用工具生成客户端代码,后面会详解  
    
    //wsimport是jdk自带的webservice客户端工具,可以根据wsdl文档生成客户端调用代码(java代码).当然,无论服务器端的WebService是用什么语言写的,都可以生成调用webservice的客户端代码。
    
    1.创建一个客户端空项目,cmd命令行进入此项目的src目录
      使用以下命令生成客户端代码  
    
        wsimport -s . http://127.0.0.1:12345/weather?wsdl
    
        -s是指编译出源代码文件,后面的.(点)指將代码放到当前目录下.
         最后面的http….是指获取wsdl说明书的地址
    

    这里写图片描述

    2.编写客户端
    public class WeatherClient {
    
        public static void main(String[] args) {
            //创建服务视图,视图是从wsdl文件的service标签的name属性获取
            WeatherInterfaceImplService weatherInterfaceImplService=new WeatherInterfaceImplService();  
    
            //获取服务实现类,实现类从wsdl文件的portType的name属性获取
            WeatherInterfaceImpl weatherInterfaceImpl=weatherInterfaceImplService.getPort(WeatherInterfaceImpl.class); 
            //获取查询方法,从portType的operation标签获取
            String weather=weatherInterfaceImpl.queryWeather("北京");
            System.out.println(weather);
    
        }
    
    }
    

    至此,我们的客户端就可以获取远程服务端的数据,接下来我们来详解一下各个部分。

    WSDL

    WSDL(Web Services Description Language), web服务描述语言,他是webservice服务端使用说明书,说明服务端接口、方法、参数和返回值,WSDL是随服务发布成功,自动生成,无需编写。

    文档结构

    这里写图片描述

    Service:相关端口的集合,包括其关联的接口、操作、消息等。

    Binding:特定端口类型的具体协议和数据格式规范

    portType: 服务端点,描述 web service可被执行的操作方法,以及相关的消息,通过binding指向portType

    message: 定义一个操作(方法)的数据参数

    types: 定义 web service 使用的全部数据类型

    阅读方式

    WSDL文档应该从下往上阅读。

    1.先看service标签,看相应port的binding属性,然后通过值查找上面的binding标签。

    2.通过binding标签可以获得具体协议等信息,然后查看binding的type属性

    3.通过binding的type属性,查找对应的portType,可以获得可操作的方法和参数、返回值等。

    4.通过portType下的operation标签的message属性,可以向上查找message获取具体的数据参数信息。

    SOAP

    SOAP即简单对象访问协议,他是使用http发送的XML格式的数据,它可以跨平台,跨防火墙,SOAP不是webservice的专有协议。

    SOAP=http+xml

    SOAP结构

    必需的 Envelope 元素,可把此 XML 文档标识为一条 SOAP 消息
    可选的 Header 元素,包含头部信息
    必需的 Body 元素,包含所有的调用和响应信息
    可选的 Fault 元素,提供有关在处理此消息所发生错误的信息
    

    这里写图片描述

    我们来看一下我们上面天气程序发送的数据的格式,这需要一个工具TCP/IP Monitor ,Eclipse自带的Debug工具之一,用于捕获Http、TCP/IP协议包。原理是一个代理服务,客户端先把数据发送到代理服务,然后代理服务再把数据发送到服务器,这样就能获取请求数据和响应数据。

    第一步:打开这个工具,选择other,然后输入TCP/IP Monitor

    这里写图片描述

    第二步:设置要代理的服务器

    这里写图片描述

    第三步:详细设置

    第一个参数是代理服务器端口,我们设置为54321
    第二个参数是被代理服务器的地址,第三个参数是被代理服务器的端口
    第四个参数要选择为TCP/IP
    

    这里写图片描述

    第四步:检测是否设置成功,我们访问代理服务器来获得wsdl文件

    这里写图片描述

    第五步:设置成功后,我们需要改一下客户端要连接的服务器,改成代理服务器的端口

    将WeatherInterfaceImplService里的所有原来地址的端口改为54321
    

    这里写图片描述

    第六步:我们启动我们的客户端,获取请求数据和响应数据

    
    请求 
    
    //先发送get请求,去获得wsdl文件,然后获得方法、参数等信息
    GET /weather?wsdl HTTP/1.1
    User-Agent: Java/1.8.0_111
    Host: 127.0.0.1:54321
    Accept: text/html, image/gif, image/jpeg, *; q=.2, */*; q=.2
    Connection: keep-alive
    
    //发送数据
    POST /weather HTTP/1.1
    Accept: text/xml, multipart/related
    Content-Type: text/xml; charset=utf-8
    SOAPAction: "http://ws.cad.com/WeatherInterfaceImpl/queryWeatherRequest"
    User-Agent: JAX-WS RI 2.2.9-b130926.1035 svn-revision#5f6196f2b90e9460065a4c2f4e30e065b245e51e
    Host: 127.0.0.1:54321
    Connection: keep-alive
    Content-Length: 203
    
    <?xml version="1.0" ?>
    <S:Envelope xmlns:S="http://schemas.xmlsoap.org/soap/envelope/">
    <S:Body>
    <ns2:queryWeather xmlns:ns2="http://ws.cad.com/">
    <arg0>北京</arg0>
    </ns2:queryWeather>
    </S:Body>
    </S:Envelope>
    
    响应数据 
    
    HTTP/1.1 200 OK
    Date: Tue, 25 Jul 2017 05:05:58 GMT
    Transfer-encoding: chunked
    Content-type: text/xml;charset=utf-8
    
    //响应wsdl内容,来获得方法、参数等信息
    899
    <?xml version="1.0" encoding="UTF-8"?><!-- Published by JAX-WS RI (http://jax-ws.java.net). RI's version is JAX-WS RI 2.2.9-b130926.1035 svn-revision#5f6196f2b90e9460065a4c2f4e30e065b245e51e. --><!-- Generated by JAX-WS RI (http://jax-ws.java.net). RI's version is JAX-WS RI 2.2.9-b130926.1035 svn-revision#5f6196f2b90e9460065a4c2f4e30e065b245e51e. --><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.cad.com/" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns="http://schemas.xmlsoap.org/wsdl/" targetNamespace="http://ws.cad.com/" name="WeatherInterfaceImplService">
    <types>
    <xsd:schema>
    <xsd:import namespace="http://ws.cad.com/" schemaLocation="http://127.0.0.1:54321/weather?xsd=1"></xsd:import>
    </xsd:schema>
    </types>
    <message name="queryWeather">
    <part name="parameters" element="tns:queryWeather"></part>
    </message>
    <message name="queryWeatherResponse">
    <part name="parameters" element="tns:queryWeatherResponse"></part>
    </message>
    <portType name="WeatherInterfaceImpl">
    <operation name="queryWeather">
    <input wsam:Action="http://ws.cad.com/WeatherInterfaceImpl/queryWeatherRequest" message="tns:queryWeather"></input>
    <output wsam:Action="http://ws.cad.com/WeatherInterfaceImpl/queryWeatherResponse" message="tns:queryWeatherResponse"></output>
    </operation>
    </portType>
    <binding name="WeatherInterfaceImplPortBinding" type="tns:WeatherInterfaceImpl">
    <soap:binding transport="http://schemas.xmlsoap.org/soap/http" style="document"></soap:binding>
    <operation name="queryWeather">
    <soap:operation soapAction=""></soap:operation>
    <input>
    <soap:body use="literal"></soap:body>
    </input>
    <output>
    <soap:body use="literal"></soap:body>
    </output>
    </operation>
    </binding>
    <service name="WeatherInterfaceImplService">
    <port name="WeatherInterfaceImplPort" binding="tns:WeatherInterfaceImplPortBinding">
    <soap:address location="http://127.0.0.1:54321/weather"></soap:address>
    </port>
    </service>
    </definitions>
    0
    
    //响应数据
    HTTP/1.1 200 OK
    Date: Tue, 25 Jul 2017 05:05:59 GMT
    Transfer-encoding: chunked
    Content-type: text/xml; charset=utf-8
    
    df
    <?xml version="1.0" ?>
    <S:Envelope xmlns:S="http://schemas.xmlsoap.org/soap/envelope/">
    <S:Body>
        <ns2:queryWeatherResponse xmlns:ns2="http://ws.cad.com/">
        <return>暴雨</return> 
        </ns2:queryWeatherResponse> 
    </S:Body>
    </S:Envelope>
    0
    

    UDDI

    UDDI 是一种目录服务,企业可以使用它对 Web services 进行注册和搜索。
    如果我们要使用一种服务,但是不知道地址(wsdl等),我们就可以在UDDI中查找。
    大部分情况下,我们都是知道服务地址的。

    Webservice的客户端调用方式

    一:生成客户端调用方式

    wsimport是jdk自带的webservice客户端工具,可以根据wsdl文档生成客户端调用代码(java代码).
    wsimport.exe位于JAVA_HOME\bin目录下 
    常用参数为:
            -d<目录>  - 将生成.class文件。默认参数。
            -s<目录> - 将生成.java文件。
            -p<生成的新包名> -将生成的类,放于指定的包下
    

    调用公网的手机归属地查询服务

    公网服务地址 (里面提供了很多免费调用的服务)
    http://www.webxml.com.cn/zh_cn/index.aspx

    第一步:wsimport生成客户端代码 
    
    wsimport -p cn.cad.mobile -s . http://ws.webxml.com.cn/WebServices/MobileCodeWS.asmx?wsdl
    
    会出现一些警告,是因为服务端提供的一些方法是SOAP1.2标准的,这个工具没有实现SOAP1.2标准的生成方式。    
    

    这里写图片描述

    第二步:查看wsdl文件,获取我们需要的信息 

    这里写图片描述

    第三步:根据获取到的服务名等信息来创建我们的客户端  
    
    public class MobileClient {
    
        public static void main(String[] args) {
            //创建服务视图
            MobileCodeWS mobileCodeWS=new MobileCodeWS();
            //获取服务实现类
            MobileCodeWSSoap mobileCodeWSSoap= mobileCodeWS.getPort(MobileCodeWSSoap.class);
            //调用查询方法
            String message=mobileCodeWSSoap.getMobileCodeInfo("xxxxxxxx", null);
            System.out.println(message);
    
        }
    }
    
    第四步:获取到信息 

    这里写图片描述

    还有天气等服务,自己可以去实现一下。

    该种方式使用简单,但一些关键的元素在代码生成时写死在生成代码中,不方便维护,所以仅用于测试。

    二:service编程调用方式

    public class MobileClient2 {
    
        public static void main(String[] args) throws IOException {
            //创建WSDL文件的URL
            URL wsdlDocumentLocation=new URL("http://ws.webxml.com.cn/WebServices/MobileCodeWS.asmx?wsdl"); 
            //创建服务名称
            //1.namespaceURI - 命名空间地址
            //2.localPart - 服务视图名
            QName serviceName=new QName("http://WebXml.com.cn/","MobileCodeWS");
            Service service=Service.create(wsdlDocumentLocation, serviceName);
    
            //获取服务实现类
            MobileCodeWSSoap mobileCodeWSSoap= service.getPort(MobileCodeWSSoap.class);
            //调用方法
            String message=mobileCodeWSSoap.getMobileCodeInfo("XXXXXXX", null);
            System.out.println(message);
    
        }
    
    }

    该种方式可以自定义命名空间,服务视图名等元素,方便以后维护,是一种标准的开发方式 。

    三:HttpURLConnection调用方式

    这种方式是由自己编写客户端,不再由工具生成,比较麻烦。

    开发步骤: 
    
            第一步:创建服务地址
    
            第二步:打开一个通向服务地址的连接
    
            第三步:设置参数
    
            第四步:组织SOAP数据,发送请求
    
            第五步:接收服务端响应 
    
    public class MobileClient2 {
    
        public static void main(String[] args) throws IOException {
                    //第一步:创建服务地址,不是WSDL地址
                    URL url = new URL("http://ws.webxml.com.cn/WebServices/MobileCodeWS.asmx");
                    //第二步:打开一个通向服务地址的连接
                    HttpURLConnection connection = (HttpURLConnection) url.openConnection();
                    //第三步:设置参数
                    //3.1发送方式设置:POST必须大写
                    connection.setRequestMethod("POST");
                    //3.2设置数据格式:content-type
                    connection.setRequestProperty("content-type", "text/xml;charset=UTF-8");
                    //3.3设置输入输出,因为默认新创建的connection没有读写权限,
                    connection.setDoInput(true);
                    connection.setDoOutput(true);
    
                    //第四步:组织SOAP数据,发送请求
                    String soapXML = getXML("XXXXXXX");
                    OutputStream os = connection.getOutputStream();
                    os.write(soapXML.getBytes());
                    //第五步:接收服务端响应,打印
                    int responseCode = connection.getResponseCode();
                    if(200 == responseCode){//表示服务端响应成功
                        InputStream is = connection.getInputStream();
                        //将字节流转换为字符流
                        InputStreamReader isr = new InputStreamReader(is,"utf-8");
                        //使用缓存区
                        BufferedReader br = new BufferedReader(isr);
    
                        StringBuilder sb = new StringBuilder();
                        String temp = null;
                        while(null != (temp = br.readLine())){
                            sb.append(temp);
                        }
                        System.out.println(sb.toString());
    
                        is.close();
                        isr.close();
                        br.close();
                    }
    
                    os.close();
                }
    
        //组织数据,将数据拼接一下
        public static String getXML(String phoneNum){
            String soapXML = "<?xml version=\"1.0\" encoding=\"utf-8\"?>"
            +"<soap:Envelope xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\" xmlns:soap=\"http://schemas.xmlsoap.org/soap/envelope/\">"
                +"<soap:Body>"
                +"<getMobileCodeInfo xmlns=\"http://WebXml.com.cn/\">"
                    +"<mobileCode>"+phoneNum+"</mobileCode>"
                  +"<userID></userID>"
                +"</getMobileCodeInfo>"
              +"</soap:Body>"
            +"</soap:Envelope>";
            return soapXML;
        }
    }

    这里写图片描述

    使用注解修改WSDL内容

    作用:
    通过注解,可以更加形像的描述Web服务。对自动生成的wsdl文档进行修改,为使用者提供一个更加清晰的wsdl文档

    WebService的注解都位于javax.jws包下: 
    
    @WebService-定义服务,在类上边
        targetNamespace:指定命名空间
        name:portType的名称
        portName:port的名称
        serviceName:服务名称
        endpointInterface:SEI接口地址,如果一个服务类实现了多个接口,只需要发布一个接口的方法,可通过此注解指定要发布服务的接口。 
    
    @WebMethod-定义方法,在公开方法上边
        operationName:方法名
        exclude:设置为true表示此方法不是webservice方法,反之则表示webservice方法,默认是false 
    
    @WebResult-定义返回值,在方法返回值前边
        name:返回结果值的名称 
    
    @WebParam-定义参数,在方法参数前边
        name:指定参数的名称
    
    //以我们前面做的天气案例为例子
    
    @WebService(
            targetNamespace="http://service.cad.com",
            portName="WeatherSOAPPort",
            serviceName="WeatherWSS",
            name="WeatherSOAP"  
    )
    public class WeatherInterfaceImpl implements WeatherInterface {
    
        @WebMethod(
                operationName="getWeather",
                exclude=false
        )
        public @WebResult(name="result")String queryWeather(@WebParam(name="cityName")String cityName) {
            System.out.println("获取城市名"+cityName);
            String weather="暴雨";    
            return weather;
        }
    
    }
    然后重新发布服务,我们再访问wsdl文件,就可以看到我们改变的内容 

    这里写图片描述

    展开全文

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 160,720
精华内容 64,288
关键字:

webservice