WebService SOAP概述 - 第275篇_WebService SOAP概述

前言

       说起web service最近几年restful大行其道,大有取代传统soap web service的趋势,但是一些特有或相对老旧的系统依然使用了传统的soapweb service,例如银行、航空公司的机票查询接口等。博主也是基于被朋友咨询WSDL协议的原因,研究了下。

你知道:

(1)何为WebService吗?

(2)XML、DTD、XSD谁是谁的老爸?

(3)WebService / SOAP与WSDL原来是这样子的关系

       如果你也有这样的困惑,通过本篇文章将为你慢慢解开13号技师的衣服,哦,不是揭开技术的面纱。

 

一、何为WebService

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

简单的说,WebService就是一种跨编程语言和跨操作系统的远程调用技术。

1.1 WebServcie技术支持

以下内容摘自百度百科:Web Service

WebService平台需要一套协议来实现分布式应用程序的创建。任何平台都有它的数据表示方法和类型系统。要实现互操作性,Web Service平台必须提供一套标准的类型系统,用于沟通不同平台、编程语言和组件模型中的不同类型系统。这些协议有:

1.1.1 XML和XSD

 

可扩展的标记语言是Web Service平台中表示数据的基本格式。除了易于建立和易于分析外,XML主要的优点在于它既与平台无关,又与厂商无关。XML是由万维网协会(W3C)创建,W3C制定的XMLSchemaXSD定义了一套标准的数据类型,并给出了一种语言来扩展这套数据类型。

WebService平台是用XSD来作为数据类型系统的。当你用某种语言如VB. NET或C#来构造一个WebService时,为了符合Web Service标准,所有你使用的数据类型都必须被转换为XSD类型。如想让它使用在不同平台和不同软件的不同组织间传递,还需要用某种东西将它包装起来。这种东西就是一种协议,如 SOAP。

       XSD全称为XML Schemas Definition,即:XML结构定义。是描述xml的,同时遵循xml规范。

 

1.1.2 SOAP

SOAP即简单对象访问协议(Simple ObjectAccess Protocol),它是用于交换XML (标准通用标记语言下的一个子集) 编码信息的轻量级协议。它有三个主要方面:

(1)XML-envelope为描述信息内容和如何处理内容定义了框架,将程序对象编码成为XML对象的规则,执行远程过程调用(RPC)的约定。

(2)SOAP可以运行在任何其他传输协议上。例如,你可以使用 SMTP,即因特网电子邮件协议来传递SOAP消息,这可是很有诱惑力的。

(3)在传输层之间的头是不同的,但XML有效负载保持相同。

WebService 希望实现不同的系统之间能够用“软件-软件对话”的方式相互调用,打破了软件应用、网站和各种设备之间的格格不入的状态,实现“基于Web无缝集成”的目标。

 

1.1.3 WSDL

Web Service描述语言WSDL就是用机器能阅读的方式提供的一个正式描述文档而基于XML的语言,用于描述Web Service及其函数、参数和返回值。因为是基于XML的,所以WSDL既是机器可阅读的,又是人可阅读的。

 

二、一个小栗子看懂web service的协议概念

有这么一个schema文件(xsd) user.xsd:

<wsdl:definitions
    xmlns:xsd="http://www.w3.org/2001/XMLSchema"
    xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/"
    xmlns:tns="http://ws.demo.kfit.com"
    xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/"
    xmlns:ns1="http://schemas.xmlsoap.org/soap/http" name="helloService"
    targetNamespace="http://ws.demo.kfit.com">
    <wsdl:types>
        <xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"
            xmlns:tns="http://ws.demo.kfit.com" elementFormDefault="unqualified"
            targetNamespace="http://ws.demo.kfit.com" version="1.0">
            <xs:element name="sayHello" type="tns:sayHello" />
            <xs:element name="sayHelloResponse"
                type="tns:sayHelloResponse" />
            <xs:complexType name="sayHello">
                <xs:sequence>
                    <xs:element minOccurs="0" name="userName"
                        type="xs:string" />
                </xs:sequence>
            </xs:complexType>
            <xs:complexType name="sayHelloResponse">
                <xs:sequence>
                    <xs:element minOccurs="0" name="return" type="xs:string" />
                </xs:sequence>
            </xs:complexType>
        </xs:schema>
    </wsdl:types>
    <wsdl:message name="sayHelloResponse">
        <wsdl:part element="tns:sayHelloResponse" name="parameters">
        </wsdl:part>
    </wsdl:message>
    <wsdl:message name="sayHello">
        <wsdl:part element="tns:sayHello" name="parameters">
        </wsdl:part>
    </wsdl:message>
    <wsdl:portType name="HelloService">
        <wsdl:operation name="sayHello">
            <wsdl:input message="tns:sayHello" name="sayHello">
            </wsdl:input>
            <wsdl:output message="tns:sayHelloResponse"
                name="sayHelloResponse">
            </wsdl:output>
        </wsdl:operation>
    </wsdl:portType>
    <wsdl:binding name="helloServiceSoapBinding"
        type="tns:HelloService">
        <soap:binding style="document"
            transport="http://schemas.xmlsoap.org/soap/http" />
        <wsdl:operation name="sayHello">
            <soap:operation soapAction="" style="document" />
            <wsdl:input name="sayHello">
                <soap:body use="literal" />
            </wsdl:input>
            <wsdl:output name="sayHelloResponse">
                <soap:body use="literal" />
            </wsdl:output>
        </wsdl:operation>
    </wsdl:binding>
    <wsdl:service name="helloService">
        <wsdl:port binding="tns:helloServiceSoapBinding"
            name="CxfServicesImplPort">
            <soap:address
                location="http://127.0.0.1:8080/cxf/cxfServices" />
        </wsdl:port>
    </wsdl:service>
</wsdl:definitions>

说明:

(1)XSD(XML Schemas Definition) , XML结构定义,user.xsd 这个里面的内容就是XML结构定义,也就是XSD文件。

(2)XML(Extensible Markup Language) , 可扩展标记语言,XML 被设计用来传输和存储数据。上面这个文件就是XML的一种展现形式。XSD和XML什么关系呢?下面分析。

(3)WSDL(Web Services Description Language) : 文件中的定义就是wsdl文档,wsdl规范了这个文档应该怎么写,要不然每个提供的服务都按照自己的意愿写的话,那么对于调用者就很痛苦了。一般每个服务框架都是可以生成WSDL文档的。

 

三、XML、DTD、XSD区别

       看了上面的定义,可能还是会有点不是很理解,那么就需要看看他们的区别了才能更好的理解。

3.1 XML

       这一切都要从XML说起了,XML类似HTML树结构,具有自我描述性语法,语法也类似html,这个写html代码的就很好理解。

       如果两个不同的文档使用相同的元素名时,就会发生命名冲突,如下文件:

File1.xml:

<root>
    <name>悟纤</name>
</root>

File2.xml:

<root>
    <age>18</age>
</root>

 

如果上面两个xml文档被一起使用,由于两个文档都包含不同内容和定义的<root>元素 , 就会发生命名冲突。

       解决方法有两种:

(1)使用前缀来避免命名冲突

<a:root>
    <name>悟纤</name>
</a:root>

 

File2.xml:

 

<b:root>
    <age>悟纤</age>
</b:root>

(2)使用命名空间

 

<a:root xmlns:a=”url1”>
    <a:name>悟纤</a:name>
</a:root>

File2.xml:

 

<b:root xmlns:b=”url1”>
    <b:age>18</b:age>
</b:root>

       与仅仅使用前缀不同,为root标签添加了一个xmlns属性,为前缀赋予了一个与命名空间相关联的限定名称。

 

3.2 如何保证XML的正确性

       我们会发现XML可以随意编写,张三喜欢定义姓名为name,李四喜欢定义姓名为:fullName。王五得到一段XML代码,要解析一下看看到底是谁,这时候就蒙圈了,到底是张三的是对的,还是李四是对的呢,哈哈,为了数据的正确显示,这时候,就得if name!=null 显示name ,否则else显示fullName了 , 这时候就出现了DTD和XSD。

       XML文件的正确性是由XML的验证模式来保证的,比较常见的验证模式有两种:DTD和XSD。

       DTD和XSD对XML的编写进行了约束,这可以理解这是XML约束模型语言。

 

3.3 DTD

DTD(Document Type Definition)即文档类型定义,是一种xml约束模式语言,是xml文件的验证机制,属于xml文件组成的一部分。DTD是一种保证xml文档格式正确的有效方法,可以通过比较xml文档和DTD文档来查看文档是否符合规范,元素和标签使用是否正确。一个DTD文档包含:元素的定义规则,元素间关系的定义规则,元素可使用的属性,可使用的实体或符号规则。

       以下是spring-beans-2.0.dtd的部分内容:

<!ELEMENT beans (
    description?,
    (import | alias | bean)*
)>
<!ATTLIST beans default-lazy-init (true | false) "false">
<!ATTLIST beans default-autowire (no | byName | byType | constructor | autodetect) "no">
<!ATTLIST beans default-dependency-check (none | objects | simple | all) "none">
<!ATTLIST beans default-init-method CDATA #IMPLIED>
<!ATTLIST beans default-destroy-method CDATA #IMPLIED>
<!ATTLIST beans default-merge (true | false) "false">
<!ELEMENT description (#PCDATA)>
<!ELEMENT import EMPTY>
<!ATTLIST import resource CDATA #REQUIRED>
<!ELEMENT alias EMPTY>
<!ATTLIST alias name CDATA #REQUIRED>
<!ATTLIST alias alias CDATA #REQUIRED>
<!ELEMENT meta EMPTY>
<!ATTLIST meta key CDATA #REQUIRED>
<!ATTLIST meta value CDATA #REQUIRED>
...

 

 

3.4 XSD

XSD(XML Schemas Definition)即xml结构定义文档。xsd描述了xml文档的结构,可以用一个指定的xml schema来验证某个xml文档,以检查该xml是否符合其要求。文档设计者可以通过xmlschema指定一个xml文档所允许的结构和内容,并可据此检查一个xml文档是否是有效的。

下面是spring-beans-3.1.xsd的部分内容:

<xsd:schema xmlns="http://www.springframework.org/schema/beans" xmlns:xsd="http://www.w3.org/2001/XMLSchema" targetNamespace="http://www.springframework.org/schema/beans">
<xsd:import namespace="http://www.w3.org/XML/1998/namespace"/>
<xsd:annotation>
<xsd:documentation>
<![CDATA[
Spring XML Beans Schema, version 3.1 Authors: Juergen Hoeller, Rob Harrop, Mark Fisher, Chris Beams This defines a simple and consistent way of creating a namespace of JavaBeans objects, managed by a Spring BeanFactory, read by XmlBeanDefinitionReader (with DefaultBeanDefinitionDocumentReader). This document type is used by most Spring functionality, including web application contexts, which are based on bean factories. Each "bean" element in this document defines a JavaBean. Typically the bean class is specified, along with JavaBean properties and/or constructor arguments. A bean instance can be a "singleton" (shared instance) or a "prototype" (independent instance). Further scopes can be provided by extended bean factories, for example in a web environment. References among beans are supported, that is, setting a JavaBean property or a constructor argument to refer to another bean in the same factory (or an ancestor factory). As alternative to bean references, "inner bean definitions" can be used. Singleton flags of such inner bean definitions are effectively ignored: inner beans are typically anonymous prototypes. There is also support for lists, sets, maps, and java.util.Properties as bean property types or constructor argument types.
]]>
</xsd:documentation>
</xsd:annotation>
 <!--  base types  -->
<xsd:complexType name="identifiedType" abstract="true">
<xsd:annotation>
<xsd:documentation>
<![CDATA[
The unique identifier for a bean. The scope of the identifier is the enclosing bean factory.
]]>
</xsd:documentation>
</xsd:annotation>
<xsd:attribute name="id" type="xsd:string">
<xsd:annotation>
<xsd:documentation>
<![CDATA[
The unique identifier for a bean. A bean id may not be used more than once within the same <beans> element.
]]>
</xsd:documentation>
</xsd:annotation>
</xsd:attribute>
</xsd:complexType>
 <!--  Top-level <beans> tag  -->
<xsd:element name="beans">

 

3.4 DTD/XSD 区别

(1)声明方式不一样

DTD需要在xml文件的头部声明,例如:

<!DOCTYPE beans PUBLIC "-//Spring//DTD BEAN 2.0//EN" "http://Springframework.org/dtd/Spring-beans-2.0.dtd">

 

而XSD通过xmlns名称空间的方式验证的,例如

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.Springframwork.org/schema/beans"
xmlns:xsi=" http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation=" http://www.Springframewrok.org/schema/beans http://www.Springframework.org/schema/beans/Spring-beans.xsd"
 </beans>      

 

(2)编写方式不不一样

DTD 是使用非 XML 语法编写的,XSD是使用XML编写的

(3)可扩展性

       DTD 不可扩展,不支持命名空间,只提供非常有限的数据类型,而XSD都是支持的。

 

四、WebService / SOAP与WSDL

4.1 WebService

       WebService:web + service,也就是 服务(service)网络(web)化的意思

它力求的是跨语言,跨平台的,基于web传输的远程调用能力。他没有强调远程调用使用什么协议,所以你可以自由选择,比如SOAP 协议(可基于http,smtp,等各种传输协议),或者常见的基于http的json化的数据传输协议,基于dubbo协议的dubbo服务调用都属于webservice的一种实现。

 

4.2 SOAP

SOAP定义了数据交互中如何传递消息的规则。比如在http中规定了post请求的传参方式,在数据类型不同的情况下可以使用不同的参数方式。在form格式下是 key=v&key1=v1 ,同样SOAP也是定义这些东西的。

       SOAP的传输协议使用的就是HTTP协议。只不过HTTP传输的内容是HTML文本,而SOAP协议传输的是SOAP的数据。

       这是一个HTTP协议:

GET / HTTP/1.1 Accept: image/gif, image/jpeg, image/pjpeg, image/pjpeg, application/x-shockwave-flash, application/x-ms-application, application/x-ms-xbap, application/vnd.ms-xpsdocument, application/xaml+xml, application/vnd.ms-excel, application/vnd.ms-powerpoint, application/msword, */*
Accept-Language: en-us
User-Agent: Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 5.1; Trident/4.0; .NET CLR 2.0.50727; .NET CLR 3.0.4506.2152; .NET CLR 3.5.30729; CIBA) chromeframe/4.0
Accept-Encoding: gzip, deflate
Connection: Keep-Alive
Host: www.google.com
Cookie: PREF=ID=d8f9f1710bfa5f72:U=a5b3bec86b6433ef:NW=1:TM=1260238598:LM=1260241971:GM=1:S=q2agYsw3BsoOQMAs; NID=29=JgIGDDUx70IQTBVAnNEP_E9PLLKBI9STjzaBjgq1eWuDg-_jCgFpka59DrOC0aZKLbj4q77HU1VMKscXTP3OaseyTbv643c2XPe9dS7lsXDHAkAnS46vy-OU8XRqbmxJ; rememberme=true; SID=DQAAAH4AAABW7M4nVkTeOR7eJUmC1AJ4R6hYbmVewuy_uItLUTzZMUTpojdaHUExhPa_EPAkO9Ex1u3r7aPXZ5cj28xHnv2DbfRYf5AyaBcimciuOTITKSIkqn3QSpGDFkRS1Xn7EGzDpCV0V1xFlCu0erf_jfe_D6GOgC2P2S08jNdFS9Vpmw; HSID=AFEFTMA68EgNjkbil; __utmx=173272373.; __utmxx=173272373.

---------如果有Post的数据,这里还会有Post的数据--------

 

 

这个是一个SOAP请求的内容:

POST /WebServices/WeatherWebService.asmx HTTP/1.1
User-Agent: Mozilla/4.0 (compatible; MSIE 6.0; MS Web Services Client Protocol 2.0.50727.3603)
Content-Type: text/xml; charset=utf-8
SOAPAction: "http://WebXml.com.cn/getSupportCity"
Host: www.webxml.com.cn
Content-Length: 348
Expect: 100-continue
Connection: Keep-Alive

<?xml version="1.0" encoding="utf-8"?><soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema"><soap:Body><getSupportCity xmlns="http://WebXml.com.cn/"><byProvinceName>广东</byProvinceName></getSupportCity></soap:Body></soap:Envelope>

 

 

可以看到,一个SOAP请求其实就是一个HTTP请求,但为了表明内容是SOAP的数据,需要加入上面请求中红色字的部分来以示区别。也就是说,如果请求头中有SOAPAction这一段,那么请求会被当作SOAP的内容来处理而不会当作HTML来解析。可以用上面指定SOAPAction头来表示内容是SOAP的内容,也可以指定 Content-Type: application/soap+xml 来表示内容是SOAP的内容。SOAP请求中最后的那段XML数据,这个就是请求的具体内容,这个就是SOAP规定的请求的数据格式。

 

4.3 WSDL

WSDL是用来描述WebService的,它用XML的格式描述了WebService有哪些方法、参数类型、访问路径等等。

       这节定义讲的有点多了,至于WSDL是什么“Lese”下节进行揭晓。

我就是我,是颜色不一样的烟火。
我就是我,是与众不同的小苹果。

à悟空学院:http://t.cn/Rg3fKJD

学院中有Spring Boot相关的课程!点击「阅读原文」进行查看!

SpringBoot视频:http://t.cn/R3QepWG

Spring Cloud视频:http://t.cn/R3QeRZc

SpringBoot Shiro视频:http://t.cn/R3QDMbh

SpringBoot交流平台:http://t.cn/R3QDhU0

SpringData和JPA视频:http://t.cn/R1pSojf

SpringSecurity5.0视频:http://t.cn/EwlLjHh

Sharding-JDBC分库分表实战:http://t.cn/E4lpD6e