概念:
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,如需转载请自行联系原作者