spring social

几周前,我写了一篇文章,展示了我认为可以使用Spring Social编写的最简单的应用程序。 该应用程序读取并显示了Twitter用户的公共数据,并被编写为Spring Social和社交编码领域的介绍。 但是,让您的应用程序显示用户的公共数据只是故事的一半,而且在大多数情况下,您将需要显示用户的私有数据。

在本博客中,我将介绍您需要在应用程序的一两个页面上显示用户的Facebook或其他软件即服务(SaaS)提供程序数据的情况。 这里的想法是尝试演示最小的和最简单的操作,您可以将Spring Social添加到需要用户登录Facebook或其他SaaS提供商的应用程序中。

创建应用

要创建该应用程序,第一步是使用SpringSource Toolkit仪表板的模板部分创建一个基本的Spring MVC项目。 这提供了一个Web应用程序,可帮助您入门。

下一步是通过添加以下依赖项来设置pom.xml

<dependency><groupId>org.springframework.security</groupId><artifactId>spring-security-crypto</artifactId><version>${org.springframework.security.crypto-version}</version>
</dependency><!-- Spring Social -->
<dependency><groupId>org.springframework.social</groupId><artifactId>spring-social-core</artifactId><version>${spring-social.version}</version>
</dependency>
<dependency><groupId>org.springframework.social</groupId><artifactId>spring-social-web</artifactId><version>${spring-social.version}</version>
</dependency><!-- Facebook API -->
<dependency><groupId>org.springframework.social</groupId><artifactId>spring-social-facebook</artifactId><version>${org.springframework.social-facebook-version}</version>
</dependency><!-- JdbcUserConfiguration -->
<dependency><groupId>org.springframework</groupId><artifactId>spring-jdbc</artifactId><version>${org.springframework-version}</version>
</dependency>
<dependency><groupId>com.h2database</groupId><artifactId>h2</artifactId><version>1.3.159</version>
</dependency><!-- CGLIB, only required and used for @Configuration usage: could be removed in future release of Spring -->
<dependency><groupId>cglib</groupId><artifactId>cglib-nodep</artifactId><version>2.2</version>
</dependency>

…显然,您还需要在文件的%lt; properties />部分中添加以下内容:

<spring-social.version>1.0.2.RELEASE</spring-social.version>
<org.springframework.social-facebook-version>1.0.1.RELEASE</org.springframework.social-facebook-version>
<org.springframework.security.crypto-version>3.1.0.RELEASE</org.springframework.security.crypto-version>

您会注意到,我为spring-security-crypto添加了一个特定的pom条目:这是因为我正在使用Spring 3.0.6。 在Spring 3.1.x中,它已成为核心库的一部分。

唯一要注意的一点是,还依赖于spring-jdbch2 。 这是因为Spring的UserConnectionRepository默认实现: JdbcUsersConnectionRepository使用它们,因此即使此应用程序不对数据库持久化任何东西(据我所知),它们也是必需的。

班级

社交编码功能包括四个类(其中一个是我从Keith Donald的Spring Social Quick Start Sample代码中摘录的):

  • FacebookPostsController
  • 社会背景
  • Facebook配置
  • UserCookieGenerator

FacebookPostsController是应用程序的业务端,负责获取用户的Facebook数据并将其推入模型中以供显示。

@Controllerpublic class FacebookPostsController {private static final Logger logger = LoggerFactory.getLogger(FacebookPostsController.class);private final SocialContext socialContext;@Autowiredpublic FacebookPostsController(SocialContext socialContext) {this.socialContext = socialContext;}@RequestMapping(value = 'posts', method = RequestMethod.GET)public String showPostsForUser(HttpServletRequest request, HttpServletResponse response, Model model) throws Exception {String nextView;if (socialContext.isSignedIn(request, response)) {List<Post> posts = retrievePosts();model.addAttribute('posts', posts);nextView = 'show-posts';} else {nextView = 'signin';}return nextView;}private List<Post> retrievePosts() {Facebook facebook = socialContext.getFacebook();FeedOperations feedOps = facebook.feedOperations();List<Post> posts = feedOps.getHomeFeed();logger.info('Retrieved ' + posts.size() + ' posts from the Facebook authenticated user');return posts;}}

如您所见,从高级的角度来看,我们要实现的目标的逻辑非常简单:

IF user is signed in THEN read Facebook data, display Facebook data
ELSE ask user to sign in when user has signed in, go back to the beginning
END IF

FacebookPostsController将处理登录逻辑的任务委托给SocialContext类。 您可能会猜到,我从Spring真正有用的ApplicationContext中得到了此类的想法。 这里的想法是,有一个类负责将您的应用程序粘贴到Spring Social。

public class SocialContext implements ConnectionSignUp, SignInAdapter {/*** Use a random number generator to generate IDs to avoid cookie clashes* between server restarts*/private static Random rand;/*** Manage cookies - Use cookies to remember state between calls to the* server(s)*/private final UserCookieGenerator userCookieGenerator;/** Store the user id between calls to the server */private static final ThreadLocal<String> currentUser = new ThreadLocal<String>();private final UsersConnectionRepository connectionRepository;private final Facebook facebook;public SocialContext(UsersConnectionRepository connectionRepository, UserCookieGenerator userCookieGenerator,Facebook facebook) {this.connectionRepository = connectionRepository;this.userCookieGenerator = userCookieGenerator;this.facebook = facebook;rand = new Random(Calendar.getInstance().getTimeInMillis());}@Overridepublic String signIn(String userId, Connection<?> connection, NativeWebRequest request) {userCookieGenerator.addCookie(userId, request.getNativeResponse(HttpServletResponse.class));return null;}@Overridepublic String execute(Connection<?> connection) {return Long.toString(rand.nextLong());}public boolean isSignedIn(HttpServletRequest request, HttpServletResponse response) {boolean retVal = false;String userId = userCookieGenerator.readCookieValue(request);if (isValidId(userId)) {if (isConnectedFacebookUser(userId)) {retVal = true;} else {userCookieGenerator.removeCookie(response);}}currentUser.set(userId);return retVal;}private boolean isValidId(String id) {return isNotNull(id) && (id.length() > 0);}private boolean isNotNull(Object obj) {return obj != null;}private boolean isConnectedFacebookUser(String userId) {ConnectionRepository connectionRepo = connectionRepository.createConnectionRepository(userId);Connection<Facebook> facebookConnection = connectionRepo.findPrimaryConnection(Facebook.class);return facebookConnection != null;}public String getUserId() {return currentUser.get();}public Facebook getFacebook() {return facebook;}}

SocialContext实现Spring Social的ConnectionSignUpSignInAdapter接口。 它包含三个方法isSignedIn()signIn()execute()FacebookSignsController类调用isSignedIn来实现上述逻辑,而Spring Social调用signIn()execute()

从我以前的博客中,您会记住,OAuth需要在浏览器,您的应用程序和SaaS提供程序之间进行多次旅行。 在进行这些操作时,应用程序需要保存多个OAuth参数的状态,例如:client_id,redirect_uri和其他参数。 通过将OAuth对话的状态映射到您的Webapp所控制的变量,Spring Social将所有这些复杂性从应用程序中隐藏起来。 这是userId ; 但是,不要以为它是用户名,因为它从未被用户看到,它只是一个唯一标识符,该标识符将许多HTTP请求链接到Spring Social核心中的SaaS提供程序连接(例如Facebook)。

由于其简单性,我遵循了Keith Donald的想法,即使用cookie在浏览器和服务器之间传递用户ID来保持状态。 我还从Spring Social快速入门中借用了他的UserCookieGenerator类来帮助我。

isSignedIn(...)方法使用UserCookieGenerator来确定HttpServletRequest对象是否包含包含有效用户ID的cookie。 如果这样做的话,它还会找出Spring Social的UsersConnectionRepository是否包含链接到相同用户ID的ConnectionRepository 。 如果这两个测试都返回true,则应用程序将请求并显示用户的Facebook数据。 如果两个测试之一返回false,则将要求用户登录。

SocialContext是专门为该示例编写的,并且包含足够的功能来演示我在此博客中所讨论的内容。 这意味着它目前有点粗糙并且可以使用,尽管可以对其进行改进以涵盖与任何/许多提供程序的连接,然后在不同的应用程序中重复使用。

最后要提到的类是FacebookConfig ,它大致基于Spring Social示例代码。 此代码与示例代码之间有两个主要区别,其中一个是FacebookConfig类实现InitializingBean接口。 这样,可以将usersConnectionRepositiory变量注入到socialContext中, 然后可以将socialContext作为其ConnectionSignUp实现注入到usersConnectionRepositiory中。 第二个区别是我正在实现providerSignInController(...)方法,以提供正确配置的ProviderSignInController对象,Spring Social将使用该对象登录Facebook。 我在此处所做的默认设置的唯一更改是将ProviderSignInControllerpostSignInUrl属性设置为“ / posts ”。 这是页面的URL,将包含用户Facebook数据,并在用户登录完成后被调用。

@Configurationpublic class FacebookConfig implements InitializingBean {private static final Logger logger = LoggerFactory.getLogger(FacebookConfig.class);private static final String appId = '439291719425239';private static final String appSecret = '65646c3846ab46f0b44d73bb26087f06';private SocialContext socialContext;private UsersConnectionRepository usersConnectionRepositiory;@Injectprivate DataSource dataSource;/*** Point to note: the name of the bean is either the name of the method* 'socialContext' or can be set by an attribute* * @Bean(name='myBean')*/@Beanpublic SocialContext socialContext() {return socialContext;}@Beanpublic ConnectionFactoryLocator connectionFactoryLocator() {logger.info('getting connectionFactoryLocator');ConnectionFactoryRegistry registry = new ConnectionFactoryRegistry();registry.addConnectionFactory(new FacebookConnectionFactory(appId, appSecret));return registry;}/*** Singleton data access object providing access to connections across all* users.*/@Beanpublic UsersConnectionRepository usersConnectionRepository() {return usersConnectionRepositiory;}/*** Request-scoped data access object providing access to the current user's* connections.*/@Bean@Scope(value = 'request', proxyMode = ScopedProxyMode.INTERFACES)public ConnectionRepository connectionRepository() {String userId = socialContext.getUserId();logger.info('Createung ConnectionRepository for user: ' + userId);return usersConnectionRepository().createConnectionRepository(userId);}/*** A proxy to a request-scoped object representing the current user's* primary Facebook account.* * @throws NotConnectedException*             if the user is not connected to facebook.*/@Bean@Scope(value = 'request', proxyMode = ScopedProxyMode.INTERFACES)public Facebook facebook() {return connectionRepository().getPrimaryConnection(Facebook.class).getApi();}/*** Create the ProviderSignInController that handles the OAuth2 stuff and* tell it to redirect back to /posts once sign in has completed*/@Beanpublic ProviderSignInController providerSignInController() {ProviderSignInController providerSigninController = new ProviderSignInController(connectionFactoryLocator(),usersConnectionRepository(), socialContext);providerSigninController.setPostSignInUrl('/posts');return providerSigninController;}@Overridepublic void afterPropertiesSet() throws Exception {JdbcUsersConnectionRepository usersConnectionRepositiory = new JdbcUsersConnectionRepository(dataSource,connectionFactoryLocator(), Encryptors.noOpText());socialContext = new SocialContext(usersConnectionRepositiory, new UserCookieGenerator(), facebook());usersConnectionRepositiory.setConnectionSignUp(socialContext);this.usersConnectionRepositiory = usersConnectionRepositiory;}}

申请流程

如果您运行此应用程序2,首先会看到一个主屏幕,其中包含一个简单的链接,邀请您显示帖子。 首次单击此链接时,您将重定向/ signin页面。 按下“登录”按钮,指示ProviderSignInController与Facebook联系。 身份验证完成后, ProviderSignInController会将应用程序定向回/ posts页面,这一次它将显示Facebook数据。

组态

为了完整起见,我认为我应该提到XML配置,尽管它没有太多,因为我在FacebookConfig类上使用了Spring注释@Configuration 。 我已经从Spring Social导入了“ data.xml ”,以便JdbcUsersConnectionRepository可以工作并添加了

<context:component-scan base-package='com.captaindebug.social' />

…用于自动接线。

摘要

尽管此示例应用程序基于将应用程序连接到用户的Facebook数据的基础,但可以轻松地对其进行修改以使用任何Spring Social客户端模块。 如果您喜欢挑战,请尝试在所有中文版本的地方实施Sina-Weibo-这是一个挑战,但是Google Translate确实很有用。

1个Spring社交和其他OAuth博客:

  1. Spring Social入门
  2. Facebook和Twitter:幕后花絮
  3. OAuth管理步骤
  4. OAuth 2.0 Webapp流程概述

2该代码可在Github上找到:https://github.com/roghughe/captaindebug.git

参考: Captain Debug的Blog博客中的JCG合作伙伴 Roger Hughes的Spring Social入门-第2部分 。

翻译自: https://www.javacodegeeks.com/2012/07/getting-started-with-spring-social-part.html

spring social

spring social_Spring Social入门–第2部分相关推荐

  1. spring social_Spring Social入门

    spring social 像我一样,无论是添加简单的Facebook"赞"按钮,一大堆"共享"按钮还是显示时间轴信息,您都不会注意到当前对应用程序" ...

  2. Spring Social入门–第2部分

    几周前,我写了一篇文章,展示了我认为可以使用Spring Social编写的最简单的应用程序. 该应用程序读取并显示了Twitter用户的公共数据,并被编写为Spring Social和社交编码领域的 ...

  3. Spring Social入门

    像我一样,无论是添加简单的Facebook"赞"按钮,一大堆"共享"按钮还是显示时间轴信息,您都不会注意到当前对应用程序"社交化"的热衷. ...

  4. Spring Cloud Eureka 入门 (三)服务消费者详解

    2019独角兽企业重金招聘Python工程师标准>>> 摘要: 原创出处:www.bysocket.com 泥瓦匠BYSocket 希望转载,保留摘要,谢谢! "真正的进步 ...

  5. Spring Data ElasticSearch入门案例

    Spring Data ElasticSearch入门案例 创建maven工程elasticsearch_springdata 基于maven导入坐标 导入spring data elasticsea ...

  6. 微服务技术方案:Spring Cloud 从入门到实战

    随着互联网技术的发展与不断创新,以及用户流量的不断增大,越来越多的企业项目面临大数据.高并发等问题,随之而来的就是通过分布式模型组建架构,微服务思想就集中体现了应用价值,2020 年的你还没有掌握微服 ...

  7. Spring Data Solr入门

    Spring Data Solr是Spring Data项目的扩展,该项目旨在简化Apache Solr在Spring应用程序中的使用. 请注意,这不是Spring(数据)或Solr的简介. 我认为您 ...

  8. spring boot(一)入门

    目录 spring boot(一)入门 一.简介 1.微服务的概念 2.什么是spring boot 3.快速入门 4.springboot的快捷部署 spring boot(一)入门 一.简介 1. ...

  9. Spring Cloud Eureka 入门 (二)服务提供者详解

    2019独角兽企业重金招聘Python工程师标准>>> 摘要: 原创出处:www.bysocket.com 泥瓦匠BYSocket 希望转载,保留摘要,谢谢! "优秀不是过 ...

最新文章

  1. spring cloud的网关服务Zuul
  2. 2009第二届C++技术大会即将在上海隆重召开
  3. 20亿参数+30亿张图像,刷新ImageNet最高分!谷歌大脑华人研究员领衔发布最强Transformer...
  4. Android-可自动缩小字体的TextView
  5. Spring4.0之四:Meta Annotation(元注解)
  6. PHP2002,php - 错误:SQLSTATE [HY000] [2002]没有这样的文件或目录 - SO中文参考 - www.soinside.com...
  7. Qt文档阅读笔记-Qt单元测试中模拟GUI事件
  8. jquery判断对象是否存在
  9. Emacs下查词典(StarDict篇)
  10. 《xUnit Test Patterns》学习笔记2 - Goal Of Test Automation
  11. 【Java】JSON数据交换格式及其使用案例(聊天工具)
  12. ERROR: libopenjp2 = 2.1.0 not found using pkg-config
  13. 5V升压8.4V芯片电路图,5V充电7.4V电池
  14. 伴随方法:线性方程的伴随方程(Adjoint Equation)
  15. git push时 please tell me who you are 或 git fatal: empty ident name (for <>) not llowed
  16. 服务器系统飞行模式怎么关闭,win10系统开启飞行模式之后无法关闭怎么解决
  17. 如何打造一个可躺赚的网盘项目,每天只需要2小时
  18. 如何查看手机计算机历史记录,怎么查看电脑历史操作记录
  19. 【08月07日】A股滚动市盈率PE最低排名
  20. 普林斯顿大学计算机排名,普林斯顿大学计算机科学与工程世界排名2020年最新排名第12(ARWU世界排名)...

热门文章

  1. Java中的6颗语法糖
  2. 干货|基于 Spring Cloud 的微服务落地
  3. (七)HTML和CSS 、JavaScript 和Java到底有什么区别,今天终于明白了!!!
  4. Object.keys方法拿到对象的key值
  5. 2015蓝桥杯省赛---java---A---3(九数分三组)
  6. 电脑基本快捷键的使用
  7. Android public class MyApplication extends MultiDexApplication使用
  8. 3-8 基于SpringBoot连接数据库与配置MyBatis实操 创建表sql
  9. netapp做内网穿透有问题
  10. 圆心角 圆弧上点坐标_数控加工中心CNC的G02/G03圆弧指令的I、J、与R的区别