WebService简介

Webservice(就是一种远程调用技术,他的作用就是从远程系统中获取业务数据)

  • Web Services 是应用程序组件
  • Web Services 使用开放协议进行通信
  • Web Services 是独立的(self-contained)并可自我描述
  • Web Services 可通过使用UDDI来发现
  • Web Services 可被其他应用程序使用

webservice 常见名词:

WSDL WSDL 指网络服务描述语言(Web Services Description Language) 是webservice服务端使用说明书,说明服务端接口、方法、参数和返回值,WSDL是随服务发布成功,自动生成,无需编写
SOAP Simple object access protocol SOAP即简单对象访问协议,他是使用http发送的XML格式的数据,它可以跨平台,跨防火墙,
UDDI Universal Description, Discovery and Integration UDDI 是一种目录服务 ,企业可以使用它对 Web services 进行注册和搜索。

执行过程:

  • Webservice是使用Http发送SOAP协议的数据的一种远程调用技术
  • Webservice要开发服务端
  • Webservice要开发客户端
  • Webservice客户端开发需要阅读服务端的使用说明书(WSDL)

F:\学习\JAVA_EE\deworkspace\WebServiceClienTest\src>wsimport -s . gateway.woxp.cn:6630/gb2312/ws_a...

1.1 Webservice的优缺点

优点

-发送方式采用http的post发送,http的默认端口是80,防火墙默认不拦截80,所以跨防火墙

-采用XML格式封装数据,XML是跨平台的,所以webservice也可以跨平台。

-Webservice支持面向对象

缺点

采用XML格式封装数据,所以在传输过程中,要传输额外的标签,随着SOAP协议的不断完善,标签越来越大,导致webservice性能下降

1Webservice应用场景

1.1 软件集成和复用

适用场景

l 发布一个服务(对内/对外),不考虑客户端类型,如果不考虑性能,建议使用webservice

l 服务端已经确定使用webservice,客户端不能选择,必须使用webservice

1.1 不适用场景

l 如果考虑性能时不建议使用webservice

l 同构程序下不建议使用webservice,比如java 用RMI,不需要翻译成XML的数据

WSDL

1.1 定义

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

1.2 文档结构

  • 服务视图,webservice的服务结点,它包括了服务端点
  • 为每个服务端点定义消息格式和协议细节
  • 服务端点,描述 web service可被执行的操作方法,以及相关的消息,通过binding指向portType
  • 定义一个操作(方法)的数据参数(可有多个参数)
  • 定义 web service 使用的全部数据类型

1.3 阅读方式:从下往上

2 SOAP

2.1 定义

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

SOAP=http+xml

2.2 协议格式

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

2.3 TCP/IP Monitor

2.3.1 代理原理

2.3.2 配置

2.3.3 测试

在浏览器中输入代理服务地址,能正常访问,代表代理服务器设置成功

2.4 SOAP1.1

请求

xml 复制代码
POST /weather HTTP/1.1
Accept: text/xml, multipart/related
Content-Type: text/xml; charset=utf-8
SOAPAction: "http://ws.jaxws.ws.hanyuanhun.cn/WeatherInterfaceImpl/queryWeatherRequest"
User-Agent: JAX-WS RI 2.2.4-b01
Host: 127.0.0.1:54321
Connection: keep-alive
Content-Length: 214
 
<?xml version="1.0" ?>
<S:Envelope xmlns:S="http://schemas.xmlsoap.org/soap/envelope/">
<S:Body><ns2:queryWeather xmlns:ns2="http://ws.jaxws.ws.hanyuanhun.cn/"><arg0>北京</arg0></ns2:queryWeather>
</S:Body>
</S:Envelope>

响应

xml 复制代码
HTTP/1.1 200 OK
Transfer-encoding: chunked
Content-type: text/xml; charset=utf-8
Date: Thu, 26 Nov 2015 03:14:29 GMT
 
<?xml version="1.0" ?>
<S:Envelope xmlns:S="http://schemas.xmlsoap.org/soap/envelope/">
<S:Body>
<ns2:queryWeatherResponse xmlns:ns2="http://ws.jaxws.ws.hanyuanhun.cn/"><return>晴</return></ns2:queryWeatherResponse>
</S:Body>
</S:Envelope>

2.5 SOAP1.2

l 如何发布SOAP1.2服务端

l Jaxws不支持SOAP1.2服务端发布,直接发布会报如下异常

l 如果想发布SOAP1.2服务端,需要在服务端引入第三方JAR(jaxws-ri-2.2.8)

l 在实现类上加入如下注解

@BindingType(SOAPBinding.SOAP12HTTP_BINDING)

请求:

xml 复制代码
POST /weather HTTP/1.1
Accept: application/soap+xml, multipart/related
Content-Type: application/soap+xml; charset=utf-8;
action="http://ws.jaxws.ws.hanyuanhun.cn/WeatherInterfaceImpl/queryWeatherRequest"
User-Agent: JAX-WS RI 2.2.4-b01
Host: 127.0.0.1:54321
Connection: keep-alive
Content-Length: 212
 
<?xml version="1.0" ?>
<S:Envelope xmlns:S="http://www.w3.org/2003/05/soap-envelope">
<S:Body><ns2:queryWeather xmlns:ns2="http://ws.jaxws.ws.hanyuanhun.cn/"><arg0>北京</arg0></ns2:queryWeather>
</S:Body>
</S:Envelope>

响应

xml 复制代码
HTTP/1.1 200 OK
Transfer-encoding: chunked
Content-type: application/soap+xml; charset=utf-8
Date: Thu, 26 Nov 2015 03:25:24 GMT
 
<?xml version='1.0' encoding='UTF-8'?>
<S:Envelope xmlns:S="http://www.w3.org/2003/05/soap-envelope">
<S:Body>
<ns2:queryWeatherResponse xmlns:ns2="http://ws.jaxws.ws.hanyuanhun.cn/"><return>晴</return></ns2:queryWeatherResponse>
</S:Body>
</S:Envelope>

2.6 SOAP1.1和SOAP1.2区别

相同点:

  • 请求发送方式相同:都是使用POST
  • 协议内容相同:都有Envelope和Body标签
  • 不同点:
  • 数据格式不同:content-type不同
  • SOAP1.1:text/xml;charset=utf-8
  • SOAP1.2:application/soap+xml;charset=utf-8

命名空间不同:

3 UDDI

UDDI 是一种目录服务 ,企业可以使用它对 Web services 进行注册和搜索。UDDI,英文为 "Universal Description, Discovery and Integration",可译为"通用描述、发现与集成服务"。

UDDI 并不像 WSDL 和 SOAP 一样深入人心,因为很多时候,使用者知道 Web 服务的位置(通常位于公司的企业内部网中)。

回顾

l 什么是webservice

l 什么是远程调用:系统和系统之间的调用,从远程系统当中获取业务数据。

l Webservice是web服务:他是用http传输SOAP协议数据的一种远程调用技术

l Webservice入门程序

l 服务端

n 第一步:创建SEI接口

n 第二步:创建SEI实现类,要在类上加入@WebService

n 第三步:发布服务,Endpoint的publish方法,2两个参数:1.服务地址;2.实现类实例

n 第四步:测试服务是否发布成功,通过阅读使用说明书,确定服务接口、方法、参数、返回值存在,说明服务发布成功。

u WSDL地址:服务地址+"?wsdl"

u WSDL阅读方式,从下往上,servvice->binding->portType->其中有接口、方法、参数和返回值

l 客户端

n 第一步:使用wsimport生成客户端代码

n 第二步:根据使用说明书,使用客户端调用服务端

u 创建服务视图,视图是从service的name属性获取

u 获取服务实现类,从portType的name属性获取

u 调用查询方法,从portType下的operation标签的name属性获取

l 优缺点:

n 发送方式采用http的post,http默认端口是80,所以跨越防火墙

n 数据封装使用XML格式,XML是跨平台,所以webservice可以跨平台

n Webservice支持面向对象开发

l Webservice应用场景

l 软件集成和复用

l 适用场景:

n 发布服务(对内/对外),不考虑性能,不考虑客户端类型,建议使用webservice

n 服务端已确定使用webservice,客户端只能使用webservice

l 不适用场景:

n 考虑性能时,不建议使用webservice

n 同构程序下,不建议使用webservice,比如客户端服务端都是java开发,建议Java RMI

l WSDL

l 定义:WSDL即Web服务描述语言,他是webservice服务端的使用说明书,他说明服务端接口、方法、参数和返回值,他是随服务发布成功,自动生成,无需编写

l 文档结构:

n Service

n Binding

n portType

n message

n types

l 阅读方式:从下往上

l SOAP

l 定义:SOAP即简单对象访问协议,他是使用http发送的XML格式的数据,跨平台、跨防火墙,他不是webservice的专有协议

l SOAP=http+xml

l 协议的格式:

n 必须有:envelope和body

n 非必有:header和fault

l SOAP1.1和1.2区别:

n 相同点:

u 都使用http的POST发送请求

u 协议的格式都相同:都有envelope标签和body标签

n 不同点:

u Content-type:

SOAP1.1:text/xml;charset=utf-8;SOAP1.2:application/soap+xml;charset=utf-8

l 命名空间不同:

l UDDI:就是一个目录服务,提供搜索和注册功能,因为不常用,所以了解下就可以了。

5 Webservice的四种客户端调用方式

公网服务地址:

www.webxml.com.cn/zh_cn/index...

5.1 第一种生成客户端调用方式

5.1.1 Wsimport命令介绍

l Wsimport就是jdk提供的的一个工具,他作用就是根据WSDL地址生成客户端代码

l Wsimport位置JAVA_HOME/bin

l Wsimport常用的参数:

l -s,生成java文件的

l -d,生成class文件的,默认的参数

l -p,指定包名的,如果不加该参数,默认包名就是wsdl文档中的命名空间的倒序

l Wsimport仅支持SOAP1.1客户端的生成

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

l 第一步:wsimport生成客户端代码

wsimport -p cn.hanyuanhun.mobile -s . webservice.webxml.com.cn/WebServices...

l 第二步:阅读使用说明书,使用生成客户端代码调用服务端

typescript 复制代码
package cn.hanyuanhun.mobile.client;
 
import cn.hanyuanhun.mobile.MobileCodeWS;
import cn.hanyuanhun.mobile.MobileCodeWSSoap;
 
/**
 *
 * <p>Title: MobileClient.java</p>
 * <p>Description:公网手机号查询客户端</p>
 * <p>Company:</p>
 * @author 
 * @date 2015年11月26日下午3:16:05
 * @version 1.0
 */
publicclass MobileClient {
 
   publicstaticvoid main(String[] args) {
      //创建服务视图
      MobileCodeWS mobileCodeWS = new MobileCodeWS();
      //获取服务实现类
      MobileCodeWSSoap mobileCodeWSSoap = mobileCodeWS.getPort(MobileCodeWSSoap.class);
      //调用查询方法
      String reuslt = mobileCodeWSSoap.getMobileCodeInfo("13888888", null);
      System.out.println(reuslt);
   }
}

5.1.3 公网天气服务端查询

ini 复制代码
package cn.hanyuanhun.mobile.client;
 
import java.util.List;
 
import cn.hanyuanhun.weather.ArrayOfString;
import cn.hanyuanhun.weather.WeatherWS;
import cn.hanyuanhun.weather.WeatherWSSoap;
 
/**
 *
 * <p>Title: WeatherClient.java</p>
 * <p>Description:公网天气查询客户端</p>
 * <p>Company: </p>
 * @author  
 * @date    2015年11月26日下午3:24:12
 * @version 1.0
 */
publicclass WeatherClient {
 
   publicstaticvoid main(String[] args) {
      WeatherWS weatherWS = new WeatherWS();
      WeatherWSSoap weatherWSSoap = weatherWS.getPort(WeatherWSSoap.class);
      ArrayOfString  arrayOfString = weatherWSSoap.getWeather("成都", "");
      List<String> list = arrayOfString.getString();
     
      for(String str : list){
         System.out.println(str);
      }
   }
}
 

5.1.4 特点

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

6 第二种:service编程调用方式

java 复制代码
package cn.hanyuanhun.mobile.client;
 
import java.io.IOException;
importjava.net.MalformedURLException;
import java.net.URL;
import javax.xml.namespace.QName;
import javax.xml.ws.Service;
import cn.hanyuanhun.mobile.MobileCodeWSSoap;
/**
 *
 * <p>Title: ServiceClient.java</p>
 * <p>Description:Service编程实现服务端调用</p>
 * <p>Company: </p>
 * @author 
 * @date    2015年11月26日下午3:43:55
 * @version 1.0
 */
publicclass ServiceClient {
 
   publicstaticvoid main(String[] args) throws IOException {
      //创建WSDL的URL,注意不是服务地址
      URL url = new URL("http://webservice.webxml.com.cn/WebServices/MobileCodeWS.asmx?wsdl");
     
      //创建服务名称
      //1.namespaceURI - 命名空间地址
      //2.localPart - 服务视图名
      QName qname = new QName("http://WebXml.com.cn/", "MobileCodeWS");
     
      //创建服务视图
      //参数解释:
      //1.wsdlDocumentLocation - wsdl地址
      //2.serviceName - 服务名称
      Service service = Service.create(url, qname);
      //获取服务实现类
      MobileCodeWSSoap mobileCodeWSSoap = service.getPort(MobileCodeWSSoap.class);
      //调用查询方法
      String result = mobileCodeWSSoap.getMobileCodeInfo("1866666666", "");
      System.out.println(result);
   }
}
 

6.1 特点

该种方式可以自定义关键元素,方便以后维护,是一种标准的开发方式

7 第三种:HttpURLConnection调用方式

开发步骤:

第一步:创建服务地址

第二步:打开一个通向服务地址的连接

第三步:设置参数

设置POST,POST必须大写,如果不大写,报如下异常

如果不设置输入输出,会报如下异常

第四步:组织SOAP数据,发送请求

第五步:接收服务端响应,打印

ini 复制代码
package cn.hanyuanhun.mobile.client;
 
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.net.HttpURLConnection;
importjava.net.MalformedURLException;
import java.net.URL;
 
/**
 *
 * <p>Title: HttpClient.java</p>
 * <p>Description:HttpURLConnection调用方式</p>
 * <p>Company: </p>
 * @author 
 * @date    2015年11月26日下午3:58:57
 * @version 1.0
 */
publicclass HttpClient {
 
   publicstaticvoid main(String[] args) throws IOException {
      //第一步:创建服务地址,不是WSDL地址
      URL url = new URL("http://webservice.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("15226466316");
      OutputStream os = connection.getOutputStream();
      os.write(soapXML.getBytes());
      //第五步:接收服务端响应,打印
      intresponseCode = connection.getResponseCode();
      if(200 == responseCode){//表示服务端响应成功
         InputStream is = connection.getInputStream();
         InputStreamReader isr = new InputStreamReader(is);
         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();
   }
  
   /**
    * <?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>string</mobileCode>
      <userID>string</userID>
    </getMobileCodeInfo>
  </soap:Body>
</soap:Envelope>
    * @param phoneNum
    * @return
    */
   publicstatic 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>";
      returnsoapXML;
   }
}
 

8 Ajax调用方式

xml 复制代码
<!doctype html>
<html lang="en">
 <head>
  <meta charset="UTF-8">
  <title>Document</title>
  <script type="text/javascript">
         function queryMobile(){
                   //创建XMLHttpRequest对象
                   var xhr = new XMLHttpRequest();
                   //打开连接
                  xhr.open("post","http://webservice.webxml.com.cn/WebServices/MobileCodeWS.asmx",true);
                   //设置数据类型
                   xhr.setRequestHeader("content-type","text/xml;charset=utf-8");
                   //设置回调函数
                   xhr.onreadystatechange=function(){
                            //判断是否发送成功和判断服务端是否响应成功
                            if(4 == xhr.readyState && 200 == xhr.status){
                                     alert(xhr.responseText);
                            }
                   }
                   //组织SOAP协议数据
                   var 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>"+document.getElementById("phoneNum").value+"</mobileCode>"
                         +"<userID></userID>"
                       +"</getMobileCodeInfo>"
                     +"</soap:Body>"
                   +"</soap:Envelope>";
                   alert(soapXML);
                   //发送数据
                   xhr.send(soapXML);
         }
  </script>
 </head>
 <body>
  手机号查询:<input type="text" id="phoneNum"/> <input type="button" value="查询" onclick="javascript:queryMobile();"/>
 </body>
</html>

9 深入开发:用注解修改WSDL内容

WebService的注解都位于javax.jws包下:

@WebService-定义服务,在public class上边

targetNamespace:指定命名空间

name:portType的名称

portName:port的名称

serviceName:服务名称

endpointInterface:SEI接口地址,如果一个服务类实现了多个接口,只需要发布一个接口的方法,可通过此注解指定要发布服务的接口。

@WebMethod-定义方法,在公开方法上边

arduino 复制代码
   operationName:方法名

   exclude:设置为true表示此方法不是webservice方法,反之则表示webservice方法,默认是false

@WebResult-定义返回值,在方法返回值前边

复制代码
   name:返回结果值的名称

@WebParam-定义参数,在方法参数前边

复制代码
   name:指定参数的名称

作用:

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

当修改了WebService注解之后,会影响客户端生成的代码。调用的方法名和参数名也发生了变化

原文链接 www.hanyuanhun.cn | node.hanyuanhun.cn

相关推荐
一只叫煤球的猫8 小时前
写代码很6,面试秒变菜鸟?不卖课,面试官视角走心探讨
前端·后端·面试
bobz9658 小时前
tcp/ip 中的多路复用
后端
bobz9658 小时前
tls ingress 简单记录
后端
皮皮林5519 小时前
IDEA 源码阅读利器,你居然还不会?
java·intellij idea
你的人类朋友10 小时前
什么是OpenSSL
后端·安全·程序员
bobz96510 小时前
mcp 直接操作浏览器
后端
前端小张同学12 小时前
服务器部署 gitlab 占用空间太大怎么办,优化思路。
后端
databook12 小时前
Manim实现闪光轨迹特效
后端·python·动效
武子康13 小时前
大数据-98 Spark 从 DStream 到 Structured Streaming:Spark 实时计算的演进
大数据·后端·spark
该用户已不存在13 小时前
6个值得收藏的.NET ORM 框架
前端·后端·.net