首页 | 源码下载 | 网站模板 | 网页特效 | 广告代码 | 网页素材 | 字体下载 | 书库 | 站长工具
会员投稿 投稿指南 RSS订阅
当前位置:主页>网络编程>java教程>资讯:面向Java开发人员的Scala指南: 增强Scitter库

面向Java开发人员的Scala指南: 增强Scitter库

www.jz123.cn  2009-09-03   来源:   IT专家网    责任编辑(袁袁)    我要投递新闻

 抽象地谈论 Scala 的确有趣,然而一旦将其付诸实践,就会发现将它作为 “玩具” 与在工作中使用它的区别。Scala 狂热者 Ted Neward 撰写了一篇 对 Scitter 的介绍,Scitter 是一个用于访问 Twitter 的 Scala 库,本文是其后续篇,在本文中,Ted Neward 为这个客户机库提供了一组更有趣也更有用的特性。

  欢迎回来,Scala 迷们。上个月,我们谈到了 Twitter,这个微博客站点目前正引起社会性网络的极大兴趣,我们还谈到它的基于 XML-/REST 的 API 如何使它成为开发人员进行研究和探索的一个有趣平台。为此,我们首先充实了 “Scitter” 的基本结构,Scitter 是用于访问 Twitter 的一个 Scala 库。

  我们对于 Scitter 有几个目标:

  ● 简化 Twitter 访问,比过去打开 HTTP 连接然后 “手动” 执行操作更容易。

  ● 可以从 Java 客户机轻松访问它。

  ● 轻松模拟以便进行测试。

  在这一期,我们不必完成整个 Twitter API,但是我们将完成一些核心部分,目的是让这个库达到公共源代码控制库的程度,便于其他人来完成这项工作。

  到目前为止:Scitter 0.1

  首先我们简单回顾一下到目前为止我们所处的阶段:

  清单 1. Scitter v0.1

  


package com.tedneward.scitter
  {
  import org.apache.commons.httpclient._, auth._, methods._, params._
  import scala.xml._
  /**
  * Status message type. This will typically be the most common message type
  * sent back from Twitter (usually in some kind of collection form). Note
  * that all optional elements in the Status type are represented by the
  * Scala Option[T] type, since that's what it's there for.
  */
  abstract class Status
  {
  /**
  * Nested User type. This could be combined with the top-level User type,
  * if we decide later that it's OK for this to have a boatload of optional
  * elements, including the most-recently-posted status update (which is a
  * tad circular).
  */
  abstract class User
  {
  val id : Long
  val name : String
  val screenName : String
  val description : String
  val location : String
  val profileImageUrl : String
  val url : String
  val protectedUpdates : Boolean
  val followersCount : Int
  }
  /**
  * Object wrapper for transforming (format) into User instances.
  */
  object User
  {
  /*
  def fromAtom(node : Node) : Status =
  {
  }
  */
  /*
  def fromRss(node : Node) : Status =
  {
  }
  */
  def fromXml(node : Node) : User =
  {
  new User {
  val id = (node  "id").text.toLong
  val name = (node  "name").text
  val screenName = (node  "screen_name").text
  val description = (node  "description").text
  val location = (node  "location").text
  val profileImageUrl = (node  "profile_image_url").text
  val url = (node  "url").text
  val protectedUpdates = (node  "protected").text.toBoolean
  val followersCount = (node  "followers_count").text.toInt
  }
  }
  }
  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
  }
  /**
  * Object wrapper for transforming (format) into Status instances.
  */
  object Status
  {
  /*
  def fromAtom(node : Node) : Status =
  {
  }
  */
  /*
  def fromRss(node : Node) : Status =
  {
  }
  */
  def fromXml(node : 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))
  }
  }
  }
  /**
  * Object for consuming "non-specific" Twitter feeds, such as the public timeline.
  * Use this to do non-authenticated requests of Twitter feeds.
  */
  object Scitter
  {
  /**
  * 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
  }
  /**
  * 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
  }
  }
  }
  /**
  * 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
  }
  }
  }

  代码有点长,但是很容易分为几个基本部分:

  ● case 类 User 和 Status,表示 Twitter 在对 API 调用的响应中发回给客户机的基本类型,包括用于构造或提取 XML 的一些方法。

  ● 一个 Scitter 独立对象,处理那些不需要对用户进行验证的操作。

  ● 一个 Scitter 实例(用 username 和 password 参数化),用于那些需要对用户执行验证的操作。

  到目前为止,对于这两种 Scitter 类型,我们只谈到了测试、verifyCredentials 和 public_timeline API.虽然这些有助于确定 HTTP 访问的基础(使用 Apache HttpClient 库)可以工作,并且我们将 XML 响应转换成 Status 对象的基本方式也是可行的,但是现在我们甚至不能进行基本的 “我的朋友在说什么” 的公共时间线查询,也没有采取过基本的措施来防止代码库中出现 “重复” 问题,更不用说寻找一些方法来模拟用于测试的网络访问代码。

上一篇:Java Math 类中的新功能(一): 实数 下一篇:通过Java或Jsp向数据库存取二进制图片

评论总数:0 [ 查看全部 ] 网友评论


关于我们隐私版权广告服务友情链接联系我们网站地图