Для твитов в 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/