龍軍
摘要:該文在分析分布式異構(gòu)系統(tǒng)及面向服務(wù)架構(gòu)基礎(chǔ)上,對(duì)WebService和Restful WebService進(jìn)行比較,研究基于PHP+Apache的分布式系統(tǒng)構(gòu)架,最后從數(shù)據(jù)庫(kù)操作、Restful WebService的制作、HTML5前端、Android客戶端等方面進(jìn)行系統(tǒng)的研究和模型設(shè)計(jì)。
關(guān)鍵詞:分布式; PHP; WebService; Restful WebService
中圖分類號(hào):TP311? ? ? 文獻(xiàn)標(biāo)識(shí)碼:A? ? ? 文章編號(hào):1009-3044(2018)35-0087-03
隨著計(jì)算機(jī)軟硬件及網(wǎng)絡(luò)技術(shù)的發(fā)展,軟件系統(tǒng)規(guī)模、應(yīng)用領(lǐng)域、實(shí)現(xiàn)功能不斷擴(kuò)大,基于資源共享、高可用和并行處理的分布式異構(gòu)系統(tǒng)成為解決復(fù)雜應(yīng)用的有力工具。
1 分布式異構(gòu)系統(tǒng)(DHS)及面向服務(wù)架構(gòu)(SOA)概述
分布式系統(tǒng)是基于網(wǎng)絡(luò)具有高內(nèi)聚性和透明性的軟件系統(tǒng),異構(gòu)系統(tǒng)由不同硬件設(shè)備、操作系統(tǒng)、應(yīng)用軟件、數(shù)據(jù)等構(gòu)成,通過(guò)消息中間件在不同應(yīng)用間提供統(tǒng)一運(yùn)行的框架和接口,實(shí)現(xiàn)跨平臺(tái)數(shù)據(jù)傳輸,共同完成應(yīng)用任務(wù),并通過(guò)動(dòng)態(tài)增加或減少業(yè)務(wù)端,使業(yè)務(wù)系統(tǒng)具有良好的動(dòng)態(tài)負(fù)載伸縮能力。
面向服務(wù)架構(gòu)以基于XML/SOAP/Web Service/SCA/SDO/UDDI標(biāo)準(zhǔn)、可重用數(shù)據(jù)、業(yè)務(wù)服務(wù)組件為基礎(chǔ),圍繞業(yè)務(wù)流程,對(duì)業(yè)務(wù)邏輯進(jìn)行高度抽象的架構(gòu)模型和軟件開(kāi)發(fā)方式,將異構(gòu)平臺(tái)上不同應(yīng)用的功能組件封裝成有良好定義、與平臺(tái)無(wú)關(guān)、標(biāo)準(zhǔn)、可拼接拆卸、可復(fù)用的服務(wù),形成松散耦合的軟件系統(tǒng)。功能為獨(dú)立服務(wù),通過(guò)如REST、SOAP等遠(yuǎn)程通信協(xié)議,借助中間件來(lái)實(shí)現(xiàn)SOA需求。
2 WebService和Restful WebService的比較
WebService是跨編程語(yǔ)言及操作系統(tǒng)平臺(tái)的遠(yuǎn)程調(diào)用技術(shù),為網(wǎng)絡(luò)應(yīng)用開(kāi)發(fā)和使用提供統(tǒng)一的編程模型,通常被定義為一組模塊化API供外部使用,有基于WSDL、UDDI的簡(jiǎn)單對(duì)象訪問(wèn)協(xié)議(SOAP)方式和REST方式兩種。
SOAP協(xié)議方式的消息通過(guò)增加特定HTTP消息頭統(tǒng)一內(nèi)容格式,用XML格式封裝數(shù)據(jù),用HTTP協(xié)議進(jìn)行傳輸,用XSD定義標(biāo)準(zhǔn)的數(shù)據(jù)類型,將所有使用的數(shù)據(jù)類型均轉(zhuǎn)換為XSD類型。WSDL用XML描述WebService及其函數(shù)、參數(shù)和返回值,保存在Web服務(wù)器上,通過(guò)URL訪問(wèn),用UDDI發(fā)現(xiàn)WebService。
REST是一面向資源的架構(gòu)風(fēng)格,是一組架構(gòu)約束條件和原則,滿足約束條件和原則的程序就是RESTful。REST專門針對(duì)網(wǎng)絡(luò)應(yīng)用設(shè)計(jì)和開(kāi)發(fā),降低開(kāi)發(fā)復(fù)雜性,提高系統(tǒng)可伸縮性,將網(wǎng)絡(luò)上所有事物都抽象成有唯一標(biāo)識(shí)的資源。REST所有操作均無(wú)狀態(tài),遵循CRUD原則,只需創(chuàng)建POST、獲取GET、更新PUT和刪除DELETE四種行為就可完成相關(guān)操作和處理,通過(guò)統(tǒng)一簡(jiǎn)短的資源標(biāo)識(shí)符(URI)來(lái)識(shí)別和定位資源,并通過(guò)HTTP規(guī)范資源操作。
3 基于PHP的分布式系統(tǒng)構(gòu)架設(shè)計(jì)
PHP是開(kāi)源跨平臺(tái)的服務(wù)器端嵌入式腳本語(yǔ)言,已發(fā)展成完整的面向?qū)ο蟪绦蛟O(shè)計(jì)語(yǔ)言,語(yǔ)法簡(jiǎn)單、強(qiáng)大的數(shù)據(jù)庫(kù)支持、在服務(wù)器端執(zhí)行、會(huì)將用戶常訪問(wèn)的程序駐留內(nèi)存、效率高,得到廣泛應(yīng)用。
本模型基于PHP+Apache+MySql,用PHP的類完成數(shù)據(jù)增刪改查等操作,用SOAP WebService和Restful WebService對(duì)前端請(qǐng)求進(jìn)行合法判斷,調(diào)用類進(jìn)行數(shù)據(jù)處理,返回JSON格式數(shù)據(jù)給前端,前端為Web應(yīng)用、移動(dòng)端的Native App和Web App應(yīng)用,在本模型中原生程序基于Android、Web App用HTML5。
4 數(shù)據(jù)庫(kù)操作類
PHP數(shù)據(jù)對(duì)象PDO擴(kuò)展定義了輕量級(jí)的接口訪問(wèn)數(shù)據(jù)庫(kù),提供了一數(shù)據(jù)訪問(wèn)的抽象,對(duì)所有數(shù)據(jù)庫(kù)均可用相同的函數(shù)/方法來(lái)操作。在類的構(gòu)造方法__construct()中設(shè)置服務(wù)器地址、數(shù)據(jù)庫(kù)名以及登錄名和密碼。創(chuàng)建連接數(shù)據(jù)庫(kù)函數(shù)conn()連接服務(wù)器并選擇數(shù)據(jù)庫(kù):
$link=new PDO("mysql:host=$hostname;dbname=$db_name", $username,$password);
通過(guò)傳入sql語(yǔ)句,完成表的增刪改函數(shù)zcg($sql):$this→link→exec($sql)。
[傳入sql語(yǔ)句查詢一條記錄 傳入sql語(yǔ)句查詢符合條件的多條記錄 $result=$this->link->query($sql);
if($row=$result->fetch_object()){
$a=array('id'=>$row->Id,'yhm'=>$row->yhm,'mm'=>$row->mm);
$json=json_encode($a);
}else
$json='{"id":"0"}}'; $result=$this->link->query($sql);
$num=$result->num_rows;
$a=array();
while($row=$result->fetch_object()){
$b=array('id'=>$row->Id,'yhm'=>$row->yhm,'mm'=>$row->mm);
$a[$i]=json_encode($b);
$i=$i+1;} ]
5 Restful WebService
1) RESTful 基礎(chǔ)類:新建一個(gè)RESTful基類,用于處理響應(yīng)請(qǐng)求的HTTP狀態(tài)碼。
[private $httpVersion = "HTTP/1.1";
public function setHttpHeaders($contentType, $statusCode){
$statusMessage = $this -> getHttpStatusMessage($statusCode);
header($this->httpVersion. " ". $statusCode ." ". $statusMessage);
header("Content-Type:". $contentType);}
public function getHttpStatusMessage($statusCode){
$hs = array(100 => 'Continue', 101 => 'Switching Protocols', 200 => 'OK',...);
return ($hs[$statusCode]) ? $hs[$statusCode] : $status[500];} ]
2) RESTful WebService處理類:新建一個(gè)RESTful基類的子類,根據(jù)接收到的Content-Type,將Request類返回的數(shù)據(jù)轉(zhuǎn)換為對(duì)應(yīng)的格式,加上header后輸出HTTP 狀態(tài)碼及數(shù)據(jù)。
[多條記錄getYhbRows($kw) 一條記錄getYhbRow($id) $yhb = new yhb();
$sql="select * from yhb where yhm like ‘%”+$key+”% order by Id desc";
$rawData = $yhb->getRows($sql);
if(empty($rawData)) {
$sCode = 404;
$rawData = array('error' => '無(wú)記錄!');
} else? $sCode = 200;
$rcType = $_SERVER['HTTP_ACCEPT'];
$this ->setHttpHeaders($rcType, $sCode);
echo $rawData; $yhb = new yhb();
$sql="select * from yhb where id="+$id;
$rawData = $yhb->getRow($sql);
if(empty($rawData)) {
$sCode = 404;
$rawData = array('error' => '無(wú)記錄!');
} else
$sCode = 200;
$rcType= $_SERVER['HTTP_ACCEPT'];
$this ->setHttpHeaders($rcType, $sCode);
echo $rawData; ]
3) RESTful WebService控制器:包含一數(shù)據(jù)操作的Request類,接收到URL的數(shù)據(jù)后,根據(jù)請(qǐng)求URL的GET、POST、PUT、PATCH、DELETE方式對(duì)數(shù)據(jù)進(jìn)行相應(yīng)的增刪改查操作,并返回操作后的結(jié)果。要注意的是在PHP文件開(kāi)始時(shí)允許跨域。
[header("Access-Control-Allow-Origin:*");
$method=$_SERVER['REQUEST_METHOD'];
$view = "";
if(isset($_GET["view"]))? $view = $_GET["view"];
$yhbHandler = new YHBHandler();
if($view=="all") $yhbHandler ->getYhbRows();
else if($view=="single") $yhbHandler ->getYhbRow($_GET["id"]); ]
4) RESTful Services URI映射:設(shè)置一直觀簡(jiǎn)短的資源地址,在配置文件htaccess中設(shè)置相應(yīng)的Rewrite規(guī)則實(shí)現(xiàn)URL重寫(rewrite)與重定向(redirect)。
[# 開(kāi)啟 rewrite 功能
Options +FollowSymlinks
RewriteEngine on
# 重寫規(guī)則
RewriteRule ^list/$? ?YhbController.php?view=all [nc,qsa]
RewriteRule ^read/([0-9]+)/$? ?YhbController.php?view=single&id=$1 [nc,qsa] ]
6 基于HTML5的Web端和移動(dòng)端
Web應(yīng)用及移動(dòng)端的Web App通過(guò)jQuery的post、get方法進(jìn)行數(shù)據(jù)處理及交互。
[GET方式 POST方式 $.get("網(wǎng)址/read/"+$("#id").val()+"/",
function(data){
json=JSON.parse(data);
$("#xs").html("id=" + json.id + "<br>用戶名=" + json.yhm + "<br>密碼=" + json.mm);
},"json"); $.post("網(wǎng)址/list/",{kw:$("#kw").val()},
function(data){
var a1=JSON.parse(data);
if(a1.length>0){var str="";
for(var i=0;i<a1.length;i++){
var a=JSON.parse(a1[i]);
str+="id:"+a.id+",用戶名:"+a.yhm+",密碼:"+a.mm+"<br>";}
$("#xs").html(str);}},"json"); ]
7 Android端原生應(yīng)用
在Android中可用HttpPost和HttpGet封裝post請(qǐng)求和get請(qǐng)求,用HttpClient的excute()發(fā)送post請(qǐng)求并返回服務(wù)器響應(yīng)數(shù)據(jù)。用HttpResponse的getAllHeaders()、getHeaders(String name)等獲取服務(wù)器的響應(yīng)頭,用getEntity()獲取包裝有服務(wù)器響應(yīng)內(nèi)容的HttpEntity對(duì)象,程序通過(guò)該對(duì)象獲取服務(wù)器的響應(yīng)內(nèi)容。
[GET方式 POST方式 String urls="網(wǎng)址/read/"+id+"/";
HttpClient hc=new DefaultHttpClient(); String urls="網(wǎng)址/list/";
HttpPost hp=new HttpPost(urls);
List<NameValuePair> p=new ArrayList<NameValuePair>(); HttpGet hg=new HttpGet(urls);
HttpResponse hr=hc.execute(hg);
HttpEntity he=hr.getEntity();
r=EntityUtils.toString(he,"utf-8"); p.add(new BasicNameValuePair("kw",e.getText().toString()));
hp.setEntity(new UrlEncodedFormEntity(par,"utf-8"));
HttpClient hc=new DefaultHttpClient();
HttpResponse hr=hc.execute(hp);
HttpEntity he=hr.getEntity();
r=jtos(EntityUtils.toString(he,"utf-8")); ]
在模型應(yīng)用間采用JSON格式數(shù)據(jù)進(jìn)行傳輸,JSON是輕量級(jí)的數(shù)據(jù)交換語(yǔ)言,JSON和XML均有相同的數(shù)據(jù)可讀性和豐富的解析手段,JSON相較XML數(shù)據(jù)體積小、與JavaScript交互更方便、速度快,但JSON的數(shù)據(jù)描述性差。
RESTful架構(gòu)層次分明、結(jié)構(gòu)清晰,輕量級(jí)JSON格式在數(shù)據(jù)交換中易訪問(wèn)、可擴(kuò)展,能輕易實(shí)現(xiàn)多種數(shù)據(jù)、多種服務(wù)的聚合,提高了軟件系統(tǒng)的開(kāi)發(fā)效率,基于PHP的分布式應(yīng)用系統(tǒng)開(kāi)發(fā)應(yīng)用面將越來(lái)越廣。
參考文獻(xiàn):
[1] 王非. RESTful Web Services在信息系統(tǒng)中的應(yīng)用[J]. 計(jì)算機(jī)系統(tǒng)應(yīng)用,2013(22).
[2] 萬(wàn)為清. WebService技術(shù)在分布式開(kāi)發(fā)中的應(yīng)用與實(shí)現(xiàn)[J]. 電腦編程技巧與維護(hù),2017(18).
[3] 徐曉琴. 基于WebService技術(shù)的SAP接口實(shí)現(xiàn)[J]. 電腦知識(shí)與技術(shù),2018(14).
[4] 張琛. 分布式軟件系統(tǒng)交互行為建模、驗(yàn)證與測(cè)試[J]. 計(jì)算機(jī)研究與發(fā)展,2015(52).
[5] 黃博怡. Web Services技術(shù)手段在異構(gòu)系統(tǒng)集成中的應(yīng)用實(shí)踐[J]. 現(xiàn)代工業(yè)經(jīng)濟(jì)和信息化,2017(9).
[通聯(lián)編輯:梁書(shū)]