1

我正在尝试使用Spring Integration with Twitter在我的 Windows XP 机器上使用独立程序向我的 Twitter 帐户发布消息。但我收到以下错误 -

WARNING: POST request for "https://api.twitter.com/1/statuses/update.json" resulted in 401 (Unauthorized); invoking error handler
Exception in thread "main" org.springframework.integration.MessageHandlingException: error occurred in message handler [org.springframework.integration.twitter.outbound.StatusUpdatingMessageHandler#0]
    at org.springframework.integration.handler.AbstractMessageHandler.handleMessage(AbstractMessageHandler.java:79)
    at org.springframework.integration.dispatcher.UnicastingDispatcher.doDispatch(UnicastingDispatcher.java:115)
    at org.springframework.integration.dispatcher.UnicastingDispatcher.dispatch(UnicastingDispatcher.java:102)
    at org.springframework.integration.channel.AbstractSubscribableChannel.doSend(AbstractSubscribableChannel.java:77)
    at org.springframework.integration.channel.AbstractMessageChannel.send(AbstractMessageChannel.java:157)
    at org.springframework.integration.channel.AbstractMessageChannel.send(AbstractMessageChannel.java:128)
    at com.skilledmonster.spring.integration.twitter.TwitterOutbound.main(TwitterOutbound.java:20)
Caused by: org.springframework.social.RevokedAuthorizationException: The authorization has been revoked. Reason: Unknown
    at org.springframework.social.twitter.api.impl.TwitterErrorHandler.handleClientErrors(TwitterErrorHandler.java:96)
    at org.springframework.social.twitter.api.impl.TwitterErrorHandler.handleError(TwitterErrorHandler.java:58)
    at org.springframework.web.client.RestTemplate.handleResponseError(RestTemplate.java:486)
    at org.springframework.web.client.RestTemplate.doExecute(RestTemplate.java:443)
    at org.springframework.web.client.RestTemplate.execute(RestTemplate.java:415)
    at org.springframework.web.client.RestTemplate.postForObject(RestTemplate.java:294)
    at org.springframework.social.twitter.api.impl.TimelineTemplate.updateStatus(TimelineTemplate.java:236)
    at org.springframework.social.twitter.api.impl.TimelineTemplate.updateStatus(TimelineTemplate.java:224)
    at org.springframework.integration.twitter.outbound.StatusUpdatingMessageHandler.handleMessageInternal(StatusUpdatingMessageHandler.java:57)
    at org.springframework.integration.handler.AbstractMessageHandler.handleMessage(AbstractMessageHandler.java:73)
    ... 6 more

这是我的代码 -

twitter-outbound.xml

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:int="http://www.springframework.org/schema/integration"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:twitter="http://www.springframework.org/schema/integration/twitter"
    xmlns:context="http://www.springframework.org/schema/context"
    xsi:schemaLocation="http://www.springframework.org/schema/integration/twitter 
    http://www.springframework.org/schema/integration/twitter/spring-integration-twitter-2.1.xsd 
    http://www.springframework.org/schema/beans 
    http://www.springframework.org/schema/beans/spring-beans-3.0.xsd 
    http://www.springframework.org/schema/integration 
    http://www.springframework.org/schema/integration/spring-integration-2.1.xsd 
    http://www.springframework.org/schema/context 
    http://www.springframework.org/schema/context/spring-context-3.0.xsd">

    <context:component-scan
        base-package="com.apress.prospringintegration.social.twitter" />

    <context:property-placeholder location="/twitter.properties" />

    <int:channel id="twitterOutbound" />

    <twitter:outbound-channel-adapter twitter-template="twitterTemplate" channel="twitterOutbound" />


    <bean id="twitterTemplate"
        class="org.springframework.social.twitter.api.impl.TwitterTemplate">
        <constructor-arg value="${twitter.consumer-key}" />
        <constructor-arg value="${twitter.consumer-secret}" />
        <constructor-arg value="${twitter.access-token}" />
        <constructor-arg value="${twitter.access-token-secret}" />
    </bean>
</beans>

TwitterConfigurationTemplate.java

package com.skilledmonster.spring.integration.twitter;

import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.social.twitter.api.impl.TwitterTemplate;

@Configuration
public class TwitterConfigurationTemplate {
      @Value("${consumer-key}") 
        private String consumerKey; 

        @Value("${consumer-secret}") 
        private String consumerSecret; 

        @Value("${access-token}") 
        private String accessToken; 

        @Value("${access-token-secret}") 
        private String accessTokenSecret; 

        @Bean 
        public TwitterTemplate twitterTemplate() { 
            TwitterTemplate twitterOperations = 
                    new TwitterTemplate( 
                            consumerKey, consumerSecret, accessToken, accessTokenSecret); 
            return twitterOperations; 
        } 
}

TwitterOutbound.java

package com.skilledmonster.spring.integration.twitter;

import java.util.Calendar;

import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import org.springframework.integration.Message;
import org.springframework.integration.MessageChannel;
import org.springframework.integration.message.GenericMessage;

public class TwitterOutbound {

    public static void main(String[] args) {

        ApplicationContext context = new ClassPathXmlApplicationContext("/twitter-outbound.xml", TwitterOutbound.class);

        MessageChannel input = context.getBean("twitterOutbound", MessageChannel.class);

        Message<String> message = new GenericMessage<String>("Testing new Twitter samples for #springintegration"+Calendar.getInstance().getTimeInMillis());
        input.send(message);

    }

}

twitter.properties

twitter.consumer-key=onj5cG1P9pe7n9qA8UI4EA 
twitter.consumer-secret=2l7hqMafKYaTkVBW3YfuBfGdzCtmICOJwjOOCEeQ 
twitter.access-token=792995125-dXmN1Pbw7sE4WttvAbX7ssxEn4lHaVd6uOX3IMxk 
twitter.access-token-secret=a1EuvvONcphdqXpfJVjCdaIBDlMZSUL5pgimWuEtg

仅供参考 - 我确实使用 twitter4j 测试了我的 twitter 令牌和密钥,它似乎成功地将消息发布到 twitter。

这是我的 twitter4j 代码-

OAuthSetup.java

package com.skilledmonster.spring.integration.twitter;

import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.util.Calendar;

import twitter4j.Status;
import twitter4j.Twitter;
import twitter4j.TwitterException;
import twitter4j.TwitterFactory;
import twitter4j.auth.AccessToken;
import twitter4j.auth.RequestToken;
public class OAuthSetup {
  /**
   * @param args
   */
  public static void main(String args[]) throws Exception {
      // The factory instance is re-useable and thread safe.
      Twitter twitter = new TwitterFactory().getInstance();

//insert the appropriate consumer key and consumer secret here

      twitter.setOAuthConsumer("onj5cG1P9pe7n9qA8UI4EA", 
          "2l7hqMafKYaTkVBW3YfuBfGdzCtmICOJwjOOCEeQ");
      RequestToken requestToken = twitter.getOAuthRequestToken();
      AccessToken accessToken = null;
      BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
      while (null == accessToken) {
        System.out.println("Open the following URL and grant access to your account:");
        System.out.println(requestToken.getAuthorizationURL());
        System.out.print("Enter the PIN(if aviailable) or just hit enter.[PIN]:");
        String pin = br.readLine();
        try{
           if(pin.length() > 0){
             accessToken = twitter.getOAuthAccessToken(requestToken, pin);
           }else{
             accessToken = twitter.getOAuthAccessToken();
           }
        } catch (TwitterException te) {
          if(401 == te.getStatusCode()){
            System.out.println("Unable to get the access token.");
          }else{
            te.printStackTrace();
          }
        }
      }
      //persist to the accessToken for future reference.
      System.out.println(twitter.verifyCredentials().getId());
      System.out.println("token : " + accessToken.getToken());
      System.out.println("tokenSecret : " + accessToken.getTokenSecret());
      //storeAccessToken(twitter.verifyCredentials().getId() , accessToken);
      Status status = twitter.updateStatus("Testing new Twitter samples for springintegration # "+Calendar.getInstance().getTimeInMillis());
      System.out.println("Successfully updated the status to [" + status.getText() + "].");
      System.exit(0);
    }
}

谁能建议我这里出了什么问题?

4

2 回答 2

0

您用于访问 Twitter 的令牌已被撤销,或者可能对您正在使用的消费者 ID/应用程序 ID 无效。

org.springframework.social.RevokedAuthorizationException: The authorization has been revoked

您将需要执行新的授权以获取用于您的应用程序的令牌和机密,或者,在 twitter 应用程序配置页面 (https://dev.twitter.com/apps/) 上,您可以专门为您的个人用途。这对于方便地测试应用程序而无需执行 OAuth 很有用。

于 2012-09-01T10:52:07.870 回答
0

我认为问题在于属性文件中键值中的空格:-)

这是我博客上的完整示例。

于 2012-09-06T19:43:38.577 回答