Over a million developers have joined DZone.

Tapestry Facebook Integration

DZone's Guide to

Tapestry Facebook Integration

· Java Zone
Free Resource

Check out this 8-step guide to see how you can increase your productivity by skipping slow application redeploys and by implementing application profiling, as you code! Brought to you in partnership with ZeroTurnaround.

Continuing from the Tweeting post, lets us extend the OAuth Service to enable us to post on a user’s wall. As all the hard work has already been done, we just have to tweak things a little.

So here is the Facebook service

public interface FacebookService extends BaseOAuthService {

    void post(Token accessToken, String text);


public class FacebookServiceImpl extends BaseOAuthServiceImpl implements FacebookService {

    public FacebookServiceImpl(OAuthConfiguration configuration, String apiPrefix) {
        super(configuration, FacebookApi.class, apiPrefix);

    public void post(Token accessToken, String text) {
        send(new FacebookPost(accessToken, text));

    public Token newRequestToken() {
        return null; // Empty Token

    public Token requestAccessToken(String oAuthToken, String verifier) {
        return getOAuthService().getAccessToken(newRequestToken(), new Verifier(verifier));


Facebook does not need a request token, you just make a request with an empty token. The request is populated with your API key and secret but that is done by scribe-java, you don’t have to worry about that. Next is the OAuthResource for Facebook Post

public class FacebookPost extends AbstractOAuthResource {

    private String text;

    public FacebookPost(Token accessToken, String text) {
        super(accessToken, Verb.POST, "/me/feed/");
        this.text = text;

    public void initialize(OAuthRequest request){
        request.addBodyParameter("message", text);


This just means we have a resource at ‘/me/feed/’ which we can request through POST method and pass the text as message parameter.

Finally the component

public class FacebookConnect implements ClientElement {
    @Parameter(value = "prop:componentResources.id", defaultPrefix = BindingConstants.LITERAL)
    private String clientId;

    private String assignedClientId;

    private JavaScriptSupport javaScriptSupport;

    private ComponentResources resources;

    private FacebookService facebookService;

    void setupRender() {
        assignedClientId = javaScriptSupport.allocateClientId(clientId);

    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>


Here we are using another OAuthResource to get the users details.

public class FacebookVerifyCredentials extends AbstractOAuthResource {

    public FacebookVerifyCredentials(Token accessToken){
        super(accessToken, Verb.GET, "account/verify_credentials");


It is almost a copy of the TwitterConnect from the previous post. When the link is clicked, the event handler returns the authorization URL which redirects the browser to Facebook authorization. After Facebook has authorized, it redirects the browser to the callback URL(which is specified in the configuration) which is our onAuthorize() event handler. The event handler, based on the request parameters, decides which callback to call.

Finally the module contribution

public FacebookService buildFacebookService() {

        OAuthConfiguration configurer = new OAuthConfiguration("MY_API_KEY",
                "http://localhost:9090/post.facebookconnect:authorize", "email,publish_stream");

        return new FacebookServiceImpl(configurer, OAuthConstants.DEFAULT_FACEBOOK_API_PREFIX);

Using the component in a page is very similar to the previous one

public class Post {

    private FacebookService facebookService;

    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'>

      <a href='#' t:id='facebookconnect' t:type='facebookConnect'>Facebook Connect</a>



From http://tawus.wordpress.com/2011/08/15/tapestry-facebook-integration/

The Java Zone is brought to you in partnership with ZeroTurnaround. Check out this 8-step guide to see how you can increase your productivity by skipping slow application redeploys and by implementing application profiling, as you code!


Opinions expressed by DZone contributors are their own.

The best of DZone straight to your inbox.

Please provide a valid email address.

Thanks for subscribing!

Awesome! Check your inbox to verify your email so you can start receiving the latest in tech news and resources.

{{ parent.title || parent.header.title}}

{{ parent.tldr }}

{{ parent.urlSource.name }}