http://www.developer.com/

Back to article

Writing Facebook Applications Using Java EE


March 13, 2008

Introduction

Facebook is a popular social networking platform where people connect with family, friends, and like-minded individuals and engage in a variety of possible online activities. A large variety of these activities are made possible through so-called Facebook applications. These applications make use of the Facebook web services and APIs to integrate with the Facebook site, access the Facebook user's social information, and extend Facebook's social platform.

The Facebook Application Model

Facebook uses a proxy server model to allow web developers to integrate to its platform. With the proxy server model, Facebook can open its platform to developers through REST web services, and can provide APIs with high integrability to the Facebook look and feel, without needing to provide hosting services for each and every third-party application. Developers are also free to engineer their applications as they wish, choosing almost any technology they desire to write their app. This creates an even playing field for all developers, at least when it comes to development costs: Developers still need to deploy their apps in a way that can handle potentially millions of users per day. It is not uncommon for a popular Facebook app to grow to a million users within a single week.

The proxy model works like this:

  • Your Facebook application lives on your server; you register the base URL of your Facebook app with Facebook
  • When a user visits your application on Facebook, Facebook calls the corresponding URL on your server
  • Your app calls the Facebook API to get information about the user and their friends and to update the user's profile page
  • Your app uses information from its own database and session, and from the Facebook user data, and renders a page with the output from its action
  • In the case of a so-called FBML canvas page, Facebook turns FBML markup into HTML and Javascript
  • In the case of an iframe canvas page, Facebook wraps the output of your application in an HTML iframe
  • Facebook then returns your app's output to the user, wrapped in the Facebook navigation headers, footers and sidebars

First Steps

Writing Facebook applications using Java has proven difficult for many developers. The official Facebook Java libraries were often buggy and not updated as often as the official PHP libraries. To add insult to injury, nearly all official Facebook documentation and sample code (and a good deal of examples out on the blogosphere) are for PHP development. Luckily, a group of independent developers proceeded to implement their own improved and maintained clone of the Facebook API libraries for Java, removing one major obstacle for Java development. This article hopes to provide concise information about how to use these unofficial libraries to create a Facebook web application, and hopefully eliminate the last hurdle for Java developers.

Before beginning to write code, you must first sign up and log in to Facebook. Then, add the Facebook Developer Application to your user profile by visiting the following URL: http://www.facebook.com/developers/. The Facebook Developer Application is where developers request the API keys and the Facebook web address from which their application will be accessed. The Facebook Developer Application is also a public group where Facebook developers can help each other with the API and with proper use of the Facebook Developer App itself.

Figure 1: Facebook sign-up page

Figure 2: Facebok Developer Application at http://www.facebook.com/developers/

Once you have added the Facebook Developer Application, you can register your intended web application with Facebook. Don't worry that you don't have an application deployed yet; the information you will fill in is quite basic and will help organize how the app is developed. To begin, click the "Setup New Application" button on the Facebook Developer App page. This will open the "New Application" page on Facebook.

Figure 3: Facebok's "New Application" page

Follow these steps to fill out the "New Application" page with basic values:

  1. Fill the "Application Name." This is what you want your application to be known as among users. Facebook will use this name when reporting user activity with your app on users' "Mini Feed."
  2. Read the "Terms and Conditions" and check the checkbox if you agree with them.
  3. Click the link named "Optional Fields" to open the form up and show the other fields.

The next fields are optional for the simplest of Facebook apps, but for most types of applications, you want to fill out at least "Callback URL" and "Canvas Page URL" and leave the rest at their default values. Without those two fields filled, you can only create a so-called external Facebook app. External Facebook apps can only be accessed from a domain different from *.facebook.com, but the app can still access Facebook users' social network information through the API.

  1. In the two e-mail fields, you can enter your e-mail address, but they can be blank during development.
  2. The "Callback URL" field needs to be filled with the base path URL to your application on your development server. All application actions and pages are relative to this URL.
    • What you enter here is specific for your own setup, but to be clear, you should not put "http://localhost:8080/myfacebookapp". This needs to be an address that Facebook servers can reach through the Internet, not a local network address. This means that if you are following along from home, developing on your home computer, you need to find what your external IP address is, and open your application server's HTTP port in your firewall. This is fine for at-home development and experimentation with the API, but you will need to find a hosting solution for "going live" with your Facebook applications.
    • This URL needs to have a servlet or web framework action mapped to it, with the URL pattern set to the root of the web app ("/" or the slash.) We will do this for our example later on.
  3. The "Canvas Page URL" refers to the base path URL on the apps.facebook.com subdomain where users go to access your app. All application actions and pages are relative to this URL.
  4. For this introduction, you will choose FBML as your application's rendering method.
    • Whether you choose to have your application rendered as an FBML canvas or iframe canvas is a matter of whether you will be using a lot of JavaScript effects, Ajax or Flash in your application's user interface (iframes), or whether you want to follow the Facebook look and feel as closely as possible with minimal effort (FBML.)
    • JSF, Facelets, and Tapestry developers should select iframe rendering.
  5. Select no to indicate your application can be added on Facebook. Selecting "yes" would mean the app will show on your users' profiles, helping your app spread as other users see information about your app on their friends' profiles. This is great once you are live, but you will turn it off during development.
  6. You can leave the Terms of Service URL blank for now.
  7. If you are developing the app with the help of other Facebook users, you can add them to the "Developers" field.

Now that the fields have been filled as outlined above, you can click "Submit." Facebook Developer App will take your input and take you to a page listing the apps you have registered with Facebook. Below your application's name, you will see an API key and a secret key for your application. Make note of these hex strings; you need them later when calling into the Facebook API.

Figure 4: Facebok's Developer App, showing the newly created app's details (blacked in my example)

Preparing the Development Environment

Throughout the rest of the article, I will be using the Eclipse Web Tools Platform, Apache Tomcat 5.5 application server, and XDoclet 1.2.3. Setting up Eclipse and the Web Tools Platform plugin, XDoclet, and Tomcat is beyond the scope of this particular article. That said, if you have never used Eclipse before and want to work through this article with a minimum of fussing around with Eclipse, I recommend you download the EasyEclipse Server Java distribution of Eclipse and web development plugins, available at http://www.easyeclipse.org/site/distributions/server-java.html . You will still need to download and install Tomcat and XDoclet separately and set up Eclipse Web Tools Platform to work with them.

Once you have your development environment properly set up, create a new Dynamic Web Project called myfacebookapp by clicking the drop-down arrow next to the "New" button on the extreme left side of the Eclipse toolbar. Then, select "Project." When the "New Project" dialog box appears, select "Dynamic Web Project" from the "Web" project category. Then, click the "Next" button.

Figure 5: The "New" button pulldown menu, with "Project" selected

Figure 6: The "New Project" dialog box, with "Dynamic Web Project" selected

At the New Dynamic Web Project dialog box, fill in the project name as "myfacebookapp" and select your Java EE app server in the "Target Runtime" selection drop down, and "Dynamic Web Project with XDoclet" in the "Configurations" selection drop down. Then, click Finish.

Figure 7: The "New Dynamic Web Project" dialog box

Once you click Finish, Eclipse creates your Dynamic Web Project, and may ask whether you want to switch to the "J2EE Perspective." Once the project is created, you can see the myfacebookapp project in the "Project Explorer." Expand all of its folders to see the structure of your project.

Figure 8: The myfacebookapp project in the Project Explorer

Getting the Facebook Libraries

As mentioned at the beginning of this article, a group of independent Java developers have produced an unofficial but excellent set of Facebook libraries for Java development. Go to http://code.google.com/p/facebook-java-api/ to learn more about the project. These libraries need at least Java SE 5. They will not work with Java SE 1.4 or earlier.

You need to download the following JARs:

If you're running your Java app server on top of Java SE 5, download the following JARs as well:

You don't need the three JARs above if you're running on Java SE 6 or later.

Download the libraries and copy them to the myfacebookapp/WebContent/WEB-INF/lib folder on your disk. Once you copy the libraries to the folder, right-click the myfacebookapp project icon in the Eclipse Project Explorer and select "Refresh." Expand the "Web App Libraries" folder and Eclipse will show you the Facebook library jar files.

Figure 9: The myfacebookapp project with the Facebook Java libraries added

Once this is done, you finally can begin coding a basic Facebook app.

A Facebook App in Two Parts: A Servlet and a JSP

To keep things simple, this app does not use any hot web frameworks and cool design patterns. You will write a simple "Model 2" Java EE application, just a servlet and JSP page per action. If you know how to write Java web applications with Struts, Spring MVC, WebWork, Tapestry, etcetera, you will be able to take this code and apply it to your Java web framework of choice. You have to know how to walk before you can run, and you'll do the servlet and JSP walk this once.

Continuing with Eclipse, right-click the "myfacebookapp" folder, and select the "New" menu item. Out of the many choices, select "Servlet." In the "Create Servlet" dialog box, write org.myfacebookapp in the "Java package" field and AbstractFacebookServlet in the "Class name" field. Click "Finish" to continue.

Figure 10: Right-click the project folder and select New -> Servlet

Figure 11: The "Create Servlet" dialog box

Eclipse will create a package in the "Java Resources: src" folder inside the project folder, and in this package you will find AbstractFacebookServlet.java. Eclipse will open AbstractFacebookServlet.java for you. Replace all of the code in it with the following:

Listing 1.1: AbstractFacebookServlet.java

package org.myfacebookapp;

import java.io.IOException;

import java.util.*;

import javax.servlet.ServletException;
import javax.servlet.http.*;

import org.w3c.dom.Document;

import com.facebook.api.*;

/**
 * Servlet implementation class for Servlet:
 * AbstractFacebookServlet
 *
 */
public class AbstractFacebookServlet
      extends javax.servlet.http.HttpServlet
      implements javax.servlet.Servlet
{
   protected static final String FB_APP_URL =
      "http://apps.facebook.com/myfacebookapp/";

   protected static final String FB_APP_ADD_URL =
      "http://www.facebook.com/add.php?api_key=";

   protected static final String FB_API_KEY =
      "your-api-key-goes-here";

   private static final String FB_SECRET_KEY =
      "your-secret-key-goes-here";

   public AbstractFacebookServlet() {
      super();
   }

   /*
    * This method is used by all of the application's servlets
    * (or  web framework actions) to authenticate the app with
    * Facebook.
    */
   protected FacebookRestClient getAuthenticatedFacebookClient(
         HttpServletRequest request, HttpServletResponse response)
   {
      Facebook fb = new Facebook(request, response,
         FB_API_KEY, FB_SECRET_KEY);

      String next = request.getServletPath().substring(1);

      if (fb.requireLogin(next)) return null;

      return fb.getFacebookRestClient();
   }
}

The getAuthenticatedFacebookClient() method above needs to be called before making any calls to the Facebook API through the FacebookRestClient. You could put the FacebookRestClient in the session object with the idea of authenticating less often, but you will find in practice that your stored FacebookRestClient will lose authentication even though your app session hasn't yet expired. Authenticating every time doesn't use that much more bandwidth because you're going to be calling back through the API anyhow to get information to process your users' requests.

Before you continue, replace the FB_API_KEY and FB_SECRET_KEY constants with the correct settings from your registered Facebook application (the last step from the section "First Steps").

Now, create another servlet, called MainPageServlet.java. Once you have the MainPageServlet.java created, replace the package, import statements, comment block, and class definition with this block of code:

package org.myfacebookapp;

import java.io.IOException;

import javax.servlet.ServletException;
import javax.servlet.http.*;

import java.util.*;

import org.w3c.dom.Document;

import com.facebook.api.*;

/**
 * Servlet implementation class for Servlet: MainPageServlet
 *
 * @web.servlet
 *   name="MainPageServlet"
 *   display-name="MainPageServlet"
 *
 * @web.servlet-mapping
 *   url-pattern="/"
 *
 */
public class MainPageServlet extends AbstractFacebookServlet
      implements javax.servlet.Servlet {

Note that this servlet will extend from AbstractFacebookServlet, not from javax.servlet.http.HttpServlet. This will allow MainPageServlet to inherit getAuthenticatedFacebookClient(). The comment block is a set of XDoclet properties for servlet definitions in the web.xml document in the application's WEB-INF folder. This declares that MainPageServlet should be mapped to the root ("/" or the slash) of the web app's base URL.

Next, replace the MainPageServlet's doGet() and doPost() methods with the following code:

   protected void doGet(
         HttpServletRequest request,
            HttpServletResponse response)
         throws ServletException, IOException 
   {
      FacebookRestClient facebook =
         getAuthenticatedFacebookClient(request, response);

      if ( facebook != null) {
         if ( getFacebookInfo(request, facebook) ) {
            request.getRequestDispatcher(
               "/main_page.jsp").forward(request, response);
         }
      }
   }

   protected void doPost(
         HttpServletRequest request,
            HttpServletResponse response)
         throws ServletException, IOException
   {
      doGet(request, response);
   }

The MainPageServlet's doGet() method gets the authenticated FacebookRestClient immediately, and then calls a method called getFacebookInfo(), which you will define shortly. If getFacebookInfo() returns true, the code proceeds to redirect the server to "/main_page.jsp." You also will define this JSP page shortly.

Continue fleshing out MainPageServlet's code. Insert this getFacebookInfo() method right after the doPost() method.

   /*
    * This method obtains some basic Facebook profile
    * information from the logged in user who is
    * accessing our application in the current HTTP request.
    */
   private boolean getFacebookInfo(
         HttpServletRequest request,
         FacebookRestClient facebook) 
   {
      try {

         long userID = facebook.users_getLoggedInUser();
         Collection<Long> users = new ArrayList<Long>();
         users.add(userID);

         EnumSet<ProfileField> fields = EnumSet.of (
            com.facebook.api.ProfileField.NAME,
            com.facebook.api.ProfileField.PIC);

         Document d = facebook.users_getInfo(users, fields);
         String name = 
            d.getElementsByTagName("name").item(0).getTextContent();
         String picture = 
            d.getElementsByTagName("pic").item(0).getTextContent();

         request.setAttribute("uid", userID);
         request.setAttribute("profile_name", name);
         request.setAttribute("profile_picture_url", picture);

      } catch (FacebookException e) {

         HttpSession session = request.getSession();
         session.setAttribute("facebookSession", null);
         return false;

      } catch (IOException e) {

         e.printStackTrace();
         return false;
      }
      return true;
   }

This piece of code is where the meat of the Facebook action is for this example, so to speak. First, you get the user ID of the current logged-in user, and add this to a collection called users. Then, you define an emumeration set of Facebook API ProfileField types, com.facebook.api.ProfileField.NAME and com.facebook.api.ProfileField.PIC. You pass the users collection and the ProfileField enumeration set to a Facebook API called users_getInfo(). This returns an XML document with the profile name and profile image URL of the user IDs in the users collection—the current logged-in user. You parse out the <name> and <pic> elements out of the XML document, and store the user ID, profile name, and picture URL as request parameters. You do this to allow main_page.jsp to have access to this information as request scope beans.

Now, you get to the JSP part of the application. Create a JSP file called main_page.jsp, and insert in it the following code:

<%@ page language="java"
   contentType="text/html; charset=UTF-8"
   pageEncoding="UTF-8"
%>
<strong>myacebookapp Main Page</strong>

<div>
      <a href="http://www.facebook.com/profile.php?id=${uid}">
      <img src="${profile_picture_url}"><br>
   </a>
   <a href="http://www.facebook.com/profile.php?id=${uid}">
      ${profile_name}</a>,
   you are special because you are using myfacebookapp!
</div>

This JSP page is straightforward and simple. It uses JSP Expression Language to output the value of the request parameters "uid," "profile_name," and "profile_picture_url" you placed in the request in the getFacebookInfo() method from MainPageServlet.java. Using these values, it displays the users' name and profile picture, with links to their profile, and congratulates them for using "myfacebookapp."

Using Facebook Markup Language (FBML)

Using the Facebook API within your servlet or other Java web framework controllers and actions gives you plenty of power to create your web app. But, there is more to the Facebook API than calling web services to pull out user profile and friend information. With FBML, you can use a markup language created by Facebook to integrate more fully with their platform with a minimum of fuss. For example, replace the main_page.jsp with the following code.

<%@ page language="java"
   contentType="text/html; charset=UTF-8"
   pageEncoding="UTF-8"
%>
<strong>myacebookapp Main Page</strong>

<div>
   <fb:profile-pic uid="loggedinuser"
                   size="small"
                   linked="true" /><br>
   <fb:name uid="loggedinuser"
            useyou="false"
            linked="true"
            capitalize="true" />,
   you are special because you are using myfacebookapp!
</div>

If you call main_page.jsp directly from your Facebook app's URL (for example, http://apps.facebook.com/myfbapp/main_page.jsp), you will see that these FBML tags produce the same output as the previous servlet and JSP EL example. Please also note that calling the JSP page directly means it didn't need to call getAuthenticatedFacebookClient() to authenticate with Facebook. These <fb:> tags aren't JSTL tags. The FBML parsing occurs on Facebook's servers, where the user has already logged in (otherwise, they couldn't access your application on Facebook's URL). Facebook also has ready access to the logged in user's profile information.

Besides FBML, there are also FBJs for Ajax-like effects, and FBQL for querying user information in a SQL-like fashion, all within pages with <fb:> tags. Combine FBML, FBJs, and FBQL with a powerful Java MVC framework, and you can create complex apps that integrate cleanly with the Facebook UI.

Conclusion

The Facebook social network is amazingly popular. To a great extent, the popularity of the service is a reflection of the popularity of the many applications created with the Facebook platform and its APIs. With improved libraries and example code, Java developers can hit the ground running and create more applications, to grow and extend the Facebook platform's reach with new ideas and social services.

Resources

About the Author

PJ Cabrera is a freelance software developer specializing in Ruby on Rails e-commerce and content management systems development. PJ's interests include Ruby on Rails and open-source scripting languages and frameworks, agile development practices, mesh networks, compute clouds, XML parsing and processing technologies, microformats for more semantic web content, and research into innovative uses of Bayesian filtering and symbolic processing for improved information retrieval, question answering, text categorization, and extraction. You can reach him at pjcabrera at pobox dot com, and read his weblog at pjtrix.com/blawg/.

Sitemap | Contact Us

Thanks for your registration, follow us on our social networks to keep up-to-date