實踐基於REST風格的Webservice(PHP,C#)

來源:互聯網
上載者:User

概念:

WEB服務的風格,從維基百科上查了一下,有不下十幾種,但是比較常用的就是REST和RPC。其中,基於SOAP協議的Webservice就是RPC風格的。

REST全稱Representational State Transfer。它是基於無狀態的,cs結構的,可以緩衝的通訊協定。事實上,它是使用 HTTP協議的。某些觀點來看,互連網本身就是基於HTTP的,因此也可以認為是一種基於REST風格的Webservice。REST風格的Webservice對於SOAP,CORBA一種和SOAP互相競爭的協議)來說,屬於輕量級。請求較之於也比較簡單。比如,用SOAP的Webservice的請求可能是如下這樣的一個XML,有用的資訊都被包括在冗餘的資訊中:

<?xml version="1.0"?>

<soap:Envelope

xmlns:soap="http://www.w3.org/2001/12/soap-envelope"

soap:encodingStyle="http://www.w3.org/2001/12/soap-encoding">

<soap:body pb="http://www.acme.com/phonebook">

 <pb:GetUserDetails>

  <pb:UserID>12345</pb:UserID>

 </pb:GetUserDetails>

</soap:Body>

</soap:Envelope>

而使用REST的請求就很簡單,只是一個URL地址:http://www.acme.com/phonebook/UserDetails/12345,只需要使用瀏覽器就能驗證這個REST的Webservice是否正常。HTTP的請求方式有多種,GET,POST,PUT,PATCH,DELETE。REST同樣可以利用這些請求方式。REST的Webservice的響應通常是一個XML檔案,但是和SOAP不同的是,REST並不一定需要響應返回XML檔案,它也可以是CSV格式或者Json格式。

很多公司都採用REST風格的Webservice,比如 Google Glass API,Twitter,Yahoo,Flickr,Amazon等。比如Google有一個Webservice,Google Maps API,它提供2種輸出格式,JSON和XML。地址分別是http://maps.googleapis.com/maps/api/geocode/json?parameters和http://maps.googleapis.com/maps/api/geocode/xml?parameters

該服務的具體使用方法和參數滿可以查閱https://developers.google.com/maps/documentation/geocoding/?hl=zh-CN&csw=1#XML

示範:

下面示範一個基於PHP語言開發的REST風格的webservice。

<?phpswitch($_SERVER['REQUEST_METHOD']){    case 'GET':        $id=$_GET["id"];        $arrayid = explode(",", $id);        search($arrayid);        break;    case 'POST':        $id=$_POST["id"];        $username=$_POST["username"];        $sex=$_POST["sex"];        $age=$_POST["age"];                                              add($id,$username,$sex,$age);        break;    default:        exit();}function search($arrayid){    $users=getCsvFile("example.csv");    $string="";    foreach($users as $a)    {        $id=$a[0];        if(in_array($id,$arrayid))        {            $string.= <<<EOF    <user id="$a[0]">        <name>$a[1]</name>        <sex>$a[2]</sex>        <age>$a[3]</age>    </user>EOF;        }    }    $string="<?xml version=\"1.0\" encoding=\"UTF-8\"?>\r\n"            ."<data>\r\n"            .$string            ."</data>";                                      header("Content-type:application/xml");    print($string);                                  }function add($id,$username,$sex,$age){    $users=getCsvFile("example.csv");    $string="$id,$username,$sex,$age";                                      WriteLinetxt($string,"example.csv");                                      $string="<?xml version=\"1.0\" encoding=\"UTF-8\"?>\r\n"            ."<return>\r\n"            ."  <status>0</status>\r\n"            ."</return>\r\n";                                      header("Content-type:application/xml");    print($string);                                  }function getCsvFile($filepath)    {        $handle=null;        $returnvalue=array();        try        {            $handle = fopen($filepath,"r");            while ($data = fgetcsv($handle, 1000, ","))            {                array_push($returnvalue,$data);            }            fclose($handle);        }        catch(Exception $e)        {            fclose($handle);            $handle=null;            die("Error!: ".$e->getMessage()."<br/>");        }                                              return $returnvalue;    }function WriteLinetxt($content,$filename){        file_put_contents($filename, $content."\r\n",FILE_APPEND);}?>

代碼說明:

上述代碼,根據請求的方式是POST還是GET來區分,如果是GET的話,則需帶上查詢的ID。服務會返回一個Content-type為application/xml的一份xm文檔。如果是POST的話,則會把相應的POST進來的值寫入到資料庫。

本例中,資料庫只是簡單的採用CSV檔案,即用逗號分割資料的文字檔。資料檔案如下:

650) this.width=650;" style="border-bottom:0px;border-left:0px;border-top:0px;border-right:0px" title="CBD247FF7AF9473193DC06EB24DBCCC8" border="0" alt="CBD247FF7AF9473193DC06EB24DBCCC8" src="http://www.bkjia.com/uploads/allimg/131228/1124314622-0.jpg" height="169" />

由於REST風格的web服務可以通過瀏覽器驗證,因此可以輸入url地址測試。本例中沒有採用url重寫,如果使用url重寫的話,服務地址會更友好。

650) this.width=650;" style="border-bottom:0px;border-left:0px;border-top:0px;border-right:0px" title="D87BE31CF24D416BA901BA11EF15A2A6" border="0" alt="D87BE31CF24D416BA901BA11EF15A2A6" src="http://www.bkjia.com/uploads/allimg/131228/1124312N4-1.jpg" height="431" />

服務部署好之後,就可以調用了。在PHP中,可以通過simplexml_load_file方法,get到這個xml檔案。

<?php$url="http://localhost:8080/b.php?id=1001,1003,1004";$response=simplexml_load_file($url);var_dump($response);?>

650) this.width=650;" style="border-bottom:0px;border-left:0px;border-top:0px;border-right:0px" title="74A2BDE9531F4A879C284A805D575126" border="0" alt="74A2BDE9531F4A879C284A805D575126" src="http://www.bkjia.com/uploads/allimg/131228/1124313A5-2.jpg" height="536" />

通過var_dump,可以看到獲得的直接是一個SimpleXMLElement對象,當然你也可以把它轉換成string對象。

下面用php代碼實現類比POST資料。PHP常用的類比POST動作的方法有3種,分別為Curl、socket、file_get_contents,這裡還是採用file_get_contents方法。代碼如下:

<?php$url="http://localhost:8080/b.php";$data = array(    'id' => '1990',    'username' => '小張',    'sex' => '男','age'=>'20');$post_string=http_build_query($data);$context = array(    'http' => array(        'method' => 'POST','header'=>'content-type: application/x-www-form-urlencoded',        'content' => $post_string)    );$stream_context = stream_context_create($context);$response = file_get_contents($url, false, $stream_context);$xml=simplexml_load_string($response);var_dump($xml);?>

代碼中,類比了POST提交,並且獲得了返回的string,再把string轉成了SimpleXMLElement對象。而且資料庫中資料也已經寫入。

650) this.width=650;" style="border-bottom:0px;border-left:0px;border-top:0px;border-right:0px" title="5ABB6024DDF8491FAE0A051F8E524C15" border="0" alt="5ABB6024DDF8491FAE0A051F8E524C15" src="http://www.bkjia.com/uploads/allimg/131228/1124315293-3.jpg" height="127" />

C#版本訪問:

C#也可以通過代碼調用PHP寫的REST風格的Webservice。代碼如下:

class Program   {       static void Main(string[] args)       {           string[] paramName = { "id" };           string[] paramVal = { "1001,1004" };           var p = HttpGet("http://localhost:8080/b.php", paramName, paramVal);           Console.WriteLine(p);           Console.WriteLine("-------------------------------");           string[] paramName1 = { "id", "username", "sex", "age" };           string[] paramVal1 = { "1030", "tom", "男", "23" };           var p1 = HttpPost("http://localhost:8080/b.php", paramName1, paramVal1);           Console.WriteLine(p1);       }       static string HttpGet(string url, string[] paramName, string[] paramVal)       {           StringBuilder paramz = new StringBuilder();           for (int i = 0; i < paramName.Length; i++)           {               paramz.Append(paramName[i]);               paramz.Append("=");               paramz.Append(HttpUtility.UrlEncode(paramVal[i]));               paramz.Append("&");           }           url += "?" + paramz.ToString();           HttpWebRequest req = WebRequest.Create(url) as HttpWebRequest;           string result = null;           using (HttpWebResponse resp = req.GetResponse() as HttpWebResponse)           {               StreamReader reader = new StreamReader(resp.GetResponseStream());               result = reader.ReadToEnd();           }           return result;       }       static string HttpPost(string url, string[] paramName, string[] paramVal)       {           HttpWebRequest req = WebRequest.Create(new Uri(url)) as HttpWebRequest;           req.Method = "POST";           req.ContentType = "application/x-www-form-urlencoded";           // Build a string with all the params, properly encoded.           // We assume that the arrays paramName and paramVal are           // of equal length:           StringBuilder paramz = new StringBuilder();           for (int i = 0; i < paramName.Length; i++)           {               paramz.Append(paramName[i]);               paramz.Append("=");               paramz.Append(HttpUtility.UrlEncode(paramVal[i]));               paramz.Append("&");           }           // Encode the parameters as form data:           byte[] formData = UTF8Encoding.UTF8.GetBytes(paramz.ToString());           req.ContentLength = formData.Length;           // Send the request:           using (Stream post = req.GetRequestStream())           {               post.Write(formData, 0, formData.Length);           }           // Pick up the response:           string result = null;           using (HttpWebResponse resp = req.GetResponse() as HttpWebResponse)           {               StreamReader reader = new StreamReader(resp.GetResponseStream());               result = reader.ReadToEnd();           }           return result;       }   }

650) this.width=650;" style="border-bottom:0px;border-left:0px;border-top:0px;border-right:0px" title="F8FED7F3BB7C4808801FE1FA3AC1C220" border="0" alt="F8FED7F3BB7C4808801FE1FA3AC1C220" src="http://www.bkjia.com/uploads/allimg/131228/1124314302-4.jpg" height="335" />

參考文檔:

http://geeknizer.com/rest-vs-soap-using-http-choosing-the-right-webservice-protocol/

http://msdn.microsoft.com/zh-cn/magazine/dd942839.aspx

http://www.gen-x-design.com/archives/create-a-rest-api-with-php/

http://rest.elkstein.org/2008/02/what-is-rest.html

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.