自从2个Google创始人卖了股票跑路了之后,自从Google发明了云计算(让我想起.Net刚出道时候的Web Service),Google就越来越微软了 -- 我是说的技术.
我以前看过Windows的完成端口,和Linux的epoll比起来简直是可以让人吐血.一大堆乱七八糟的参数,不少甚至写着系统内部使用,我囧啊囧.我足足看了一个月,才看懂了这个满屏都是匈牙利命名法的东东.
从此以后,我发誓再也不用直接完成端口写代码了.
不过,我们今天的主题是Google倡导的标准.
先来看看Gdata,一个与XML完全等价的Json数据:
举一个简单的例子:
以下面的json为例子
{"entry":[{"category":[{"@scheme":"http://www.douban.com/2007#kind","@term":"http://www.douban.com/2007#miniblog.note"}],"title":{"$t":"写了新日记什么是YY,这就是YY"},"content":{"$t":"写了新日记<a
href=\"http://www.douban.com/note/20025875/\">什么是YY,这就是YY</a>","@type":"html"},"link":[{"@rel":"related","@href":"http://api.douban.com/note/20025875"}],"published":{"$t":"2008-10-19T00:11:50+08:00"},"id":{"$t":"http://api.douban.com/miniblog/70368743"}},{"category":[{"@scheme":"http://www.douban.com/2007#kind","@term":"http://www.douban.com/2007#miniblog.book"}],"title":{"$t":"想读2066年之西行漫记"},"content":{"$t":"想读<a
href=\"http://www.douban.com/subject/1640220/\">2066年之西行漫记</a>","@type":"html"},"link":[{"@rel":"related","@href":"http://api.douban.com/book/subject/1640220"},{"@rel":"image","@href":"http://otho.douban.com/spic/s1797022.jpg"}],"published":{"$t":"2008-10-18T23:27:33+08:00"},"db:attribute":[{"$t":"collection","@name":"category"},{"$t":"wish","@name":"status"}],"id":{"$t":"http://api.douban.com/miniblog/70351748"}},{"content":{"$t":"上校内,关心一下同学境况
..........................................................................................
1,
第一点,也是最不友好的一点
不能直接用 " . " 来点出属性来
比如,我必须要这样写
if(this["db:attribute"]) ....
而不能 直接写 if(this.db.attribute)
这样解析的时候就非常麻烦 @,$这些奇怪的符号,都会打断.的流畅操作
比如说this["db:attribute"].id["$t"]与this.db.id比较实在的太啰嗦了
2.
时间的表示:
"$t":"2008-10-19T00:11:50+08:00"
这是什么时间格式?不能直接拿来做当作Date的初始化,我不得不这样写
time=this.published.$t.split("T");
time[0]=time[0].split('-');
time[1]=time[1].split('+')[0].split(':');
new Date(
time[0][0],
time[0][1]-1,
time[0][2],
time[1][0],
time[1][1],
time[1][2])
很痛苦吧.
3.嵌套层次太深,很多没有意义的变量名称
{"entry":[{"category":[{"@scheme":"http://www.douban.com/2007#kind","@term":"http://www.douban.com/2007#miniblog.note"}],"title":{"$t":"写了新日记什么是YY,这就是YY"},"content":{"$t":"写了新日记<a
href=\"http://www.douban.com/note/20025875/\">什么是YY,这就是YY</a>","@type":"html"},"link":[{"@rel":"related","@href":"http://api.douban.com/note/20025875"}],"published":{"$t":"2008-10-19T00:11:50+08:00"},"id":{"$t":"http://api.douban.com/miniblog/70368743"}},{....
首先entry就是一个没有用的变量名,直接返回一个数组是很直观的事情
scheme这个东西有什么用?term完全可以是"miniblog.note",无需那么冗余的前缀?
"title":{"$t":"写了新日记什么是YY,这就是YY"} ,这个$t就是完全无用的 title:"xxx"不是很直观吗?
id,published等等所有东西都有一个这个$t,实在是不胜其烦.
"link":[{"@rel":"related","@href":"http://api.douban.com/book/subject/1640220"},{"@rel":"image","@href":"http://otho.douban.com/spic/s1797022.jpg"}
这种link写法也很是多余
link:"http://api.douban.com/book/subject/1640220",
image:"http://otho.douban.com/spic/s1797022.jpg"
完全可以胜任
难道想要一个可以从XML自动转换Json格式就必须这么痛苦吗?当然,不是.
我们看看yahoo的Json格式
http://developer.yahoo.com/common/json.html
{"ResultSet":{
"totalResultsAvailable":"229307",
"totalResultsReturned":"2",
"firstResultPosition":"1",
"Result":[
{
"Title":"madonna 116",
"Summary":"Picture 116 of 184",
"Url":"http:\/\/www.celebritypicturesarchive.com\/pictures\/m\/madonna\/madonna-116.jpg",
..................
Yahoo! Web Services输出的XML和JSON包含相同的数据;唯一的差别是数据格式。基于不同的服务,从XML转换成JSON符号的方法可能有所不同,但一般你只需要遵循以下规则:
* 响应只存在一个顶层对象。
* 把简单的XML元素(元素只包含内容)转换成字符串/值组合。
* 把复杂的XML元素(包含其它嵌套元素)转化成嵌套对象。
* 把属性转化为字符串/值组合。
* 如果一个元素同时包含内容和属性,属性转化成字符/值的组合,内容转化成content命名的字符/值组合
2.oauth
Oauth是一个很龌龊的协议
1.首先要申请 一个Request Token
2.用户授权给Request Token
3.Request Token换取Access Token
每次都需要下面的参数
oauth_consumer_key API Key
oauth_signature_method 签名方法,豆瓣支持OAuth中定义的HMAC-SHA1, RSA-SHA1和PLAINTEXT三种签名方式
oauth_signature 签名值
oauth_timestamp 时间戳,用格林威治时间1970年1月1日0时0分0秒起的秒数表示,下同
oauth_nonce 单次值,一个随机字符串,用于防止重放攻击
然后每次访问还有加上一堆参数
Oh,我手工调试程序都很麻烦,非常麻烦.
当然也有更好的办法,见 http://is.gd/5xV4 ,这是"第二人生"用的协议,八卦一个,第二人生服务器也是用的python
简单的说,就是获得一个唯一的一次性url,通过这个url来访问数据.OK.
至于什么中间人攻击,什么回放攻击,让他们见鬼去吧.http访问还不是能被这样攻击,窃取一下cookie就ok了.
不过想要安全也可以,认证流程可以和oauth一致,然后认证之后就通过唯一的url访问.可以登出和超时就可以了.
当然技术性的描述有点绕,看下面.
* caps.py: capability 服务,客户(Viewer)请求capability服务获取对特定功能的访问。
/cap/grant
调用该服务将记住Private URL,并返回一个Public URL(Capability 服务的代理地址)
/cap/multigrant
/cap/revoke
取消某个PublicURL对应。
/cap/UUID 为调用capability 代理服务。
例子:看看登录的时候如何获得 AgentHost会话的(Seed) Capability 服务URL,首先客户进行登录(login server),login Server 在 AgentHost上启动一个新的会话,AgentHost想授权客户能访问该服务,于是AgentHost将该会话(seed)服务的私有URL传递给 capability 服务,执行 /cap/grant ,返回该seed服务的PublicURL,然后AgentHost将该PublicURL地址发给登录服务,登录服务在作为登录响应一起返回给客户。
好了,下次你就可以和AgentHost会话服务交谈了——通过Capability 代理服务。连接该PublicURL,实际上是连接上Capability 代理服务,Capability 代理服务然后在查找public对应的 privateURL,并将动作转发给该privateURL。 AgentHost Seed服务将检查你访问授权,通过之后才返回给你新的PublicURL去访问新的服务。