Spring Social Twitter Setup – Spring社交推特设置

最后修改: 2013年 4月 14日

中文/混合/英文(键盘快捷键:t)

The first part of the series dealth with the initial work of consuming the StackExchange REST API in order to retrieve its top questions. This second part will focus on setting up the support necessary to interact with the Twitter REST APIs using the Spring Social Twitter project. The end goal is to be able to tweet these questions, two per day, on several accounts, each focused on a single topic.

该系列的第一部分处理了消耗StackExchange REST API以检索其热门问题的初步工作。这第二部分将侧重于设置必要的支持,以便使用Spring Social Twitter项目与Twitter REST API进行交互。最终的目标是能够在几个账户上推送这些问题,每天两个,每个账户专注于一个主题。

1. Using Spring Social Twitter

1.使用Spring Social Twitter

The required dependencies necessary to use the Spring Social Twitter project are straightforward. First, we define spring-social-twitter itself:

使用Spring Social Twitter项目所需的依赖性是很简单的。首先,我们定义spring-social-twitter本身。

<dependency>
   <groupId>org.springframework.social</groupId>
   <artifactId>spring-social-twitter</artifactId>
   <version>1.1.0.RELEASE</version>
</dependency>

Then, we need to override some of it’s dependencies with more up-to-date versions:

然后,我们需要用更多的最新版本覆盖它的一些依赖关系。

<dependency>
   <groupId>org.springframework</groupId>
   <artifactId>spring-core</artifactId>
   <version>4.1.0.RELEASE</version>
</dependency>
<dependency>
   <groupId>org.springframework</groupId>
   <artifactId>spring-web</artifactId>
   <version>4.1.0.RELEASE</version>
</dependency>
<dependency>
   <groupId>org.codehaus.jackson</groupId>
   <artifactId>jackson-mapper-asl</artifactId>
   <version>1.9.13</version>
</dependency>

Both spring-core and spring-web are defined as dependencies by spring-social-twitter but with older versions3.0.7.RELEASE and 3.1.0.RELEASE respectively. Overriding these in our own pom ensures that the project is using the up-to-date versions that we have defined instead of these older inherited versions.

spring-corespring-web都被spring-social-twitter定义为依赖项,但都是较早的版本3.0.7.RELEASE3.1.0.RELEASE。在我们自己的pom中重写这些,可以确保项目使用我们定义的最新版本,而不是这些旧的继承版本。

2. Creating a Twitter Application

2.创建一个Twitter应用程序

This usecase – tweeting on a personal account and not on behalf of other users on their accounts, is a simple one. The fact that it is simple allows us to dispense with most of the OAuth orchestration necessary if the application would need to tweet for multiple users, on each of their twitter accounts.

这个用例–在个人账户上发推,而不是代表其他用户的账户发推,是一个简单的用例。简单的事实使我们能够免除大部分OAuth 协调,如果应用程序需要在多个用户的每个 twitter 帐户上为其发布推文的话。

So, for our usecase, we will create the TwitterTemplate directly, as we can manually set up everything we need to do so.

因此,对于我们的用例,我们将直接创建TwitterTemplate,因为我们可以手动设置我们需要做的一切。

First thing we need is a dev application – one can be created here, after logging in. After creating the application, we will have a Consumer Key and Consumer Secret – these are obtained from the page of the Application – on the Details tab, under OAuth settings.

首先,我们需要一个dev应用程序 – 一个可以在这里创建,登录后。创建应用程序后,我们将有一个消费者密钥消费者秘密–这些可以从应用程序的页面上获得–在Details标签,在OAuth设置下。

Also, in order to allow the Application to tweet on the account, Read and Write Access must be set to replace the default Read only privileges.

另外,为了允许应用程序在账户上发推文,必须设置读和写权限,以取代默认的唯一权限。

3. Provisioning a TwitterTemplate

3.提供一个TwitterTemplate

Next, the TwitterTemplate requires an Access Token and an Access Token Secret to be provisioned. These can also be generated from the Application page – under the Details tab – Create my access token. Both the Access Token and the Secret can then be retrieved from under the OAuth tool tab.

接下来,TwitterTemplate需要一个访问令牌和一个访问令牌秘密来配置。这些也可以从应用程序页面生成 – 在Details标签下 – Create my access token。然后可以从OAuth工具标签下检索访问令牌和秘密。

New ones can always be regenerated on the Details tab, via Recreate my access token action.

新的访问令牌总是可以在Details标签上,通过Recreate my access token动作来重新生成。

At this point we have everything we need – the Consumer Key and Consumer Secret, as well as the Access Token and Access Token Secret – which means we can go ahead and create our TwitterTemplate for that application:

在这一点上,我们拥有我们需要的一切–消费者密钥和消费者秘密,以及访问令牌和访问令牌秘密–这意味着我们可以继续为该应用程序创建我们的TwitterTemplate

new TwitterTemplate(consumerKey, consumerSecret, accessToken, accessTokenSecret);

4. One Template per Account

4.每个账户一个模板

Now that we have seen how to create a single TwitterTemplate for a single account, we can look back at our usecase again – we need to tweet on several accounts – which means we need several TwitterTemplate instances.

现在我们已经看到了如何为一个账户创建一个TwitterTemplate,我们可以再回头看看我们的用例–我们需要在几个账户上发推特,这意味着我们需要几个TwitterTemplate实例。

These can be easily created on request, with a simple mechanism:

这些可以根据要求很容易地创建,有一个简单的机制。

@Component
public class TwitterTemplateCreator {
   @Autowired
   private Environment env;

   public Twitter getTwitterTemplate(String accountName) {
      String consumerKey = env.getProperty(accountName + ".consumerKey");
      String consumerSecret = env.getProperty(accountName + ".consumerSecret");
      String accessToken = env.getProperty(accountName + ".accessToken");
      String accessTokenSecret = env.getProperty(accountName + ".accessTokenSecret");
      Preconditions.checkNotNull(consumerKey);
      Preconditions.checkNotNull(consumerSecret);
      Preconditions.checkNotNull(accessToken);
      Preconditions.checkNotNull(accessTokenSecret);

      TwitterTemplate twitterTemplate = 
         new TwitterTemplate(consumerKey, consumerSecret, accessToken, accessTokenSecret);
      return twitterTemplate;
   }
}

The four security artifacts are of course externalized in a properties file, by account; for example, for the SpringAtSO account:

当然,这四个安全工件是按账户在属性文件中外置的;例如,对于SpringAtSO账户

SpringAtSO.consumerKey=nqYezCjxkHabaX6cdte12g
SpringAtSO.consumerSecret=7REmgFW4SnVWpD4EV5Zy9wB2ZEMM9WKxTaZwrgX3i4A
SpringAtSO.accessToken=1197830142-t44T7vwgmOnue8EoAxI1cDyDAEBAvple80s1SQ3
SpringAtSO.accessTokenSecret=ZIpghEJgFGNGQZzDFBT5TgsyeqDKY2zQmYsounPafE

This allows for a good mix of flexibility and safety – the security credentials are not part of the codebase (which is opensource) but live independently on the filesystem and are picked up by Spring and available in the Spring Enviroment via a simple configuration:

这使得灵活性和安全性得到了很好的结合–安全证书不是代码库(是开源的)的一部分,而是独立存在于文件系统中,并由Spring接收,通过简单的配置在Spring环境中可用。

@Configuration
@PropertySource({ "file:///opt/stack/twitter.properties" })
public class TwitterConfig {
    // 
}

Properties in Spring are a subject that has been discussed before, so we won’t go into further details on this subject here.

Spring中的属性是一个之前已经讨论过的话题,所以我们在此不再赘述。

Finally, a test will verify that an account has the necessary security information readily available in the Spring Environment; if the properties are not present, the getTwitterTemplate logic should fail the test with a NullPointerException:

最后,测试将验证一个账户在Spring环境中是否有现成的必要安全信息;如果属性不存在,getTwitterTemplate逻辑应该以NullPointerException失败。

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(classes = { TwitterConfig.class })
public class TwitterTemplateCreatorIntegrationTest {
   @Autowired
   private TwitterTemplateCreator twitterTemplateCreator;
   //
   @Test
   public void givenValidAccountSpringAtSO_whenRetrievingTwitterClient_thenNoException() {
      twitterTemplateCreator.getTwitterTemplate(SimpleTwitterAccount.SpringAtSO.name());
   }
}

5. Tweeting

5.鸣叫

With the TwitterTemplate created, let’s turn to the actual action of tweeting. For this, we’ll use a very simple service, accepting a TwitterTemplate and using its underlying API to create a tweet:

随着TwitterTemplate的创建,让我们转向tweeting的实际操作。为此,我们将使用一个非常简单的服务,接受一个TwitterTemplate并使用其底层API来创建一条tweet。

@Service
public class TwitterService {
   private Logger logger = LoggerFactory.getLogger(getClass());

   public void tweet(Twitter twitter, String tweetText) {
      try {
         twitter.timelineOperations().updateStatus(tweetText);
      } catch (RuntimeException ex) {
         logger.error("Unable to tweet" + tweetText, ex);
      }
   }
}

6. Testing the TwitterTemplate

6.测试TwitterTemplate

And finally, we can write an integration test to perform the entire process of provisioning a TwitterTemplate for an account and tweeting on that account:

最后,我们可以写一个集成测试来执行为一个账户提供TwitterTemplate的整个过程,并在该账户上发推。

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(classes = { TwitterConfig.class })
public class TweetServiceLiveTest {
   @Autowired
   private TwitterService twitterService;
   @Autowired
   private TwitterTemplateCreator twitterCreator;

   @Test
   public void whenTweeting_thenNoExceptions() {
      Twitter twitterTemplate = twitterCreator.getTwitterTemplate("SpringAtSO");
      twitterService.tweet(twitterTemplate, "First Tweet");
   }
}

7. Conclusion

7.结论

At this point, the Twitter API we have created is completely separate from the StackExchange API and can be used independent of that particular usecase, to tweet anything.

在这一点上,我们所创建的Twitter API与StackExchange API完全分开,可以独立于那个特定的用例,用于推送任何东西。

The next logical step in the process of tweeting questions from Stack Exchange accounts is to create a component – interacting with both the Twitter and StackExchange APIs that we have presented so far – this will be the focus of the next article in this series.

在从Stack Exchange账户推送问题的过程中,下一个合乎逻辑的步骤是创建一个组件–与我们迄今为止所介绍的Twitter和StackExchange APIs互动–这将是本系列下一篇文章的重点。