领先一步
VMware 提供培训和认证,以加速您的进步。
了解更多这篇文章是由社区成员Tadayasu Tsuyukubo (@ttddyy)撰写的客座文章,他是 Spring Social Slideshare 项目的创建者。感谢 Tadaya!我希望看到更多这样的客座文章,所以——像往常一样——随时联系我!——Josh
Spring Social Evernote 是 Spring Social 生态系统中的一个社区模块。它是一个针对 Evernote 的服务提供商实现。它允许开发人员使用惯用的 Spring 习惯用法与 Evernote Java SDK 进行交互。
Evernote 采用了一种独特的方法向开发人员提供其 API。他们基于 Thrift 序列化格式 创建了 特定语言的 SDK。Evernote 的 CTO Dave Engberg 在 这篇博客文章中解释了选择 Thrift 的原因。
Java SDK 包含 Thrift 生成的域类(例如Notebook
、Note
、User
等)和端点访问客户端(例如UserStoreClient
、NoteStoreClient
等)。即使~StoreClient
类很好地封装了身份验证和 Thrift 端点通信协议,它们仍然有一些限制。
例如,各种~StoreClient
类型中进行通信的所有 Thrift 方法都会抛出**受检**异常。此外,~StoreClient
类没有与其操作相对应的接口,这使得单元测试(稍微)有些困难。Spring Social Evernote 填补了这些空白,同时提供了一个熟悉的 Spring Social 编程模型。
Spring Social Evernote 提供了一个熟悉的基于 Spring 和 Java 的编程模型,该模型使用接口、非受检异常和针对 Thrift 基于域对象的空安全Collection
。它还提供了一个 Evernote OAuth API 的服务提供商实现。
Evernote
接口及其实现EvernoteTemplate
是 API 的核心类型。Evernote
接口返回与 SDK 的~StoreClient
类相对应的~StoreOperations
(例如NoteStoreOperations
或UserStoreOperations
)接口。这些接口上的方法抛出**非受检**EvernoteException
,而不是受检EDAM*Exception
。这些实现还对 Thrift 生成的域类型中的集合具有更智能的空值处理。
Evernote evernote = new EvernoteTemplate(
EvernoteService.SANDBOX, "your-custom-access-token");
// interface based programming
NoteStoreOperations noteStore = evernote.noteStoreOperations();
// no checked exception is thrown
Notebook notebook = noteStore.getDefaultNotebook();
// no NPE when there are no shared notebooks
for (SharedNotebook sharedNotebook : notebook.getSharedNotebooks()) {
...
}
~StoreClientOperations
接口类对应于~StoreClient
实现类(例如,NoteStoreClientOperations
对应于com.evernote.clients.NoteStoreClient
)。
// NoteStoreOperations is interface encapsulating NoteStoreClient
NoteStoreOperations noteStore = evernote.noteStoreClientOperations();
Notebook notebook = noteStore.getNotebook("...");
EDAM 异常(例如com.evernote.edam.error.EDAMUserException
)和 Thrift 异常(例如com.evernote.Thrift.TException
)会被捕获并重新抛出为类型为EvernoteException
的*运行时*异常。
// with UserStoreOperations, no explicit exception handling is required
User user = evernote.userStoreOperations().getUser();
// or explicitly you can get exception info
try {
User user = userStoreClient.getUser();
} catch(EvernoteException e) {
if (e.isEDAMUserException()) {
EDAMErrorCode errorCode = e.getEDAMErrorCode();
EDAMUserException originalException = e.getCause();
....
}
}
在 Thrift 中,空集合不会被序列化,但是这种约定会导致在使用 API 时出现一些意外的NullPointerException
。Spring Social Evernote 实现使用空集合来清理这些值。
Note note = evernote.noteStoreOperations().getNote(...)
// it is safe to loop without null check
for(Resource resource: note.getResources()) {
...
}
或者(在 Java 8 中)
evernote.noteStoreOperations()
.getNote()
.getResources()
.forEach ( r -> System.out.println( r.toString() ));
Spring Social Evernote 会检查类型的脏数据并还原其空值,前提是集合在序列化之前为空。
有关此特定支持的更多信息,请查看nullsafe-Thrift——一个概念验证项目。
注册ConnectionFactory
要将 Evernote 环境(sandbox
、prod
、yinxiang
)注册到 Spring Social 服务提供商连接框架中,您可以使用特定于环境的ConnectionFactory
类,例如EvernoteSandboxConnectionFactory
、EvernoteProductionConnectionFactory
或EvernoteYinXiangConnectionFactory
。或者,您可以在构造函数中将EvernoteService
枚举传递给EvernoteConnectionFactory
。
ConnectionFactoryRegistry registry = new ConnectionFactoryRegistry();
// sandbox connection
registry.addConnectionFactory(new EvernoteSandboxConnectionFactory("consumerKey", "consumerSecret"));
// production connection
registry.addConnectionFactory(new EvernoteProductionConnectionFactory("consumerKey", "consumerSecret"));
// or by EvernoteService enum
registry.addConnectionFactory(new EvernoteConnectionFactory("consumerKey", "consumerSecret", EvernoteService.SANDBOX));
执行基于 Evernote 的 OAuth 身份验证 的过程如下:
// obtain request token (temporal credential)
OAuth1Operations oauthOperations = evernoteConnectionFactory.getOAuthOperations();
OAuthToken requestToken = oauthOperations.fetchRequestToken(
callbackUrl, null);
// construct authorization url with callback url for client to redirect
OAuth1Parameters parameters = new OAuth1Parameters();
parameters.set("preferRegistration", "true"); // create account
parameters.set("supportLinkedSandbox", "true");
String authorizeUrl = oauthOperations.buildAuthorizeUrl(
requestToken.getValue(), parameters);
// obtain access token
OAuthToken requestToken = new OAuthToken(oauthToken, requestTokenSecret);
AuthorizedRequestToken authorizedRequestToken = new AuthorizedRequestToken(requestToken, oauthVerifier);
OAuth1Operations oAuth1Operations = evernoteConnectionFactory.getOAuthOperations(); // EvernoteOAuth1Operations
EvernoteOAuthToken accessToken = (EvernoteOAuthToken)oAuth1Operations.exchangeForAccessToken(authorizedRequestToken, null);
有关更多项目文档,请查看项目 Wiki 页面。此外,还可以在此测试类中演示 Thrift 中的空安全集合。
由于 Evernote 没有 RESTful API,我创建了一个 Web 应用程序Evernote Rest Webapp,它为 Evernote 服务提供 RESTful 端点。它构建在Spring Boot 和Spring Social Evernote之上。如果您感兴趣,此实现可以作为一种桥接 API。
Spring Social Evernote 提供了现代化的编程模型,并可轻松将 Evernote 身份验证集成到您的应用程序中。
如果您有任何建议、问题或其他任何事项,请通过 @ttddyy 联系我。