实践基于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文件,即用逗号分割数据的文本文件。数据文件如下:
由于REST风格的web服务可以通过浏览器验证,因此可以输入url地址测试。本例中没有采用url重写,如果使用url重写的话,服务地址会更友好。
服务部署好之后,就可以调用了。在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 );
?>
|
通过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对象。而且数据库中数据也已经写入。
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;
}
}
|
参考文档:
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,如需转载请自行联系原作者
实践基于REST风格的Webservice(PHP,C#)相关推荐
- 管道 过滤器风格 java_完成基于管道过滤器风格的KWI实现.doc
完成基于管道过滤器风格的KWI实现.doc 实验2:软件体系结构风格实现 一.实验目的 初步了解不同的体系结构风格 掌握不同体系结构风格的实现 二.实验学时 4学时. 三.实验方法 根据KWIC的描述 ...
- 用cxf开发restful风格的WebService
我们都知道cxf还可以开发restful风格的webService,下面是利用maven+spring4+cxf搭建webService服务端和客户端Demo 1.pom.xml <projec ...
- Mycat社区出版: 分布式数据库架构及企业实践——基于Mycat中间件
书名: 分布式数据库架构及企业实践--基于Mycat中间件 作者:周继锋 冯钻优 陈胜尊 左越宗 ISBN:978-7-121-30287-9 出版年月:2016年11月 定价:79元 开本:787× ...
- 基于注解风格的Spring-MVC的拦截器
Spring-MVC如何使用拦截器,官方文档只给出了非注解风格的例子.那么基于注解风格如何使用拦截器呢? 基于注解基本上有2个可使用的定义类,分别是DefaultAnnotationHandlerMa ...
- Spring Boot文档阅读笔记-构建Restful风格的WebService
Maven代码如下: <?xml version="1.0" encoding="UTF-8"?> <project xmlns=" ...
- 知识图谱入门2-1:实践——基于医疗知识图谱的问答系统
注:欢迎关注datawhale:https://datawhale.club/ 系列: 知识图谱入门一:知识图谱介绍 知识图谱入门2-1:实践--基于医疗知识图谱的问答系统 知识图谱入门2-2:用户输 ...
- 使用ASP.NET Web Api构建基于REST风格的服务实战系列教程
最近发现web api很火,园内也有各种大神已经在研究,本人在asp.net官网上看到一个系列教程,原文地址:http://bitoftech.net/2013/11/25/detailed-tuto ...
- 分布式数据库架构及企业实践--基于Mycat中间件pdf
下载地址:网盘下载 内容提要 编辑 <分布式数据库架构及企业实践--基于Mycat中间件>由资深 Mycat 专家及一线架构师.DBA 编写而成.全书总计 8 章,首先简单介绍了分布式系统 ...
- 机器学习实践—基于Scikit-Learn、Keras和TensorFlow2第二版—第9章 无监督学习技术(Chapter9_Unsupervised_Learning_Techniques)
机器学习实践-基于Scikit-Learn.Keras和TensorFlow2第二版-第9章 无监督学习技术(Chapter9_Unsupervised_Learning_Techniques) 虽然 ...
最新文章
- 曲苑杂坛--收缩数据库文件
- P1024 一元三次方程求解(递归式二分)
- 分割命令: split
- 解决局域网共享好用脚本集
- linux mysql数据库备份并删除前一分钟的数据
- pycharm profile对函数调用效率进行测试
- 【redis3在linux安装与基本操作】
- 人少钱少需求多的新项目该怎么带?看到这篇我心里有底了!
- 转义sed替换模式的字符串
- 缺失索引自动创建语句
- GRE阅读高频机经原文及答案之Design-Engineering
- python安装pyqt4_如何使用pip在Windows上安装PyQt4?
- 【Java愚公】gitlab关闭注册功能
- 【信息检索导论】第一章 布尔检索
- 微信公众平台开发(121) 微信二维码海报
- E1使用Padavan固件网口做WAN的设置
- [JavaScript学习记录] 首次运用于网页,做一个简易利息计算器!!!
- xgb.cv进行交叉验证
- pip安装命令大全(持续更新)
- python封装mel命令
热门文章
- 【Spark亚太研究院系列丛书】Spark实战高手之路-第一章 构建Spark集群(第二步)(4)...
- 《ActionScript3.0 游戏设计基础(第二版)》随书代码和附赠章节(共4章)
- GSL库在VC6.0上的配置
- eclipse导入myeclipse的web项目在eclipse中不能识别成web项目
- C#未来新特性:静态委托和函数指针
- ruby require的使用
- 新版微信对付款码截屏做处理 防止被骗
- 约瑟夫问题(c++)
- Linux 2.6内核编译与配置安装升级
- Python数据分析工具:Pandas_Part 1