1. Web Service 接口
1.1 接口方式说明和长处
在笔者的开发生涯中,看成为接口提供商给第三方提供接口时,以及做为client去调用第三方提供的接口时,大部分时候都是使用 Web Service接口, Web Service做为接口使用普遍的缘由,与它的特色息息相关。 javascript
Web Service的主要目标是跨平台的可互操做性,为了实现这一目标, Web Service 全然基于 XML(可扩展标记语言)、 XSD( XML Schema)等独立于平台、独立于软件供应商的标准,是建立可互操做的、分布式应用程序的新平台。所以使用 Web Service有不少长处: php
1.1.1 跨防火墙的通讯 css
假设应用程序有成千上万的用户,而且分布在世界各地,那么client和server之间的通讯将是一个棘手的问题。因为client和server之间通常会有防火墙或者代理server。要调用 Web Service,可以直接使用 SOAPclient,而后把它和应用程序链接起来。不只缩短了开发周期,还下降了代码复杂度,并能够加强应用程序的可维护性。
1.1.2 跨程序语言的应用程序集成 html
在企业的各类应用系统中,很是多系统不是使用一样的语言编写的,好比有的使用 Java,有的使用 php、 C#、 asp。当各类系统之间需要交互时,可以使用各类语言都通用的 WSDL定义接口,对外将需要的接口暴露给指定的客户。 java
XML Web services 提供了在松耦合环境中使用标准协议( HTTP、 XML、 SOAP 和 WSDL)交换消息的能力。消息可以是结构化的、带类型的,也可以是松散定义的。
1.1.3 软件和数据重用 ajax
Web Service在赞成重用代码的同一时候,可以重用代码背后的数据。使用 Web Service,不再必像曾经那样,要先从第三方购买、安装软件组件,再从应用程序中调用这些组件;仅仅需要直接调用远端的 Web Service就可以了。 算法
还有一种软件重用的状况是,把好几个应用程序的功能集成起来,经过 Web Service “暴露 ”出来,就可以很easy地把所有这些功能都集成到你的门户网站中,为用户提供一个统一的、友好的界面。 编程
可以在应用程序中使用第三方的 Web Service 提供的功能,也可以把本身的应用程序功能经过 Web Service 提供给别人。两种状况下,都可以重用代码和代码背后的数据。 json
1.2 重要概念
1.2.1 何为Web Service ?
Web Service是构建互联网分布式系统的基本部件,它是一个应用程序,它向外界暴露出一个能够经过 Web 进行调用的 API 。这就是说,别人能够用编程的方法经过 Web 来调用这个应用程序。 小程序
它经过标准通讯协议,在互联网上以服务的方式公布实用的程序模块,眼下大部分是用 SOAP做为通讯协议。
它提供一份具体的接口说明书,来帮助用户构建应用程序,这个接口说明书叫 WSDL( Web服务描写叙述语言, Web Service Description Language)。
一般已公布的 Web Service要注冊到管理server,便于使用者查询和使用。这个是经过 UDDI( 统一描写叙述、发现和集成, Universal Discovery Description and Integration)来完毕的。
1.2.2 何为 SOAP 协议?
SOAP定义 SOAP消息的 XML格式( XML格式),假设你用一对 SOAP标记( SOAP Elements)把 XML文档括起来,那么这个就是一个 SOAP消息。
SOAP规范还定义了如何用 XML来描写叙述程序数据,如何运行 RPC( 远程过程调用, Remote Procedure Call)。大多数 SOAP解决方式都支持 RPC-style应用程序,因为很是多程序猿已对 DCOM或 CORBA熟悉。 它还支持 Document-style应用程序( SOAP消息仅仅包括 XML文本信息)。 Document-style应用程序有很是好的灵活性,因此很是多用 RPC很是难构建的 Web Service用这样的方式构建。
最后 SOAP规范还定义了 HTTP消息是如何传输 SOAP消息的。这并不表明 SOAP仅仅能用 HTTP来做为传输协议, MSMQ、 SMTP、 TCP/IP都可以作 SOAP的传输协议。
安全性对于应用程序来讲是很是重要的。那么 SOAP的安全性怎样呢?对于把 HTTP做为传输协议的 SOAP来讲是没有问题的,因为 HTTP协议已经有很是好的安全构架。那么用其它传输协议会出现安全问题吗?这方面也已经有相关规范
( http://msdn.microsoft.com/library/default.asp?url=/library/en-us/dnglobspec/html/ws-security.asp )。
1.2.3 何为 WSDL ?
WSDL是一种 XML文档,它定义 SOAP消息和这些消息是如何交换的。 IDL( Interface Description Language,接口描写叙述语言)是用于 COM和 CORBA的, WSDL是用于 SOAP的。 WSDL是一种 XML文档,因此可以阅读和编辑,但很是多时候是用工具来建立、由程序阅读。
举个实例,当读者需要使用第三方的 Web Service构建应用程序。你可以向接口提供商索取使用 WSDL文档,在该文档中具体的说明了各个方法的方法名、參数和參数类型等信息。在 Java等编程语言的 IDE(好比 My Eclipse)中,可以依据 Web Servie生成相应的測试代码,略微改动一下就能够。
1.2.4 何为 UDDI ?
UDDI可以比喻成电话本,电话本里记录的是电话信息,而 UDDI记录的是 Web Service信息。可以不把 Web Service注冊到 UDDI。但假设要让全球的人知道这个 Web Service,不妨注冊到 UDDI。
UDDI文件夹说明文件也是一个 XML文档,它包含三个部分。“白页( White Paper)”说明提供 Web Service的公司(人)信息,比方说名称、地址和联系方式等等。“黄页( Yellow Paper)”说明 UDDI文件夹的分类,比方说金融、服务和印刷等等。“绿页( green Paper)”说明接口( Web Service 提供的)的具体信息。 UDDI提供多种查询方式,来帮助你找到需要的 Web Service。假设你查询与財务有关的 Web Service,那么 UDDI会提供具体的信息。
1 .2.5 何为 XML ?
XML( Extensible Markup Language)就能够扩展标记语言,它与 HTML同样,都是 SGML(Standard Generalized Markup Language,标准通用标记语言 )。在 Web Service接口中, WSDL和 UDDI文件夹文件都是一种 XML文档, XML攻克了数据表示的问题。
1.2.6 何为 XSD ?
XML攻克了数据表示的问题,但它未定义一套标准的数据类型,更没有说怎么去扩展这套数据类型。好比,整型数究竟表明什么? 16位, 32位,仍是 64位?
W3C制定的 XML Schema(XSD)就是专门解决问题的一套标准。它定义了一套标准的数据类型,并给出了一种语言来扩展这套数据类型。 Web Service就是用 XSD来做为其数据类型系统的。
1.3 开发 Web Service 接口和调用測试
在 Java IDE环境中开发 Web Service接口,以及怎样调用第三方的 WSDL文档怎样进行接口測试的參考文章详见:
1)《 使用XFire+Spring 构建 Web Service (一) ——helloWorld 篇 》:
http://www.blogjava.net/amigoxie/archive/2007/09/26/148207.html
2)《 使用XFire+Spring 构建 Web Service (二) 》:
http://www.blogjava.net/amigoxie/archive/2007/09/28/149074.html
3)《 依据wsdl 生成相应的 Java 代码进行接口測试(一) 》:
http://www.blogjava.net/amigoxie/archive/2009/11/20/303038.html
1.4 开发举例
1.4.1 做为提供商提供hello world的接口
參见:《 使用XFire+Spring 构建 Web Service (一) ——helloWorld 篇 》:
http://www.blogjava.net/amigoxie/archive/2007/09/26/148207.html
1.4.2 做为提供商提供用户信息查询接口
參见:《 使用XFire+Spring 构建 Web Service (二) 》:
http://www.blogjava.net/amigoxie/archive/2007/09/28/149074.html
2. js 接口
2.1 接口方式说明和优缺点
在开发的过程当中,也遇到过需要调用第三方接口的状况,好比笔者在完毕的一个股票查询的小 demo中,就需要调用新浪提供的股票查询的 js接口。另外有一次,在系统中使用了第三方的 GIS系统,调用的也是 js接口。 因为调用 js接口的门槛很是低,因此有的接口供应商会提供多种调用接口的方式,好比 Web Servivce接口和 js接口等。
对于浏览器来讲, script标签的 src属性所指向资源就跟 img标签的 src属性所指向的资源同样,都是一个静态资源,浏览器会在适当的时候本身主动去加 载这些资源,而不会出现所谓的跨域问题。这样咱们就可以经过该属性将要訪问的数据对象引用进当前页面而绕过 js跨域问题。固然,前提是接口必须是返回一段 js脚本,如一个 json对象数组定义的脚本:
modlist = [
{"modname": "mod1", "usernum": 200, "url": "/widget/info/1"},
{"modname": "mod2", "usernum": 300, "url" : "/widget/info/2"},
…
];
但 script标签也有必定的局限性,并不能解决所有 js跨域问题。 script标签的 src属性值不能动态改变以知足在不一样条件下获取不一样数据的需求, 更重要的是,不能经过这样的方式正确訪问以 xml内容方式组织的数据。
2.2 开发举例
2.2.1 新浪股票查询的js接口
功能说明 : stockDetail.jsp依据传入的 stockId參数,调用新浪股票查询提供的 js接口返回股票结果信息,并解析返回结果,将股票信息在页面展现出来。
stockDetail.jsp代码參考例如如下:
<%
@ page language = " java " contentType = " text/html; charset=UTF-8 " pageEncoding = " UTF-8 "
%>
<!
DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
>
<%
String stockId = request.getParameter( " stockId " );
if (stockId == null ) {
stockId = " 000001 " ;
}
%>
<
html
>
<
head
>
<
meta
http-equiv
="Content-Type"
content
="text/html; charset=UTF-8"
/>
<
title
>
股票查询结果
</
title
>
<
link
href
="<%=request.getContextPath() %>/css/style.css"
type
="text/css"
rel
="stylesheet"
>
<
script
type
="text/javascript"
src
="http://hq.sinajs.cn/list=s_sh<%=stockId %>"
charset
="gb2312"
></
script
>
<
meta
http-equiv
="pragma"
content
="no-cache"
>
<
meta
http-equiv
="cache-control"
content
="no-cache"
>
<
meta
http-equiv
="expires"
content
="0"
>
</
head
>
<
body
onload
=""
>
<
div
class
="bodyDiv"
>
<
table
>
<
tr
>
<
td
colspan
="2"
valign
="bottom"
align
="left"
style
="width:176px; background: url(<%=request.getContextPath() %>/images/line2_bg.gif) repeat-x;border-bottom: 1px solid #b0bec7;"
height
="19"
>
<
span
class
="titleFont"
>
<
font
class
="newTitleFont"
><
b
>
股票查询结果
</
b
></
font
>
</
span
>
</
td
>
</
tr
>
<
tr
>
<
td
>
指数名称:
</
td
>
<
td
><
span
id
="stockName"
>
</
span
></
td
>
</
tr
>
<
tr
>
<
td
>
当前点数:
</
td
>
<
td
><
span
id
="currentPoint"
>
</
span
></
td
>
</
tr
>
<
tr
>
<
td
>
当前价格:
</
td
>
<
td
><
span
id
="currentPrice"
>
</
span
></
td
>
</
tr
>
<
tr
>
<
td
>
涨跌率:
</
td
>
<
td
><
span
id
="ratio"
>
</
span
></
td
>
</
tr
>
<
tr
>
<
td
>
成交额(w):
</
td
>
<
td
><
span
id
=turnVolume
>
</
span
></
td
>
</
tr
>
<
tr
>
<
td
colspan
="2"
valign
="bottom"
align
="right"
style
="width:176px; background: url(<%=request.getContextPath() %>/images/line2_bg.gif) repeat-x;border-bottom: 1px solid #b0bec7;"
height
="19"
>
<
span
class
="titleFont"
>
<
font
class
="newTitleFont"
><
b
>
1日K线
0返回
</
b
></
font
>
</
span
>
</
td
>
</
tr
>
</
table
>
</
div
>
<
script
language
="javascript"
>
<!--
// 查询结果的格式为:指数名称,当前点数,当前价格,涨跌率,成交量(手),成交额(万元)
// 解析字符串
var stockValue = hq_str_s_sh <%= stockId %> ;
var stockArray = stockValue.split( " , " );
document.getElementById( " stockName " ).innerText = stockArray[ 0 ];
document.getElementById( " currentPoint " ).innerText = stockArray[ 1 ];
document.getElementById( " currentPrice " ).innerText = stockArray[ 2 ];
document.getElementById( " ratio " ).innerText = stockArray[ 3 ];
document.getElementById( " turnVolume " ).innerText = stockArray[ 5 ];
-->
</
script
>
</
body
>
</
html
>
带上 6位 stockId參数(好比:值为 000002),实时的 A股(代号为 s_sh000002)查询结果例如如下图所看到的:
在文件头部可看到例如如下一句引入了新浪提供的 js:
<
script
type
="text/javascript"
src
="http://hq.sinajs.cn/list=s_sh<%=stockId %>"
charset
="gb2312"
></
script
>
用例如如下语句得到经过接口查询到的数据:
var stockValue = hq_str_s_sh
<%
=
stockId
%>
;
2.2.2 对外提供js接口
对外提供js接口仅仅需要经过<script src="..." type="..."/>请求的地址返回的是JSON字符串就能够。
在本实例中,用到了笔者一篇 JSON文章的实例(《 JSON知识总结入门篇》: http://www.blogjava.net/amigoxie/archive/2010/09/25/332832.html ),在上面进行了小幅改动,简便起见,没有建立不论什么的Java类,提供的对外的js接口是直接经过json.txt,经过该文件返回一个JSON字符串,在实际的应用状况中,可以是一个Ation等。
json.txt定义了 JSON格式的字符串,并定义放在 json这个变量中, jsInterface.html文件请求远端的一个路径,然后解析返回的 JSON串,并打印出来。 json.txt在远端的一个server上,好比该文件訪问地址为: http://test.com/json.txt ,文件的内容例如如下:
var json={
"programmers": [
{ "firstName": "阿蜜果", "lastName":"McLaughlin", "email": "brett@newInstance.com" },
{ "firstName": "范范", "lastName":"Hunter", "email": "jason@servlets.com" },
{ "firstName": "高子", "lastName":"Harold", "email": "elharo@macfaq.com" }
],
"authors": [
{ "firstName": "安安", "lastName": "Asimov", "genre": "science fiction" },
{ "firstName": "Tad", "lastName": "Williams", "genre": "fantasy" },
{ "firstName": "Frank", "lastName": "Peretti", "genre": "christian fiction" }
],
"musicians": [
{ "firstName": "茂茂", "lastName": "Clapton", "instrument": "guitar" },
{ "firstName": "Sergei", "lastName": "Rachmaninoff", "instrument": "piano" }
]
}
在本地建立一个 jsInterface.html网页,使用 <script type="text/javascript" src=”…”/>请求返回 json字符串的路径信息,接着进行打印,该文件代码例如如下:
<
html
>
<
head
>
<
title
>
JS Interface Test
</
title
>
<
meta
http-equiv
="Content-Type"
content
="text/html; charset=UTF-8"
>
<
script
type
="text/javascript"
src
="http://test.com/json.txt"
></
script
>
<
script
type
="text/javascript"
>
alert(json.programmers[ 0 ].firstName + ',' + json.programmers[ 0 ].lastName + ',' + json.programmers[ 0 ].email);
alert(json.programmers[ 1 ].firstName + ',' + json.programmers[ 1 ].lastName + ',' + json.programmers[ 1 ].email);
alert(json.programmers[ 2 ].firstName + ',' + json.programmers[ 2 ].lastName + ',' + json.programmers[ 2 ].email);
alert(json.authors[ 0 ].firstName + ',' + json.authors[ 0 ].lastName + ',' + json.authors[ 0 ].genre);
alert(json.authors[ 1 ].firstName + ',' + json.authors[ 1 ].lastName + ',' + json.authors[ 1 ].genre);
alert(json.authors[ 2 ].firstName + ',' + json.authors[ 2 ].lastName + ',' + json.authors[ 2 ].genre);
alert(json.musicians[ 0 ].firstName + ',' + json.musicians[ 0 ].lastName + ',' + json.musicians[ 0 ].instrument);
alert(json.musicians[ 1 ].firstName + ',' + json.musicians[ 1 ].lastName + ',' + json.musicians[ 1 ].instrument);
</
script
>
</
head
>
<
body
>
</
body
>
</
html
>
执行后可看到执行结果与《 JSON 知识总结入门篇》第一个实例的执行结果一致。
3. http 接口
3.1 接口方式说明和优缺点
需要为第三方提供一个接口,原本打算继续使用 Web Service接口,结果那边的开发者说,他们没有使用过 Web Service接口(是作 IPTV的一个公司),但愿咱们能够提供 http方式的接口。
另外咱们通常在提供 Web Sservice接口的同一时候,也对外提供 http接口。
3.2 开发实例
3.2.1 向http接口发送消息的使用小程序
本实例对本身提供请求信息为xml格式的http接口,将xml格式的请求信息发给http接口的地址后,将调用接口的返回消息简单的显示在页面,为了简便起见,笔者没有对js代码进行包装。
该html文件代码例如如下:
<!
DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
>
<
html
>
<
head
>
<
meta
http-equiv
="Content-Type"
content
="text/html; charset=GB2312"
>
<
title
>
http interface test
</
title
>
<
meta
http-equiv
="pragma"
content
="no-cache"
>
<
meta
http-equiv
="cache-control"
content
="no-cache"
>
<
meta
http-equiv
="expires"
content
="0"
>
<
script
>
// XMLHttpRequest
var http_request = false ;
function send_request(method, url, content, responseType, callback)
{
http_request = false ;
// XMLHttpRequest
if (window.XMLHttpRequest)
{
// Mozilla
http_request = new XMLHttpRequest();
if (http_request.overrideMimeType)
{
// MIME
http_request.overrideMimeType( " text/xml " );
}
} else if (window.ActiveXObject)
{
// IE
try
{
http_request = new ActiveXObject( " Msxml2.XMLHTTP " );
} catch (e)
{
try
{
http_request = new ActiveXObject( " Microsoft.XMLHTTP " );
}
catch (e)
{}
}
}
if ( ! http_request)
{
window.alert( " XMLHttpRequest create Error. " );
return false ;
}
if (responseType.toLowerCase() == " text " || responseType.toLowerCase() == " xml " )
{
http_request.onreadystatechange = callback;
} else
{
window.alert( " error responseType. " );
return false ;
}
if (method.toLowerCase() == " get " )
{
http_request.open(method, url, true );
} else if (method.toLowerCase() == " post " )
{
http_request.open(method, url, true );
http_request.setRequestHeader( " Content-Type " , " text/xml " );
} else
{
window.alert( " http method error. " );
return false ;
}
http_request.send(content);
}
function submitInfo()
{
var form = document.httpTestForm;
var pathInfo = form.pathInfo.value;
var xmlInfo = form.xmlInfo.value;
form.returnInfo.value = " wait
" ;
send_request( " POST " , pathInfo, xmlInfo, " xml " , showHttpTestBack);
}
function showHttpTestBack()
{
if (http_request.readyState == 4 )
{
if (http_request.status == 200 )
{
var responseInfo = http_request.responseText;
var form = document.httpTestForm;
form.returnInfo.value = responseInfo;
}
}
}
</
script
>
</
head
>
<
body
>
<
form
name
="httpTestForm"
action
=""
method
="post"
>
<
table
width
="100%"
border
="1"
>
<
tr
>
<
td
colspan
="2"
align
="center"
>
<
b
>
http interface Test
</
b
>
</
td
>
</
tr
>
<
tr
>
<
td
>
xmlInfo:
</
td
>
<
td
>
<
textarea
id
="xmlInfo"
name
="xmlInfo"
cols
="100"
rows
="5"
></
textarea
>
</
td
>
</
tr
>
<
tr
>
<
td
>
pathInfo:
</
td
>
<
td
>
<
input
type
="text"
name
="pathInfo"
value
="http://192.168.2.154:16000/Mbd/http/video"
size
="100"
/>
</
td
>
</
tr
>
<
tr
>
<
td
>
returnInfo:
</
td
>
<
td
>
<
textarea
name
="returnInfo"
id
="returnInfo"
cols
="100"
rows
="5"
></
textarea
>
</
td
>
</
tr
>
<
tr
>
<
td
colspan
="2"
align
="center"
>
<
input
type
="button"
name
="submitButton1"
value
="Submit"
onclick
="javascript:submitInfo()"
/>
</
td
>
</
tr
>
</
table
>
</
form
>
</
body
>
</
html
>
訪问该页,页面很是easy,输入正确的 xml请求消息,和正确的路径信息,点击“ Submit”button,经过 ajax调用 httpport,并在成功取得信息后将返回结果显示在最后一个文本框:
3.2.2 做为提供商提供http接口
在这个实例中,server提供了一个 http接口,在这里是一个 jsp页面的訪问地址,实际应用过程当中,可以是 Servlet或 Action的訪问地址,在这个实例中,client发送 http get发送请求,带上了 hotel(宾馆信息)和 name(顾客姓名), http接口程序拿到參数信息后,依据必定算法检查分配空暇房间号,这里为了简便起见,仅仅是随机的生成一个数字返回给client。 http接口的简单程序 httpInterface.jsp例如如下所看到的:
<%
@ page language = " java " contentType = " text/html; charset=UTF-8 " pageEncoding = " UTF-8 "
%>
<!
DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
>
<%
Double room = 500 * Math.random();
out.write( " hotel= " + request.getParameter( " hotel " )
+ " ;name= " + request.getParameter( " name " )
+ " ;room= " + room.intValue());
out.close();
%>
<
html
>
<
head
>
<
meta
http-equiv
="Content-Type"
content
="text/html; charset=UTF-8"
/>
<
title
>
http Interface
</
title
>
<
meta
http-equiv
="pragma"
content
="no-cache"
>
<
meta
http-equiv
="cache-control"
content
="no-cache"
>
<
meta
http-equiv
="expires"
content
="0"
>
</
head
>
<
body
>
</
body
>
</
html
>
可在 IE 上带上參数訪问这个地址,可看到參考的结果信息,好比訪问 http://IP:port / 应用名称 /httpInterface.jsp?hotel=motel&name=amigo ,參考返回结果例如如下:
hotel=motel;name=amigo;room=407
4. 參考文章
1)《 Web Service入门》: http://tech.it168.com/j/2007-09-09/200709092111735.shtml
2)《 Web Service简单介绍特色 ,长处 ,缺点》:
http://hi.baidu.com/linjk03/blog/item/4ee93b03a5d29a8dd43f7cd5.html
3)《 Web Service百度百科》:
http://baike.baidu.com/view/67105.htm
4)《怎样解决 js跨域问题》:
http://www.yaronspace.cn/blog/index.php/archives/542