Saturday, July 18, 2009

Ajax, Seam ve Facebook Connect

Facebook Connect mekanizmasini Java servis tarafi kodlarina baglama cabasinin iyilestirmeleri suruyor. Bir onceki yazida, Facebook FQL sorgusunu Javascript'e yaptirarak gelen verileri servis tarafina aktarmistik. Buradaki bir problem, Uzun suren Ajax cagrilarinin geri donuste problem yasamasi. Bu tur uzun sureli islem kodlarini servis tarafina gondermek daha iyi.

Ek olarak, simdiye kadar Javascript -> FB baglantisini kurmak icin kullanici UID (yani Facebook kullanici kimligi) Ajax ile set etmek bir cozum gorulebilirdi. Fakat bu cozum FB Connect kullanan uygulama acisindan guvenli bir cozum olmayacaktir - Facebook UID cok gizli bir bilgi degildir, 1'den baslayarak birer birer artan bir tam sayi sadece (kuruculari 1,2,3,4 diye kimlikler almislar mesela!), o zaman sadece Facebook tarafindan "uretilen", ve hem client hem servis tarafinda ayri ayri kontrol edilebilen, ve rutin olarak degisen bir kimlige ihtiyacimiz var.

Oturum kimligi (session id) bu isi basarabilir. Eger Facebook'a login edilmis haldeyseniz, ki degilseniz bir ziplama ekrani sonrasi login edilmis olursunuz, artik Facebook size bir session id uretebilir. Bu id Java servis kodlarina Ajax ya da form post uzerinden gonderilir, ve arka planda tekrar kontrol edilir. Bunun icin servis tarafinda FB cagrisi yapabilmek lazim tabii. Servis tarafi bunu yapiyorsa, User objesinin set edilmesi @Out ile de-enjente edilmesi, vs. gerceklestirilmis olur. O noktadan sonra isler tamamen Seam'in kontrolunde olacaktir.

Servis tarafinda Facebook baglantisi yapmak icin REST arayuzu var.

FB Session id almak icin Javascript kullanacagiz. Javascript illa ki biraz oluyor, cunku baska turlu FB ile ilk baglantiyi kurmak mumkun degil. Ama bu kod cok az olacak.

<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:fb="http://www.facebook.com/2008/fbml"
xmlns:ui="http://java.sun.com/jsf/facelets"
xmlns:c="http://java.sun.com/jstl/core"
xmlns:s="http://jboss.com/products/seam/taglib"
xmlns:f="http://java.sun.com/jsf/core"
xmlns:h="http://java.sun.com/jsf/html">

<head>
<script type="text/javascript" src="seam/resource/remoting/resource/remote.js"></script>
<script type="text/javascript" src="seam/resource/remoting/interface.js?userHandler"></script>
</head>

<script type="text/javascript">
FB_RequireFeatures(["XFBML"], function()
{
FB.Facebook.init("[API KEY BURAYA]",
"xd_receiver.htm");
});

function flogin() {
sessionKey = FB.Facebook.apiClient.get_session().session_key ;
Seam.Component.getInstance("userHandler").facebookLogin(sessionKey);
}
</script>

<body>
<h:form>
<a href="#" onclick="flogin()">Login</a>
</h:form>
</body>

</html>
Ustteki HTML gosterilip Login baglantisina tiklaninca userHandler objesi uzerinde facebookLogin cagrisi yapilacaktir. Servis tarafi kodlari soyle:
import javax.ejb.Local;
import org.jboss.seam.annotations.remoting.WebRemote;
import com.google.code.facebookapi.FacebookException;
@Local
public interface UserHandler {
@WebRemote
public void facebookLogin(String sessionKey) ;
}


import com.google.code.facebookapi.FacebookJsonRestClient;
import com.google.code.facebookapi.FacebookException;
import java.util.LinkedList;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
import org.w3c.dom.Document;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;

@Stateful
@Scope(SESSION)
@Name("userHandler")
public class UserHandlerBean implements UserHandler {

protected FacebookJsonRestClient _client;

public void facebookLogin(String sessionKey) {
try {
_client = new FacebookJsonRestClient("[APP KEY BURAYA]",
"[GIZLI APP KEY BURAYA]",
sessionKey);

Collection list = getFriendIds();
log.debug("list=" + list);
} catch (Exception e) {
Util.log(e);
}
}

public Collection getFriendIds() throws FacebookException, IOException {
Collection userIds = new LinkedList();

JSONArray friends = _client.friends_get();
if (friends == null || friends.length() == 0) {
return userIds;
}

for (int i = 0; i < friends.length(); i++) {
try {
userIds.add(friends.getString(i));
}
catch (JSONException e) {
log.debug("Can't fetch friend " + i + " from list");
throw new IOException("friend list can't be extracted");
}
}

return userIds;
}

Ustteki kodlar facebook-java-api kodlarina ihtiyac duyuyor. Kodlari indirip kurun. Ayrica MoochSpot sitesinin ornek kodlari java-api kodlarini sarmalayan yardimci bazi kodlar sunmakta.

Bu konu hakkinda ek yazilar gelebilir; Sonuc olarak bir kere java-api uzerinden baglanti kurulunca, _client uzerinden Facebook uid gibi bilgiler alinarak, Seam User objesini set etmek icin kullanilabilir.

No comments: