Продолжая публикацию в Твиттере , мы расширяем службу OAuth, чтобы мы могли публиковать сообщения на стене пользователя. Поскольку вся тяжелая работа уже проделана, нам просто нужно немного подправить.
Так вот сервис Facebook
//interface public interface FacebookService extends BaseOAuthService { void post(Token accessToken, String text); } //implementation public class FacebookServiceImpl extends BaseOAuthServiceImpl implements FacebookService { public FacebookServiceImpl(OAuthConfiguration configuration, String apiPrefix) { super(configuration, FacebookApi.class, apiPrefix); } @Override public void post(Token accessToken, String text) { send(new FacebookPost(accessToken, text)); } @Override public Token newRequestToken() { return null; // Empty Token } @Override public Token requestAccessToken(String oAuthToken, String verifier) { return getOAuthService().getAccessToken(newRequestToken(), new Verifier(verifier)); } }
Facebook не нужен токен запроса, вы просто делаете запрос с пустым токеном. Запрос заполняется вашим ключом и секретом API, но это делает scribe-java, вам не нужно об этом беспокоиться. Следующим является OAuthResource для поста Facebook
public class FacebookPost extends AbstractOAuthResource { private String text; public FacebookPost(Token accessToken, String text) { super(accessToken, Verb.POST, "/me/feed/"); this.text = text; } @Override public void initialize(OAuthRequest request){ request.addBodyParameter("message", text); } }
Это просто означает, что у нас есть ресурс в / me / feed /, который мы можем запросить через метод POST и передать текст в качестве параметра сообщения.
Наконец компонент
@Events({OAuthConstants.CONNECTION_ESTABLISHED, OAuthConstants.CONNECTION_FAILED}) public class FacebookConnect 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 FacebookService facebookService; void setupRender() { assignedClientId = javaScriptSupport.allocateClientId(clientId); } @Override public String getClientId() { return assignedClientId; } URL onConnectToFacebook() throws MalformedURLException { return new URL(facebookService.getAuthorizationURL()); } Object onAuthorize( @RequestParameter(value = "code", allowBlank = true) final String code, @RequestParameter(value = "error_reason", allowBlank = true) final String errorReason, @RequestParameter(value = "error", allowBlank = true) final String error, @RequestParameter(value = "error_description", allowBlank = true) final String errorDescription ) { if(code != null){ return accessGranted(code); }else { return accessDenied(error, errorReason, errorDescription); } } private Object accessGranted(String code) { Token accessToken = facebookService.requestAccessToken(null, code); CaptureResultCallback<Object> callback = new CaptureResultCallback<Object>(); JSONObject response = facebookService.send(new FacebookAccessInfo(accessToken)); boolean handled = resources.triggerEvent(OAuthConstants.CONNECTION_ESTABLISHED, new Object[] { accessToken, (String)response.get("id") }, callback); if (handled) { return callback.getResult(); } return null; } private Object accessDenied(String error, String errorReason, String errorDescription) { CaptureResultCallback<Object> callback = new CaptureResultCallback<Object>(); boolean handled = resources.triggerEvent(OAuthConstants.CONNECTION_FAILED, new Object[] { error, errorReason, errorDescription }, callback); if (handled) { return callback.getResult(); } return null; } }
<t:container xmlns:t='http://tapestry.apache.org/schema/tapestry_5_1_0.xsd'> <a href='#' t:type='eventlink' t:event='connectToFacebook'><t:body/></a> </t:container>
Здесь мы используем другой OAuthResource для получения информации о пользователях.
public class FacebookVerifyCredentials extends AbstractOAuthResource { public FacebookVerifyCredentials(Token accessToken){ super(accessToken, Verb.GET, "account/verify_credentials"); } }
Это почти копия TwitterConnect из предыдущего поста. При нажатии на ссылку обработчик события возвращает URL-адрес авторизации, который перенаправляет браузер на авторизацию Facebook. После авторизации Facebook перенаправляет браузер по URL-адресу обратного вызова (указанному в конфигурации), который является нашим обработчиком события onAuthorize (). Обработчик событий, основываясь на параметрах запроса, решает, какой обратный вызов вызвать.
Наконец, вклад модуля
public FacebookService buildFacebookService() { OAuthConfiguration configurer = new OAuthConfiguration("MY_API_KEY", "MY_API_SECRET", "http://localhost:9090/post.facebookconnect:authorize", "email,publish_stream"); return new FacebookServiceImpl(configurer, OAuthConstants.DEFAULT_FACEBOOK_API_PREFIX); }
Использование компонента на странице очень похоже на предыдущий
public class Post { @Inject private FacebookService facebookService; @SuppressWarnings("unused") @Property @Persist(PersistenceConstants.FLASH) private String message; void onConnectionEstablishedFromFacebookConnect(Token token, String verifier) { facebookService.send(new FacebookPost(token, "Hello from scribe-facebook at " + new Date())); message = "Posted"; } void onConnectionFailed(String error, String errorReason, String errorDescription){ message = "Failed"; } }
<html xmlns:t='http://tapestry.apache.org/schema/tapestry_5_1_0.xsd'> <body> ${message}<br/> <a href='#' t:id='facebookconnect' t:type='facebookConnect'>Facebook Connect</a> </body> </html>
От http://tawus.wordpress.com/2011/08/15/tapestry-facebook-integration/