Для твитов в Java не так много вариантов, как в других языках, особенно в ruby. Лучшее решение, которое я нашел, это писец-ява . Взаимодействие с этой библиотекой очень просто, но вы тратите много времени, пытаясь найти, что делать, когда.
Первым шагом было заставить библиотеку говорить как Гобелен. Для этого мы создаем базовый сервис для OAuth.
//Interface public interface BaseOAuthService { String getAuthorizationURL(); Token requestAccessToken(String temporaryToken, String verifier); JSONObject send(OAuthResource resource); Token newRequestToken(); OAuthConfiguration getConfiguration(); } //Implementation public class BaseOAuthServiceImpl implements BaseOAuthService { private OAuthService service; private String apiPrefix; private OAuthConfiguration configuration; private static final Logger logger = LoggerFactory.getLogger(BaseOAuthServiceImpl.class); public BaseOAuthServiceImpl(OAuthConfiguration configuration, Class<? extends Api> provider, String apiPrefix) { ServiceBuilder builder = new ServiceBuilder().provider(provider) .apiKey(configuration.getApiKey()).apiSecret(configuration.getApiSecret()) .callback(configuration.getCallbackURL()); if (configuration.getScope() != null) { builder.scope(configuration.getScope()); } service = builder.build(); this.apiPrefix = apiPrefix; this.configuration = configuration; } @Override public String getAuthorizationURL() { return service.getAuthorizationUrl(newRequestToken()); } public Token newRequestToken() { return service.getRequestToken(); } public Token requestAccessToken(String oAuthToken, String verifier) { Token accessToken = service.getAccessToken( new Token(oAuthToken, configuration.getApiSecret()), new Verifier(verifier)); return accessToken; } public JSONObject send(OAuthResource resource) { OAuthRequest request = new OAuthRequest(resource.getMethod(), apiPrefix + resource.getURL()); resource.initialize(request); service.signRequest(resource.getAccessToken(), request); Response response = request.send(); checkResponse(response); resource.process(response); return new JSONObject(response.getBody()); } private void checkResponse(Response response) { if (response.getCode() != HttpServletResponse.SC_OK) { logger.error("Failed sending request : " + response.getBody()); throw new OAuthException("Failure sending request"); } } public OAuthService getOAuthService() { return service; } public OAuthConfiguration getConfiguration(){ return configuration; } }
Как вы можете видеть, там мало что происходит. Это просто оболочка, которая позволяет нам запрашивать ресурс, указанный OAuthResource. Ответ проверяется на статус и, если он не успешен (HTTP-код: 200), генерируется исключение.
public interface OAuthResource { Verb getMethod(); void initialize(OAuthRequest request); String getURL(); Token getAccessToken(); void process(Response response); } //An abstract implementation public abstract class AbstractOAuthResource implements OAuthResource { private Verb method; private String resource; private Token accessToken; public AbstractOAuthResource(Token accessToken, Verb method, String resource){ this.accessToken = accessToken; this.method = method; this.resource = resource; } @Override public Verb getMethod() { return method; } @Override public String getURL() { return resource; } @Override public Token getAccessToken(){ return accessToken; } @Override public void initialize(OAuthRequest request){ } @Override public void process(Response response) { } }
getMethod возвращает метод, который должен использоваться для запроса ресурса. getURL () возвращает URL ресурса. getAccessToken () возвращает токен доступа, который должен быть передан в запрос для авторизации. Метод initialize () используется для передачи параметров в запрос, а process () — для обработки ответа. Такой интерфейс лучше всего понять при реализации.
public class Tweet extends AbstractOAuthResource { private String tweet; public Tweet(Token token, String tweet){ super(token, Verb.POST, "statuses/update.json"); this.tweet = tweet; } @Override public void initialize(OAuthRequest request){ request.addBodyParameter("status", tweet); request.addBodyParameter("wrap_links", "true"); } }
API-интерфейсы Twitter ожидают POST-запрос ресурса «statuses / update.json» для обновления статуса пользователя на простом английском языке, чтобы твитнуть. Текст твита передается как параметр в запрос в методе initialize ().
Конфигурация для сервиса передается как
public class OAuthConfiguration { private String apiKey; private String apiSecret; private String callbackURL; private String scope; public OAuthConfiguration(String apiKey, String apiSecret, String callbackURL, String scope) { this.apiKey = apiKey; this.apiSecret = apiSecret; this.callbackURL = callbackURL; this.scope = scope; } public OAuthConfiguration(String apiKey, String apiSecret, String callbackURL){ this(apiKey, apiSecret, callbackURL, null); } public String getApiKey() { return apiKey; } public String getApiSecret() { return apiSecret; } public String getCallbackURL() { return callbackURL; } public String getScope() { return scope; } public void setScope(String scope){ this.scope = scope; } }
использование
Чтобы использовать этот сервис, давайте создадим компонент, который дает нам доступ к учетной записи Twitter
@Events({OAuthConstants.CONNECTION_ESTABLISHED, OAuthConstants.CONNECTION_FAILED}) public class TwitterConnect implements ClientElement { @Parameter(value = "prop:componentResources.id", defaultPrefix = BindingConstants.LITERAL) private String clientId; private String assignedClientId; @Inject private JavaScriptSupport javaScriptSupport; @Inject private ComponentResources resources; @Inject private TwitterService twitterService; void setupRender() { assignedClientId = javaScriptSupport.allocateClientId(clientId); } @Override public String getClientId() { return assignedClientId; } URL onConnectToTwitter() throws MalformedURLException { return new URL(twitterService.getAuthorizationURL()); } Object onAuthorize( @RequestParameter(value = "oauth_verifier", allowBlank = true) final String verifier, @RequestParameter(value = "oauth_token", allowBlank = true) String oAuthToken, @RequestParameter(value = "denied", allowBlank = true) String denied) { if(verifier != null){ return accessGranted(oAuthToken, verifier); }else { return accessDenied(denied); } } private Object accessGranted(String oAuthToken, String verifier) { Token accessToken = twitterService.requestAccessToken(oAuthToken, verifier); CaptureResultCallback<Object> callback = new CaptureResultCallback<Object>(); boolean handled = resources.triggerEvent(OAuthConstants.CONNECTION_ESTABLISHED, new Object[] { accessToken}, callback); if (handled) { return callback.getResult(); } return null; } private Object accessDenied(String denied) { CaptureResultCallback<Object> callback = new CaptureResultCallback<Object>(); boolean handled = resources.triggerEvent(OAuthConstants.CONNECTION_FAILED, new Object[] { denied}, callback); if (handled) { return callback.getResult(); } return null; } } public class OAuthConstants { public static final String DEFAULT_TWITTER_API_PREFIX = "http://api.twitter.com/1/"; public static final String CONNECTION_ESTABLISHED = "connectionEstablished"; public static final String CONNECTION_FAILED = "connectionFailed"; }
<t:container xmlns:t='http://tapestry.apache.org/schema/tapestry_5_1_0.xsd'> <a href='#' t:type='eventlink' t:event='connectToTwitter'><t:body/></a> </t:container>
Когда ссылка нажата, браузер перенаправляется на ссылку авторизации Twitter. Перед возвратом URL getAuthorizationURL () сначала запрашивает токен запроса из твиттера. Твиттер авторизует и перенаправляет браузер на URL-адрес обратного вызова (URL-адрес обратного вызова настраивается в модуле приложения), который запускает onAuthorize (), который в зависимости от того, была ли авторизация успешной или нет, инициирует различные события.
Услуги должны быть внесены в модуль приложения
public TwitterService buildTwitterService() { OAuthConfiguration configurer = new OAuthConfiguration("MY_API_KEY", "MY_API_SECRET", "http://127.0.0.1:9090/tweet.twitterconnect:authorize"); return new TwitterServiceImpl(configurer, OAuthConstants.DEFAULT_TWITTER_API_PREFIX); }
Обратите внимание, что URL-адрес должен указывать на обработчик события авторизации TwitterConnect. (Я знаю, что эта часть взломана, но скоро заменит лучшие решения)
И наконец страница, использующая это. Как вы могли догадаться из приведенного выше URL, твиттер-страница — Tweet
public class Tweet { @Inject private TwitterService twitterService; @SuppressWarnings("unused") @Property @Persist(PersistenceConstants.FLASH) private String message; void onConnectionEstablishedFromTwitterConnect(Token accessToken) { twitterService.tweet(accessToken, "Hello from scribe-twitter at " + new Date()); message = "Tweeted"; } void onConnectionFailed(String denied){ message = "Failed"; } }
<html xmlns:t='http://tapestry.apache.org/schema/tapestry_5_1_0.xsd'> <body> ${message}<br/> <a href='#' t:id='twitterconnect' t:type='twitterConnect'>Connect to Twitter</a> </body> </html>
От http://tawus.wordpress.com/2011/08/14/tweeting-with-tapestry/