Here is complete code for making a facebook app in wicket. The code just lists all the user's friends.
Note: I'm not using the FaceBook client that comes from the FaceBook website. I'm using a version from this website: http://code.google.com/p/facebook-java-api/
This is the application class itself:
Code Block |
---|
import com.facebook.api.FacebookRestClient; import org.apache.wicket.*; import org.apache.wicket.authorization.IUnauthorizedComponentInstantiationListener; import org.apache.wicket.authorization.UnauthorizedInstantiationException; import org.apache.wicket.authorization.strategies.page.AbstractPageAuthorizationStrategy; import org.apache.wicket.protocol.http.WebApplication; import org.apache.wicket.request.target.basic.RedirectRequestTarget; import javax.security.auth.login.FailedLoginException; public class FaceBookApp extends WebApplication implements IUnauthorizedComponentInstantiationListener { public static final String CLIENT = "auth.client"; private String _apiKey = "put your own key here"; //replace this private String _secretKey = "put your own key here"; //replace this protected void init() { super.init(); getSecuritySettings().setAuthorizationStrategy(new FaceBookAuthorizationStrategy()); getSecuritySettings().setUnauthorizedComponentInstantiationListener(this); } public Class getHomePage() { return Login.class; } public void onUnauthorizedInstantiation(Component component) { if (component instanceof Page) { Page page = (Page) component; if (((FaceBookSession) page.getSession()).getClient() != null) { return; } FaceBookSession session = (FaceBookSession) page.getSession(); try { FacebookRestClient authClient = FaceBookAuthHandler.getAuthenticatedClient(page.getRequest(), _apiKey, _secretKey); session.setClient(authClient); } catch (FailedLoginException fle) { //user not logged in forceLogin(page); } catch (Exception e) { e.printStackTrace(); } } else { throw new UnauthorizedInstantiationException(component.getClass()); } } private void forceLogin(Page page) { page.getRequestCycle().setRequestTarget(new RedirectRequestTarget("http://www.facebook.com/login.php?api_key=" + _apiKey + "&v=1.0")); } public Session newSession(Request request, Response response) { return new FaceBookSession(request); } private static class FaceBookAuthorizationStrategy extends AbstractPageAuthorizationStrategy { protected boolean isPageAuthorized(final Class pageClass) { return false; } } } |
This is the FaceBookAuthHandler:
Code Block |
---|
import com.facebook.api.FacebookParam; import com.facebook.api.FacebookRestClient; import org.apache.wicket.Request; import javax.security.auth.login.FailedLoginException; public class FaceBookAuthHandler { public static FacebookRestClient getAuthenticatedClient(Request request, String apiKey, String secretKey) throws Exception { String authToken = request.getParameter("auth_token"); String sessionKey = request.getParameter(FacebookParam.SESSION_KEY.toString()); FacebookRestClient fbClient = null; if (sessionKey != null) { fbClient = new FacebookRestClient(apiKey, secretKey, sessionKey); } else if (authToken != null) { fbClient = new FacebookRestClient(apiKey, secretKey); //establish session fbClient.auth_getSession(authToken); } else { throw new FailedLoginException("Session key not found"); } fbClient.setIsDesktop(false); return fbClient; } } |
This is the custom session object:
Code Block |
---|
import com.facebook.api.FacebookRestClient; import org.apache.wicket.Request; import org.apache.wicket.protocol.http.WebSession; public class FaceBookSession extends WebSession { private FacebookRestClient client; public FaceBookSession(Request request) { super(request); } public synchronized FacebookRestClient getClient() { return client; } public synchronized void setClient(FacebookRestClient client) { this.client = client; } } |
This is the wicket template:
Code Block | ||||
---|---|---|---|---|
| ||||
<html> <body> <div wicket:id="friends"><span wicket:id="friend">friend</span></div> </body> </html> |
This is the Wicket page (the facebook callback URL):
Code Block |
---|
import com.facebook.api.FacebookException; import com.facebook.api.FacebookRestClient; import com.facebook.api.schema.FriendsGetResponse; import org.apache.wicket.markup.html.WebPage; import org.apache.wicket.markup.html.basic.Label; import org.apache.wicket.markup.html.list.ListItem; import org.apache.wicket.markup.html.list.ListView; import java.io.IOException; import java.util.List; public class Login extends WebPage { public Login() { try { FacebookRestClient client = ((FaceBookSession) getSession()).getClient(); client.friends_get(); FriendsGetResponse fbResponse = (FriendsGetResponse) client.getResponsePOJO(); List<Long> friends = fbResponse.getUid(); add(new ListView("friends", friends) { protected void populateItem(ListItem listItem) { listItem.add(new Label("friend", listItem.getModelObjectAsString())); } }); } catch (FacebookException e) { throw new RuntimeException(e); } catch (IOException e) { throw new RuntimeException(e); } } } |
Unregistered Application to Facebook User Problem
If your facebook profile is not associated with the application then client.friends_get() in the Login page will throw a NullPointerException.
This occurs because although the onUnauthorizedInstantiation method defined in the application class forces the login to occur in this case for some reason the Login page constructor is still called before the redirect takes place.
An ugly hack to make the demo work in this case is to add a test before client.friends_get() like:
Code Block |
---|
if (client == null) { WebMarkupContainer friends = new WebMarkupContainer("friends"); friends.add(new Label("friend", "missing frields")); } else { client.friends_get(); FriendsGetResponse fbResponse = (FriendsGetResponse) client.getResponsePOJO(); List<Long> friends = fbResponse.getUid(); add(new ListView("friends", friends) { protected void populateItem(ListItem listItem) { listItem.add(new Label("friend", listItem.getModelObjectAsString())); } }); } |
Or, you can force Wicket to redirect to Facebook login page immediately - just change the forceLogin method:
Code Block |
---|
private void forceLogin(Page page) { throw new RedirectToUrlException("http://www.facebook.com/login.php?api_key=" + _apiKey + "&v=1.0"); } |