领先一步
VMware 提供培训和认证,助您加速进步。
了解更多如今,网民越来越多地使用互联网通过社交网站与朋友、家人和同事建立联系。曾经通过电子邮件进行的对话,现在正在某人 Facebook 墙上的短消息或 Twitter 上的简短推文中进行。曾经通过握手建立的联系,现在正在使用 LinkedIn 创建。当需要面对面会议时,可以使用 TripIt 分享旅行详情。
就像人们利用这些社交网站互相交流一样,企业也在寻找方法将自己融入社交图谱,以便能以更个性化的方式与客户联系,并使他们的网站成为客户社交体验的延伸。
本周,我们很高兴发布了 Spring Social 的第一个里程碑版本,它是 Spring 的一个新扩展,旨在提供一个平台,用于构建具备社交功能的 Spring 应用。我想借此机会向您介绍 Spring Social,并让您初步了解它的功能。
表面上看,开发与各种社交网络交互的应用可能看起来很简单。由于大多数社交网络都提供 REST API,Spring 的 RestTemplate
似乎就是您所需要的全部。但您很快就会发现,这些社交 REST API 受 OAuth 保护,并且使用 OAuth 凭据签署通过 RestTemplate
发送的请求并非易事。
OAuth 是一种开放协议,它使用户能够将托管在一个或多个服务提供商上的数据共享给另一个应用。通过访问这些数据,应用可以聚合、展示和处理这些信息,从而提供超越服务提供商自身最初设想或想象的额外价值。
几乎所有主要的服務提供商都支持 OAuth,包括 Twitter、Facebook、LinkedIn、TripIt 和 Foursquare,以及 Google 和 Yahoo APIs。因此,OAuth 对于开发具备社交功能的应用至关重要。
在受 OAuth 保护的交互开始时,有一个来回的对话,通常被称为“OAuth Dance”(OAuth 舞蹈)。在典型的 OAuth Dance 中,涉及三方
此舞蹈的关键步骤如下
在步骤 3 中收到的访问令牌是必须附带任何请求发送给服务提供商 REST API 的“代客密钥”(valet key)。在 OAuth 1 中,这意味着访问令牌以及请求 URL、参数和一些其他信息被收集到一个基本字符串中,加密后作为 Authorization
头部发送到请求中。构建此头部并将其附加到请求是一项复杂的任务。这就是使用 RestTemplate
访问受 OAuth 保护的资源困难的原因。如果操作不当,服务提供商将对您尝试访问的任何资源响应 HTTP 401,并且调试加密的 Authorization
头部非常棘手。
Spring Social 的一个关键组成部分是其社交模板集合。这些模板(内部利用了 RestTemplate
)暴露了它们所建模的服务提供商的操作,为您处理添加 OAuth Authorization
头部的复杂细节。
Spring Social 1.0.0.M1 包含 4 个社交模板可供选择
TwitterTemplate
FacebookTemplate
LinkedInTemplate
TripItTemplate
要使用这些模板中的任何一个,只需创建其一个实例,通过构造函数参数提供 OAuth 连接详细信息。例如,创建 TwitterTemplate
的实例
TwitterTemplate twitter = new TwitterTemplate(apiKey, apiSecret, accessToken, accessTokenSecret);
TwitterTemplate
构造函数的四个参数都是 String 类型的值。当您在 Twitter 上注册应用时会获得 API key 和 API secret(参见 http://dev.twitter.com/apps/new)。access token 和 access token secret 是在与 Twitter 进行 OAuth Dance 结束时,按每个用户授权给您的应用。在此,我假设您已经获得了这四个值;稍后我们将回到如何管理 API key 和 token。
创建其他社交模板的实例差别不大。LinkedInTemplate
和 TripItTemplate
各自的构造函数与上面显示的 TwitterTemplate
构造函数具有相同的参数列表。由于 Facebook 的 API 安全基于 OAuth 2,FacebookTemplate
的构造函数略微简单,只需要 access token 的值
FacebookTemplate facebook = new FacebookTemplate(accessToken);
一旦您有了其中一个社交模板的实例,您可以用它做什么呢?如果您使用的是 TwitterTemplate
,也许您想知道认证用户的 Twitter 屏幕名
String screenName = twitter.getProfileId();
或者,对于更复杂一些的操作,您或许可以代表用户发送一条推文
twitter.updateStatus("Hey, I'm tweeting with #Spring Social!");
类似地,手持 FacebookTemplate
,您可以发帖到用户的墙上
facebook.updateStatus("Spring Social can also post to Facebook!");
如果您想查看用户的即将到来的旅行行程,TripItTemplate
的 getTrips()
方法可以满足您的需求
List trips = tripIt.getTrips();
for(Trip trip : trips) {
System.out.println("I'm traveling to " + trip.getPrimaryLocation() +
" on " + trip.getStartDate());
}
这只是您可以使用 Spring Social 模板完成的一些事情的示例。请查阅 API 文档以了解可用的其他操作。
当我在上面创建 TwitterTemplate
实例时,我跳过了 API key/secret 和 access token 的来源。最初,access token 是在用户授权应用访问服务提供商托管的数据后收到的。但您可能不希望每次用户使用您的应用时都强制他们进行授权,因此您需要一种方法来长期存储 access token,以便在未来的会话中重复使用。
在其第一个里程碑版本中,Spring Social 不提供 OAuth token 管理策略,由应用自行获取和管理 OAuth 详细信息。这是我们计划在 1.0 里程碑版本 2 中解决的问题。然而,在此期间,我们可以参考 Greenhouse 来了解这可能如何实现。
在 Greenhouse 中,关于服务提供商的所有信息都存储在关系数据库中的一个 ServiceProvider
表中,其模式如下
如您所见,ServiceProvider
表除其他信息外,还包括提供商的 API key 和 secret。要访问单个服务提供商记录,Greenhouse 使用 JdbcServiceProviderFactory
,它是 ServiceProvider
接口的一个实现
package com.springsource.greenhouse.connect;
public interface ServiceProviderFactory {
ServiceProvider getServiceProvider(String name);
<S> ServiceProvider<S> getServiceProvider(String name, Class<S> serviceType);
}
要从数据库中检索 Twitter 服务提供商,Greenhouse 只需调用 getServiceProvider()
方法,将“twitter”(提供商名称)作为参数传入。对于 Twitter,这最终会返回 TwitterServiceProvider
的一个实例,它是 ServiceProvider
接口的一个实现。
ServiceProvider 有几个方法,但其中两个方法在 token 管理方面很有趣。第一个是 connect()
,Greenhouse 用它来创建其用户与他们在服务提供商上的社交身份之间的连接
void connect(Long accountId, AuthorizedRequestToken requestToken);
在调用 connect()
方法时,Greenhouse 已经完成了足够的 OAuth dance 流程,手头拥有了一个已授权的请求 token。将这些以及用户帐户 ID 一同传递,将在 AccountConnection
表中创建一个连接。AccountConnection
表的模式如下
建立连接后,您可以使用 ServiceProvider
的 getServiceOperations()
方法来获取 TwitterOperations
(TwitterTemplate
基于的接口)的一个实例
TwitterOperations twitter = twitterProvider.getServiceOperations(accountId);
在 getServiceOperations()
内部,ServiceProvider
实现会检索 access token,并将其与其自身的 API key 和 secret 一起使用来构建一个 TwitterTemplate,从而使应用无需直接处理 access token。
在 Greenhouse 中,TwitterOperations
实例是一个请求范围的 bean,通过 ServiceProvidersApiConfiguration
中的工厂方法使用 Spring JavaConfig 创建,如下所示
@Bean
@Scope(value="request", proxyMode=ScopedProxyMode.INTERFACES)
public TwitterOperations twitter(ServiceProvider<TwitterOperations> twitterProvider, @Value("#{request.getAttribute('account')}") Account account) {
return twitterProvider.getServiceOperations(accountId(account));
}
作为 Spring bean,TwitterOperations
可以注入到任何需要与 Twitter 交换数据的其他 Spring bean 中。例如,在 Greenhouse 中,EventsController
是处理所有面向事件请求的 Spring MVC 控制器。它使用 TwitterOperations
代表用户发布关于事件的推文。它是通过其构造函数注入 TwitterOperations
bean 的
@Inject
public EventsController(EventRepository eventRepository, TwitterOperations twitterApi) {
this.eventRepository = eventRepository;
this.twitterApi = twitterApi;
}
正如我提到的,我们计划在里程碑版本 2 中将 ServiceProvider
功能从 Greenhouse 迁移到 Spring Social。显然,目前的实现支持关系型数据库存储 OAuth 详细信息,但我们渴望听取您关于在其他类型的存储中维护 OAuth 信息的其他实现的建议。
虽然您可以在 http://greenhouse.springsource.org 查看正在运行的 Greenhouse 应用,但在探索 Spring Social 时,您可能希望 checkout Greenhouse 源代码并亲自尝试一下。为此,请按照以下步骤操作
git clone git://git.springsource.org/greenhouse/greenhouse.git
需要执行步骤 4,因为 Greenhouse 使用了 Spring 3.1 的新环境 bean 特性,该特性使得只为特定 profiles 创建 bean 成为可能。设置该属性表示应用应以“embedded” profile 运行。
Spring Social 1.0 M1 是将社交网络功能引入 Spring 的激动人心的探索的第一步。我鼓励您下载 Spring Social,查看代码,并通过问题跟踪系统、Spring Social 论坛或Greenhouse 邮件列表提供反馈。