Продолжая публикацию в Твиттере , мы расширяем службу 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/