91超碰碰碰碰久久久久久综合_超碰av人澡人澡人澡人澡人掠_国产黄大片在线观看画质优化_txt小说免费全本

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

Twitter是什么

發布時間:2021-12-09 09:07:42 來源:億速云 閱讀:161 作者:iii 欄目:編程語言

這篇文章主要講解了“Twitter是什么”,文中的講解內容簡單清晰,易于學習與理解,下面請大家跟著小編的思路慢慢深入,一起來研究和學習“Twitter是什么”吧!

Twitter 迅速占領了 Internet 市場。您肯定知道這個出色的社交網絡工具允許訂閱者提供關于他們自身以及當前正在執行的任務的簡要狀態更新。追隨者 將接收到他們的 “Twitter 提要” 的更新,這與博客將更新生成到博客閱讀者的提要中極為類似。

就其本身而言,Twitter 是對社交網絡的有趣討論,并且是用戶之間的新一代 “高度互聯”,它具備您能想到的所有優點和缺點。

由于 Twitter 很早就發布了其 API,因此大量 Twitter 客戶機應用程序涌入到 Internet 上。由于該 API 主要建立在直觀和易于理解的基礎上,因此許多開發人員都發現有必要構建一個自己的 Twitter 客戶機,這與學習 Web 技術的開發人員構建自己的博客服務器極為類似。

考慮到 Scala 的功能性(這看上去能很好地協同 Twitter 的 REST 式特性)以及非常出眾的 XML 處理特性,因此嘗試構建一個用于訪問 Twitter 的 Scala 客戶機庫應該是一個非常不錯的體驗。

何為 Twitter?

在詳細討論之前,我們先來看看 Twitter API。

簡單來說,Twitter 是一個 “微型博客” — 關于您自己的簡短個性化提要,不超過 140 個字符,任何 “追隨者” 都可以通過 Web 更新、RSS、文本消息等方式接收它們。(140 字符的限制完全來自文本消息,它是 Twitter 的主要來源渠道,并受到類似的限制)。

最具 REST 特征 是什么意思?

一些讀者會對我所使用的最具 REST 特征 短語感到好奇;這需要一些說明。“Twitter API 試圖符合 Representational State Transfer (REST) 的設計原則”。并且在很大程度上說它做到了。該思想的創造者 Roy Fielding 可能不同意 Twitter 使用這個術語,但實現來說,Twitter 的方法將適合大多數人的 REST 定義。我只希望避免關于 REST 定義的激烈爭論。因此,我使用了限定詞 “最”。

從實際的角度來說,Twitter 是一個最具 REST 特征 的 API,您可以使用一些種類的消息格式 — XML、ATOM、RSS 或 JSON — 來發送或從 Twitter 服務器接收消息。不同的 URL,與不同的消息和它們所需及可選的消息部分相結合,可以發起不同的 API 調用。例如,如果您希望接收 Twitter 上所有人的所有 “Tweets”(Twitter 更新)的完整列表(也稱作 “公共時間軸”),您需要準備一個 XML、ATOM、RSS 或 JSON 消息,將它發送給合適的 URL,并采用與 Twitter 網站(apiwiki.twitter.com)上相同的格式來使用結果:

------------------------------------------------------------

public_timeline

返回設定了自定義用戶圖標的

非保護用戶的 20 條最新狀態。不需要身份驗證。

注意,公共時間軸將緩存 60 秒鐘

因此頻繁請求它不再浪費資源。

URL: http://twitter.com/statuses/public_timeline.format

格式:xml、json、rss、atom

方法:GET

API 限制:不適用

返回:狀態元素列表

------------------------------------------------------------

從編程的角度來說,這意味著我們給 Twitter 服務器發送一個簡單的 GET HTTP 請求,并且我們將獲取一組封裝在 XML、RSS、ATOM 或 JSON 消息中的 “狀態” 消息。Twitter 站點將 “狀態” 消息定義為類似清單 1 所示的內容:

清單 1. 您好世界,您在哪里?

< feed xml:lang="en-US" xmlns="http://www.w3.org/2005/Atom">   < title>Twitter / tedneward< /title>   < id>tag:twitter.com,2007:Status< /id>   < link type="text/html" rel="alternate" href="http://twitter.com/tedneward"/>   < updated>2009-03-07T13:48:31+00:00< /updated>   < subtitle>Twitter updates from Ted Neward / tedneward.< /subtitle>   < entry>  < title>tedneward: @kdellison Happens to the best of us...< /title>  < content type="html">tedneward: @kdellison Happens to the best of us...< /content>  < id>tag:twitter.com,2007:http://twitter.com/tedneward/statuses/1292396349< /id>  < published>2009-03-07T11:07:18+00:00< /published>  < updated>2009-03-07T11:07:18+00:00< /updated>  < link type="text/html" rel="alternate"         href="http://twitter.com/tedneward/statuses/1292396349"/>  < link type="image/png" rel="image"         href="http://s3.amazonaws.com/twitter_production/profile_images/           55857457/javapolis_normal.png"/>  < author>    < name>Ted Neward< /name>    < uri>http://www.tedneward.com< /uri>  < /author>   < /entry> < /feed>

狀態消息中的大部分元素(如果不是全部的話)都很直觀,因此不再贅述。

由于我們可以采用三種基于 XML 的格式使用 Twitter 消息,以及 Scala 具備一些非常強大的 XML 特性,包括 XML 字面值和類似 XPath 的查詢語法 API,因此編寫可以發送和接收 Twitter 消息的 Scala 庫只需要一些基礎的 Scala 編碼工作。舉例來說,通過 Scala 使用清單 1 消息來提取狀態更新的標題或內容可以利用 Scala 的 XML 類型和 \ 及 \\ 方法,如 清單 2 所示:

清單 2. 您好 Ted,您在哪里?

< ![CDATA[  package com.tedneward.scitter.test  {    class ScitterTest    {      import org.junit._, Assert._            @Test def simpleAtomParse =      {        val atom =          < feed xml:lang="en-US" xmlns="http://www.w3.org/2005/Atom">           < title>Twitter / tedneward< /title>           < id>tag:twitter.com,2007:Status< /id>           < link type="text/html" rel="alternate" href="http://twitter.com/tedneward"/>           < updated>2009-03-07T13:48:31+00:00< /updated>           < subtitle>Twitter updates from Ted Neward / tedneward.< /subtitle>           < entry>             < title>tedneward: @kdellison Happens to the best of us...< /title>             < content type="html">tedneward: @kdellison                                   Happens to the best of us...< /content>             < id>tag:twitter.com,2007:                  http://twitter.com/tedneward/statuses/1292396349< /id>             < published>2009-03-07T11:07:18+00:00< /published>             < updated>2009-03-07T11:07:18+00:00< /updated>             < link type="text/html" rel="alternate"                   href="http://twitter.com/tedneward/statuses/1292396349"/>             < link type="image/png" rel="image"                   href="http://s3.amazonaws.com/twitter_production/profile_images/                          55857457/javapolis_normal.png"/>             < author>               < name>Ted Neward< /name>               < uri>http://www.tedneward.com< /uri>             < /author>           < /entry>         < /feed>             assertEquals(atom \\ "entry" \ "title",     "tedneward: @kdellison Happens to the best of us...")      }    }  }  ]]>

有關 Scala 的 XML 支持的更多詳細信息,請參閱 “Scala 和 XML”。

實際上,使用原始 XML 本身并不是一個有趣的練習。如果 Scala 的宗旨是讓我們的生活更加輕松,那么可以創建一個或一組專用于簡化 Scala 消息發送和接收任務的類。作為其中一個目標,應該能夠在 “普通” Java 程序中方便地使用庫(這意味著可以方便地從任何可理解普通 Java 語義的環境中來訪問它,比如說 Groovy 或 Clojure)。

API 設計

在深入了解 Scala/Twitter 庫的 API 設計之前(根據同事 ThoughtWorker Neal Ford 的建議,我將它稱作 “Scitter”),需要明確一些需求。

首先,Scitter 顯然會對網絡訪問有一些依賴 — 并且可擴展到 Twitter 服務器 — 這會使測試變得非常困難。

其次,我們需要解析(和測試)Twitter 發回的各種格式。

第三,我們希望隱藏 API 內部各種格式之間的差異,以便客戶機不需要擔心已記錄的 Twitter 消息格式,但是可以僅使用標準類。

最后,由于 Twitter 依賴 “通過身份驗證的用戶” 才能使用大量 API,因此 Scitter 庫需要適應 “驗證” 和 “未驗證” API 之間的差異,而不會讓事情變得過于復雜。

網絡訪問需要一些形式的 HTTP 通信,以便聯系 Twitter 服務器。雖然我們可以使用 Java 庫本身(特別是 URL 類及其同胞),但由于 Twitter API 需要大量請求和響應主體連接,因此可以更加輕松地使用不同的 HTTP API,特別是 Apache Commons HttpClient 庫。為了更便于測試客戶機 API,實際通信將隱藏在一些 API 內部的 Scitter 庫中,以便能夠更加輕松地切換到另一個 HTTP 庫(其必要性不太容易想到),并能模擬實際網絡通信以簡化測試(其作用很容易想到)。

結果,第一個測試是 Scala 化 HttpClient 調用,以確保基本通信模式就位;注意,由于 HttpClient 依賴另外兩個 Apache 庫(Commons Logging 和 Commons Codec),因此還需要在運行時提供這些庫;對于那些希望開發相似種類代碼的讀者,確保類路徑中包括所有三個庫。

由于最易于使用的 Twitter API 是測試 API

因此在請求格式中返回 “ok”,并附帶 200 OK HTTP 狀態碼。

我們將使用它作為 Scitter 測試中的保留條款。它位于 URL http://twitter.com/help/test.format(其中,“format” 為 “xml” 或 “json”;至于目前,我們將選擇使用 “xml”),并且僅有的支持 HTTP 方法是 GET。HttpClient 代碼簡明易懂,如清單 3 所示:

清單 3. Twitter PING!

package com.tedneward.scitter.test  {    class ExplorationTests    {      // ...          import org.apache.commons.httpclient._, methods._, params._, cookie._            @Test def callTwitterTest =      {        val testURL = "http://twitter.com/help/test.xml"               // HttpClient API 101        val client = new HttpClient()        val method = new GetMethod(testURL)         method.getParams().setParameter(HttpMethodParams.RETRY_HANDLER,           new DefaultHttpMethodRetryHandler(3, false))         client.executeMethod(method)                val statusLine = method.getStatusLine()                assertEquals(statusLine.getStatusCode(), 200)        assertEquals(statusLine.getReasonPhrase(), "OK")      }    }  }

此代碼中最重要的一部分是 HttpClient 樣板 — 感興趣的讀者應該查閱 HttpClient API 文檔了解詳細信息。假設連接到公共 Internet 的網絡可用(并且 Twitter 并未修改其公共 API),那么該測試應該能順利通過。

鑒于此,我們詳細分析 Scitter 客戶機的第一部分。這意味著我們需要解決一個設計問題:如何構建 Scitter 客戶機來處理經過驗證和未經過驗證的調用。目前,我將采用典型的 Scala 方式,假定驗證是 “按對象” 執行的,因此將需要驗證的調用放在類定義中,并在未驗證的調用放在對象定義中:

清單 4. Scitter.test

package com.tedneward.scitter  {    /**     * Object for consuming "non-specific" Twitter feeds, such as the public timeline.     * Use this to do non-authenticated requests of Twitter feeds.     */   object Scitter    {      import org.apache.commons.httpclient._, methods._, params._, cookie._       /**       * Ping the server to see if it's up and running.       *       * Twitter docs say:       * test       * Returns the string "ok" in the requested format with a 200 OK HTTP status code.       * URL: http://twitter.com/help/test.format       * Formats: xml, json       * Method(s): GET       */     def test : Boolean =      {        val client = new HttpClient()         val method = new GetMethod("http://twitter.com/help/test.xml")         method.getParams().setParameter(HttpMethodParams.RETRY_HANDLER,           new DefaultHttpMethodRetryHandler(3, false))         client.executeMethod(method)                val statusLine = method.getStatusLine()        statusLine.getStatusCode() == 200     }    }    /**     * Class for consuming "authenticated user" Twitter APIs. Each instance is     * thus "tied" to a particular authenticated user on Twitter, and will     * behave accordingly (according to the Twitter API documentation).     */   class Scitter(username : String, password : String)    {    }  }

目前,我們將網絡抽象放在一邊 — 稍后,當離線測試變得更加重要時再添加它。當我們更好地理解如何使用 HttpClient 類時,這還將幫助避免 “過度抽象” 網絡通信。

由于已經明確區分了驗證和未驗證 Twitter 客戶機,因此我們將快速創建一個經過驗證的方法。看上去 Twitter 提供了一個可驗證用戶登錄憑證的 API。再次,HttpClient 代碼將類似于之前的代碼,除了將用戶名和密碼傳遞到 Twitter API 中之外。

這引出了 Twitter 如何驗證用戶的概念。快速查看 Twitter API 頁面后,可以發現 Twitter 使用的是一種 Stock HTTP 驗證方法,這與任何經過驗證的資源在 HTTP 中的方法相同。這意味著 HttpClient 代碼必須提供用戶名和密碼作為 HTTP 請求的一部分,而不是作為 POST 的主體,如清單 5 所示:

清單 5. 您好 Twitter,是我!

package com.tedneward.scitter.test  {    class ExplorationTests    {      def testUser = "TwitterUser"  def testPassword = "TwitterPassword"         @Test def verifyCreds =      {        val client = new HttpClient()         val verifyCredsURL = "http://twitter.com/account/verify_credentials.xml"       val method = new GetMethod(verifyCredsURL)         method.getParams().setParameter(HttpMethodParams.RETRY_HANDLER,           new DefaultHttpMethodRetryHandler(3, false))         client.getParams().setAuthenticationPreemptive(true)        val defaultcreds = new UsernamePasswordCredentials(testUser, testPassword)        client.getState().setCredentials(new AuthScope("twitter.com", 80,                                                       AuthScope.ANY_REALM), defaultcreds)                client.executeMethod(method)                val statusLine = method.getStatusLine()                assertEquals(200, statusLine.getStatusCode())        assertEquals("OK", statusLine.getReasonPhrase())      }    }  }

注意,要讓此測試順利通信,用戶名和密碼字段將需要輸入 Twitter 能接收的內容 — 我在開發時使用了自己的 Twitter 用戶名和密碼,但顯然您需要使用自己設定的用戶名和密碼。注冊新的 Twitter 帳戶相當簡單,因此我假定您已經擁有一個帳戶,或者知道如何注冊(很好。我會等待完成此任務)。

完成后,使用用戶名和密碼構造函數參數將它映射到 Scitter 類非常簡單,如清單 6 所示:

清單 6. Scitter.verifyCredentials

package com.tedneward.scitter  {    import org.apache.commons.httpclient._, auth._, methods._, params._     // ...     /**     * Class for consuming "authenticated user" Twitter APIs. Each instance is     * thus "tied" to a particular authenticated user on Twitter, and will     * behave accordingly (according to the Twitter API documentation).     */   class Scitter(username : String, password : String)    {      /**       * Verify the user credentials against Twitter.       *       * Twitter docs say:       * verify_credentials       * Returns an HTTP 200 OK response code and a representation of the       * requesting user if authentication was successful; returns a 401 status       * code and an error message if not.  Use this method to test if supplied       * user credentials are valid.       * URL: http://twitter.com/account/verify_credentials.format       * Formats: xml, json       * Method(s): GET       */     def verifyCredentials : Boolean =      {        val client = new HttpClient()         val method = new GetMethod("http://twitter.com/help/test.xml")         method.getParams().setParameter(HttpMethodParams.RETRY_HANDLER,           new DefaultHttpMethodRetryHandler(3, false))                  client.getParams().setAuthenticationPreemptive(true)        val creds = new UsernamePasswordCredentials(username, password)        client.getState().setCredentials(          new AuthScope("twitter.com", 80, AuthScope.ANY_REALM), creds)         client.executeMethod(method)                val statusLine = method.getStatusLine()        statusLine.getStatusCode() == 200     }    }  }

清單 7 中相應的 Scitter 類測試也相當簡單:

清單 7. 測試 Scitter.verifyCredentials

package com.tedneward.scitter.test  {    class ScitterTests    {      import org.junit._, Assert._      import com.tedneward.scitter._       def testUser = "TwitterUsername"       def testPassword = "TwitterPassword"             // ...         @Test def verifyCreds =      {        val scitter = new Scitter(testUser, testPassword)        val result = scitter.verifyCredentials        assertTrue(result)      }    }  }

不算太糟。庫的基本結構已經成形,但顯然還有很長的路要走,特別是因為目前實際上未執行任何特定于 Scala 的任務 — 在面向對象設計中,庫的構建并不像練習那樣簡單。因此,我們開始使用一些 XML,并通過更加合理的格式將它返回。

從 XML 到對象

現在可以添加的最簡單的 API 是 public_timeline,它收集 Twitter 從所有用戶處接收到的最新的 n 更新,并返回它們以便于進行使用。與之前討論的另外兩個 API 不同,public_timeline API 返回一個響應主體(而不是僅依賴于狀態碼),因此我們需要分解生成的 XML/RSS/ATOM/,然后將它們返回給 Scitter 客戶機。

現在,我們編寫一個探索測試,它將訪問公共提要并將結果轉儲到 stdout 以便進行分析,如清單 8 所示:

清單 8. 大家都在忙什么?

package com.tedneward.scitter.test  {    class ExplorationTests    {      // ...          @Test def callTwitterPublicTimeline =      {        val publicFeedURL = "http://twitter.com/statuses/public_timeline.xml"               // HttpClient API 101        val client = new HttpClient()        val method = new GetMethod(publicFeedURL)        method.getParams().setParameter(HttpMethodParams.RETRY_HANDLER,           new DefaultHttpMethodRetryHandler(3, false))                client.executeMethod(method)                val statusLine = method.getStatusLine()        assertEquals(statusLine.getStatusCode(), 200)        assertEquals(statusLine.getReasonPhrase(), "OK")                val responseBody = method.getResponseBodyAsString()        System.out.println("callTwitterPublicTimeline got... ")        System.out.println(responseBody)      }    }  }

運行后,結果每次都會有所不同,因為公共 Twitter 服務器上有許多用戶,但通常應與清單 9 的 JUnit 文本文件轉儲類似:

清單 9. 我們的 Tweets 結果

< statuses type="array">     < status>       < created_at>Tue Mar 10 03:14:54 +0000 2009< /created_at>       < id>1303777336< /id>       < text>She really is. http://tinyurl.com/d65hmj< /text>       < source>< a href="http://iconfactory.com/software/twitterrific">twitterrific< /a>         < /source>       < truncated>false< /truncated>       < in_reply_to_status_id>< /in_reply_to_status_id>       < in_reply_to_user_id>< /in_reply_to_user_id>       < favorited>false< /favorited>       < user>           < id>18729101< /id>           < name>Brittanie< /name>           < screen_name>brittaniemarie< /screen_name>           < description>I'm a bright character. I suppose.< /description>           < location>Atlanta or Philly.< /location>           < profile_image_url>http://s3.amazonaws.com/twitter_production/profile_images/                               81636505/goodish_normal.jpg< /profile_image_url>           < url>http://writeitdowntakeapicture.blogspot.com< /url>           < protected>false< /protected>           < followers_count>61< /followers_count>       < /user>     < /status>     < status>       < created_at>Tue Mar 10 03:14:57 +0000 2009< /created_at>       < id>1303777334< /id>       < text>Number 2 of my four life principles.  "Life is fun and rewarding"< /text>       < source>web< /source>       < truncated>false< /truncated>       < in_reply_to_status_id>< /in_reply_to_status_id>       < in_reply_to_user_id>< /in_reply_to_user_id>       < favorited>false< /favorited>       < user>           < id>21465465< /id>           < name>Dale Greenwood< /name>           < screen_name>Greeendale< /screen_name>           < description>Vegetarian. Eat and use only organics.                          Love helping people become prosperous< /description>           < location>Melbourne Australia< /location>           < profile_image_url>http://s3.amazonaws.com/twitter_production/profile_images/                               90659576/Dock_normal.jpg< /profile_image_url>           < url>http://www.4abundance.mionegroup.com< /url>           < protected>false< /protected>           < followers_count>15< /followers_count>        < /user>      < /status>        (A lot more have been snipped)  < /statuses>

通過查看結果和 Twitter 文檔可以看出,調用的結果是一組具備一致消息結構的簡單 “狀態” 消息。使用 Scala 的 XML 支持分離結果相當簡單,但我們會在基本測試通過后立即簡化它們,如清單 10 所示:

清單 10. 大家都在忙什么?

package com.tedneward.scitter.test  {    class ExplorationTests    {      // ...          @Test def simplePublicFeedPullAndParse =      {        val publicFeedURL = "http://twitter.com/statuses/public_timeline.xml"               // HttpClient API 101        val client = new HttpClient()        val method = new GetMethod(publicFeedURL)        method.getParams().setParameter(HttpMethodParams.RETRY_HANDLER,           new DefaultHttpMethodRetryHandler(3, false))        val statusCode = client.executeMethod(method)        val responseBody = new String(method.getResponseBody())                val responseXML = scala.xml.XML.loadString(responseBody)        val statuses = responseXML \\ "status"        for (n < - statuses.elements)        {          n match          {            case < status>{ contents @ _*}< /status> =>            {              System.out.println("Status: ")              contents.foreach((c) =>                c match                {                  case < text>{ t @ _*}< /text> =>                    System.out.println("\tText: " + t.text.trim)                  case < user>{ contents2 @ _* }< /user> =>                  {                    contents2.foreach((c2) =>                      c2 match                      {                        case < screen_name>{ u }< /screen_name> =>                          System.out.println("\tUser: " + u.text.trim)                        case _ =>        ()                      }                    )                  }                  case _ =>        ()                }              )            }            case _ =>              () // or, if you prefer, System.out.println("Unrecognized element!")          }        }      }    }  }

隨著示例代碼模式的變化,這并不值得推薦 — 這有點類似于 DOM,依次導航到各個子元素,提取文本,然后導航到另一個節點。我可以僅執行兩個 XPath 樣式的查詢,如清單 11 所示:

清單 11. 替代解析方法

for (n < - statuses.elements)  {       val text = (n \\ "text").text         val screenName = (n \\ "user" \ "screen_name").text  }

這顯然更加簡短,但它帶來了兩個基本問題:

我們可以強制 Scala 的 XML 庫針對每個元素或子元素遍歷一次圖,其速度會隨時間減慢。

我們仍然需要直接處理 XML 消息的結構。這是兩個問題中最為重要的。

也就是說,這種方式不具備可伸縮性 — 假設我們最終對 Twitter 狀態消息中的每個元素都感興趣,我們將需要分別從各狀態中提取各個元素。

這又造成了另一個與各格式本身相關的問題。記住,Twitter 可以使用四種不同的格式,并且我們不希望 Scitter 客戶機需要了解它們之間的任何差異,因此 Scitter 需要一個能返回給客戶機的中間結構,以便未來使用,如清單 12 所示:

清單 12. Breaker,您的狀態是什么?

abstract class Status  {    val createdAt : String    val id : Long    val text : String    val source : String    val truncated : Boolean    val inReplyToStatusId : Option[Long]    val inReplyToUserId : Option[Long]    val favorited : Boolean    val user : User  }

這與 User 方式相類似,考慮到簡潔性,我就不再重復了。注意,User 子元素有一個有趣的問題 — 雖然存在 Twitter 用戶類型,但其中內嵌了一個可選的 “最新狀態”。狀態消息還內嵌了一個用戶。對于這種情況,為了幫助避免一些潛在的遞歸問題,我選擇創建一個嵌入在 Status 內部的 User 類型,以反映所出現的 User 數據;反之亦然,Status 也可以嵌入在 User 中,這樣可以明確避免該問題。(至少,在沒發現問題之前,這種方法是有效的)。

現在,創建了表示 Twitter 消息的對象類型之后,我們可以遵循 XML 反序列化的公共 Scala 模式:創建相應的對象定義,其中包含一個 fromXml 方法,用于將 XML 節點分離到對象實例中,如清單 13 所示:

清單 13. 分解 XML

/**   * Object wrapper for transforming (format) into Status instances.   */ object Status  {    def fromXml(node : scala.xml.Node) : Status =    {      new Status {        val createdAt = (node \ "created_at").text        val id = (node \ "id").text.toLong        val text = (node \ "text").text        val source = (node \ "source").text        val truncated = (node \ "truncated").text.toBoolean        val inReplyToStatusId =          if ((node \ "in_reply_to_status_id").text != "")            Some((node \"in_reply_to_status_id").text.toLong)          else           None        val inReplyToUserId =           if ((node \ "in_reply_to_user_id").text != "")            Some((node \"in_reply_to_user_id").text.toLong)          else           None        val favorited = (node \ "favorited").text.toBoolean        val user = User.fromXml((node \ "user")(0))      }    }  }

其中最強大的一處是,它可以針對 Twitter 支持的其他任何格式進行擴展 — fromXml 方法可以在分解節點之前檢查它是否保存了 XML、RSS 或 Atom 類型的內容,或者 Status 可以包含 fromXml、fromRss、fromAtom 和 fromJson 方法。實際上,后一種方法是我的優先選擇,因為它會平等對待基于 XML 的格式和 JSON(基于文本)格式。

好奇和細心的讀者會注意到在 Status 及其內嵌 User 的 fromXml 方法中,我使用的是 XPath 樣式的分解方法,而不是之前建議的遍歷內嵌元素的方法。現在,XPath 樣式的方法看上去更易于閱讀,但幸運的是,我后來改變了注意,良好的封裝仍然是我的朋友 — 我可以在隨后修改它,Scitter 外部的任何人都不會知道。

注意 Status 內部的兩個成員如何使用 Option[T] 類型;這是因為這些元素通常排除在 Status 消息外部,并且雖然元素本身會出現,但它們顯示為空(類似于 < in_reply_to_user_id>< /in_reply_to_user_id>)。這正是 Option[T] 的作用所在。當元素為空時,它們將使用 “None” 值。(這表示考慮到基于 Java 的兼容性,訪問它們會更加困難,但惟一可行方法是對最終生成的 Option 實例調用 get(),這不太復雜并且能很好地解決 “非 null 即 0” 問題)。

現在已經可以輕而易舉地使用公共時間軸:

清單 14. 分解公共時間軸

@Test def simplePublicFeedPullAndDeserialize =  {    val publicFeedURL = "http://twitter.com/statuses/public_timeline.xml"       // HttpClient API 101    val client = new HttpClient()    val method = new GetMethod(publicFeedURL)    method.getParams().setParameter(HttpMethodParams.RETRY_HANDLER,       new DefaultHttpMethodRetryHandler(3, false))    val statusCode = client.executeMethod(method)    val responseBody = new String(method.getResponseBody())        val responseXML = scala.xml.XML.loadString(responseBody)    val statuses = responseXML \\ "status"    for (n < - statuses.elements)    {      val s = Status.fromXml(n)      System.out.println("\t'@" + s.user.screenName + "' wrote " + s.text)    }  }

顯然,這看上去更加簡潔,并且易于使用。

將所有這些結合到 Scitter 單一實例中相當簡單,僅涉及執行查詢、解析各個 Status 元素以及將它們添加到 List[Status] 實例中,如清單 15 所示:

清單 15. Scitter.publicTimeline

package com.tedneward.scitter  {    import org.apache.commons.httpclient._, auth._, methods._, params._    import scala.xml._     object Scitter    {      // ...          /**       * Query the public timeline for the most recent statuses.       *       * Twitter docs say:       * public_timeline       * Returns the 20 most recent statuses from non-protected users who have set       * a custom user icon.  Does not require authentication.  Note that the       * public timeline is cached for 60 seconds so requesting it more often than       * that is a waste of resources.       * URL: http://twitter.com/statuses/public_timeline.format       * Formats: xml, json, rss, atom       * Method(s): GET       * API limit: Not applicable       * Returns: list of status elements            */     def publicTimeline : List[Status] =      {        import scala.collection.mutable.ListBuffer              val client = new HttpClient()         val method =            new GetMethod("http://twitter.com/statuses/public_timeline.xml")         method.getParams().setParameter(HttpMethodParams.RETRY_HANDLER,           new DefaultHttpMethodRetryHandler(3, false))         client.executeMethod(method)                val statusLine = method.getStatusLine()        if (statusLine.getStatusCode() == 200)        {          val responseXML =            XML.loadString(method.getResponseBodyAsString())           val statusListBuffer = new ListBuffer[Status]           for (n < - (responseXML \\ "status").elements)            statusListBuffer += (Status.fromXml(n))                    statusListBuffer.toList        }        else       {          Nil        }      }    }  }

在實現功能全面的 Twiter 客戶機之前,我們顯然還有很長的路要走。但到目前為止,我們已經實現基本的行為。

感謝各位的閱讀,以上就是“Twitter是什么”的內容了,經過本文的學習后,相信大家對Twitter是什么這一問題有了更深刻的體會,具體使用情況還需要大家實踐驗證。這里是億速云,小編將為大家推送更多相關知識點的文章,歡迎關注!

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

五常市| 崇阳县| 湖南省| 屏东县| 宕昌县| 沅陵县| 丹东市| 礼泉县| 龙山县| 宁陕县| 盱眙县| 上林县| 南投市| 龙口市| 读书| 南京市| 富顺县| 呼图壁县| 肥西县| 广昌县| 炉霍县| 祁东县| 昌邑市| 娱乐| 且末县| 卢龙县| 彭水| 鲁甸县| 永顺县| 吴江市| 湟源县| 大埔县| 湖州市| 沁源县| 九龙坡区| 玉山县| 武山县| 建瓯市| 墨玉县| 黎川县| 张家界市|