ITPub博客

首页 > 应用开发 > IT综合 > 实践基于REST风格的Webservice(PHP,C#)

实践基于REST风格的Webservice(PHP,C#)

原创 IT综合 作者:mqp26180 时间:2020-09-18 12:15:14 0 删除 编辑

  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。

  <?php

  switch($_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文件,即用逗号分割数据的文本文件。数据文件如下:

  CBD247FF7AF9473193DC06EB24DBCCC8

  由于REST风格的web服务可以通过浏览器验证,因此可以输入url地址测试。本例中没有采用url重写,如果使用url重写的话,服务地址会更友好。

  D87BE31CF24D416BA901BA11EF15A2A6

  服务部署好之后,就可以调用了。在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);

  ?>

  74A2BDE9531F4A879C284A805D575126

  通过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对象。而且数据库中数据也已经写入。

  5ABB6024DDF8491FAE0A051F8E524C15

  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;

  }

  }


来自 “ ITPUB博客 ” ,链接:https://blog.itpub.net/69976881/viewspace-2722198/ ,如需转载,请注明出处,否则将追究法律责任。

请登录后发表评论 登录
全部评论

注册时间:2020-07-28

  • 博文量
    13
  • 访问量
    16046