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

简介:


概念:

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。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
<?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文件。

1
2
3
4
5
<?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方法。代码如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
<?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。代码如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
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;
        }
    }

F8FED7F3BB7C4808801FE1FA3AC1C220

参考文档:

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

















本文转自cnn23711151CTO博客,原文链接: http://blog.51cto.com/cnn237111/1285298,如需转载请自行联系原作者



相关文章
|
4天前
|
程序员 PHP 开发者
PHP中的异常处理:理解与实践
【10月更文挑战第36天】在编程的海洋里,异常处理是导航灯塔,指引我们避开错误的暗礁。本文将深入浅出地介绍PHP中如何通过try-catch语句来处理程序运行中的异常情况。我们将从基础语法入手,逐步过渡到高级用法,最后以一个实战案例来巩固知识点。无论你是PHP新手还是有经验的开发者,这篇文章都将帮助你提升代码的健壮性和可维护性。
|
9天前
|
安全 编译器 PHP
PHP 8新特性解析与实践应用####
————探索PHP 8的创新功能及其在现代Web开发中的实际应用
|
15天前
|
PHP 开发者
PHP中的面向对象编程实践
【10月更文挑战第25天】在探索PHP的世界中,面向对象编程(OOP)是一块基石。本文将通过浅显易懂的语言和生动的例子,带你领略PHP中OOP的魅力。从基础概念到实际应用,我们将一步步揭开OOP的神秘面纱,让你轻松掌握这一强大的编程范式。无论你是初学者还是有一定基础的开发者,这篇文章都将为你提供有价值的指导和启示。
|
23天前
|
开发框架 自然语言处理 PHP
PHP在Web开发中的持久魅力与创新实践###
【10月更文挑战第17天】 本文探讨了PHP作为一门老牌却充满活力的编程语言,在现代Web开发中的独特优势和未来趋势。通过分析其简洁性、灵活性、强大生态系统及不断创新的特性,本文旨在揭示PHP为何能持续吸引开发者,并在技术快速迭代的时代保持竞争力。同时,文章也展望了PHP在未来Web开发领域的发展潜力,强调其在技术创新和社区支持下,依然能够引领Web开发的新潮流。 ###
34 9
|
17天前
|
SQL 安全 Go
PHP在Web开发中的安全实践与防范措施###
【10月更文挑战第22天】 本文深入探讨了PHP在Web开发中面临的主要安全挑战,包括SQL注入、XSS攻击、CSRF攻击及文件包含漏洞等,并详细阐述了针对这些风险的有效防范策略。通过具体案例分析,揭示了安全编码的重要性,以及如何结合PHP特性与最佳实践来加固Web应用的安全性。全文旨在为开发者提供实用的安全指南,帮助构建更加安全可靠的PHP Web应用。 ###
32 1
|
18天前
|
PHP 开发者
PHP中的面向对象编程:基础与实践
【10月更文挑战第22天】本文旨在通过简明的语言和实例,介绍PHP中面向对象编程的基础知识和实际应用。文章将深入浅出地解释类、对象、继承、封装和多态等概念,并通过代码示例展示如何在PHP中实现这些面向对象的特性。无论你是PHP新手还是有一定基础的开发者,这篇文章都将帮助你更好地理解和应用面向对象编程,提升你的PHP开发技能。
|
20天前
|
PHP 数据安全/隐私保护 开发者
PHP 7新特性解析与实践
【10月更文挑战第20天】本文将深入浅出地介绍PHP 7的新特性,包括性能提升、语法改进等方面。我们将通过实际代码示例,展示如何利用这些新特性优化现有项目,提高开发效率。无论你是PHP新手还是资深开发者,都能从中获得启发和帮助。
|
19天前
|
PHP 开发者
PHP中的异常处理:理解与实践
【10月更文挑战第21天】在编程的世界里,错误和异常是不可避免的。它们像是路上的绊脚石,让我们的步伐变得蹒跚。然而,如果我们能够正确地处理这些错误和异常,那么我们就可以将它们转化为成长的机会,让我们的代码变得更强大、更健壮。本文将深入探讨PHP中的异常处理机制,带你一起学习如何捕获和处理异常,以及如何使用自定义异常类来增强你的应用程序的错误处理能力。让我们一起踏上这段旅程,探索如何在PHP中优雅地处理异常吧!
|
19天前
|
测试技术 C# 数据库
C# 一分钟浅谈:测试驱动开发 (TDD) 实践
【10月更文挑战第18天】测试驱动开发(TDD)是一种软件开发方法论,强调先编写测试代码再编写功能代码,以确保代码质量和可维护性。本文从 TDD 的基本概念入手,详细介绍了其核心步骤——编写测试、运行测试并失败、编写代码使测试通过,以及“红绿重构”循环。文章还探讨了 TDD 的优势,包括提高代码质量、促进设计思考、减少调试时间和文档化。此外,文中分析了常见问题及解决方案,如测试覆盖率不足、测试代码过于复杂、忽视重构和测试依赖过多,并通过一个简单的计算器类的代码案例,展示了 TDD 的实际应用过程。
32 1
|
15天前
|
关系型数据库 API PHP
PHP在Web开发中的优势与实践###
【10月更文挑战第24天】 PHP是一种流行的服务器端脚本语言,特别适合Web开发。其简单易学、灵活性高和广泛应用的特点,使其成为众多开发者的首选。本文将探讨PHP在Web开发中的主要优势及其实际应用,通过实例展示如何使用PHP构建高效、可靠的Web应用。无论你是初学者还是有经验的开发者,这篇文章都将提供有价值的见解和实用技巧。 ###
25 0