Connect Facebook em Java utilizando Google Gson e Apache Http Client

Como estou utilizando o meu Connect Facebook em um projeto Web utilizando o VRaptor como MVC, você encontrará a anotação @Component do VRaptor, mas nada impede que você utilize a mesma lógica em outros projetos Web ou Mobile.

Se você chegou nesse passo, é bem provável que você já tenha se cadastrado como desenvolvedor do Facebook pelo site: http://developers.facebook.com/

E também que já tenha inserido esse link do connect Facebook no HTML do seu site:

<a class="button facebook x18 center" href="https://www.facebook.com/login.php?api_key=1231545...

Caso você tenha alguma duvida nos passos de cadastro e na geração do link do Connect, é só postar a sua dúvida que responderei, e posso criar um POST sobre isso.

Vamos ao Java:

O callback do Facebook após o usuário digitar seus dados de acesso envia o code do Facebook por Query string para esse serviço do meu site: /auth/facebook/callback. No VRaptor tenho esse metodo Get no meu Controller:

@Get
@Path("/auth/facebook/callback")
public void facebookOauth(String code, String state) {
	UserFacebook userFacebook = userFacebookFactory.get(code);
	...
}

Vamos lá, a classe FacebookAuthUrl.java serve para gerar a url de solicitação de accessToken do Facebook. Essa URL é formada com seus dados de desenvolvedor do Facebook, no caso os dados da sua aplicação que são apiKey e secret, além disso precisaremos do code que você recebeu por Query string na sua url de callback do connect Facebook conforme falei no passo anterior. Essa URL serve para gerar um token de acesso que servirá para você solicitar os dados do usuário do Facebook, essa URL poderá ser consumida apenas uma vez, caso você tente acessá-la mais de uma vez o Facebook retornará uma exceção de autorização.

package br.com.denissys.social.facebook;

import br.com.caelum.vraptor.ioc.Component;

/**
 * @author Denis Santos
 */
@Component
public class FacebookAuthUrl {

	private static final String API_KEY = "100000"; // get this info on your developer facebook account

	private static final String SECRET = "xptoCode0123456"; // get info key on your developer facebook account

	private static final String URL_CALLBACK = "http%3A%2F%2Fwww.DOMINIO_DO_SEU_SITE.com.br%2Fauth%2Ffacebook%2Fcallback";

	private static final String REDIRECT_URI = "https://graph.facebook.com/oauth/access_token?"
			+ "client_id=" + API_KEY
			+ "&redirect_uri=https://graph.facebook.com/oauth/access_token?"
			+ "client_id=" + API_KEY
			+ "&redirect_uri=" + URL_CALLBACK
			+ "&client_secret=" + SECRET + "&code=";

	public String getUrl(final String authCode) {
		return REDIRECT_URI + authCode;
	}
	
}

Agora vamos para o próximo passo, que será fazer a chamada dessa url pelo framework Apache HTTP Client na classe FacebookAccessTokenFactory.java.

package br.com.denissys.social.facebook;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import org.apache.http.HttpResponse;
import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.impl.client.DefaultHttpClient;

import br.com.caelum.vraptor.ioc.Component;

/**
 * @author Denis Santos
 */
@Component
public class FacebookAccessTokenFactory {

	private FacebookAuthUrl facebookAuthUrl;

	public FacebookAccessTokenFactory(FacebookAuthUrl facebookAuthUrl) {
		this.facebookAuthUrl = facebookAuthUrl;
	}

	private static final int FB_ACCESS_TOKEN_PARAM = 2;

	public String get(final String code) throws ClientProtocolException, IOException {

		HttpGet getRequest = new HttpGet(facebookAuthUrl.getUrl(code));
		HttpResponse response = new DefaultHttpClient().execute(getRequest);
		BufferedReader reader = new BufferedReader(new InputStreamReader(response.getEntity().getContent()));

		Pattern pt = Pattern.compile("[\\?@begin@]([^&=]+)=([^&=]+)");
		Matcher params = pt.matcher("@begin@" + reader.readLine());

		String accessToken = "";
		if (params.find()) {
			accessToken = params.group(FB_ACCESS_TOKEN_PARAM).toString();
		}
		return accessToken;
	}

}

Como você pode ter percebido, até agora foi apenas um fluxo de autorizações do Facebook, é uma forma de controlar o acesso aos dados. O próximo passo será utilizar a classe UserFacebookFactory.java que retornará um usuário do Facebook representado pelo Bean UserFacebook.java. A nossa fábrica de usuários fará uso da API Rest oAuth do Facebook, faremos o uso do serviço “/me” para obter dados como nome, sobrenome, idade, localidade e sexo.

Veja esse trecho de código:

UserFacebook userFacebook = new Gson().fromJson(userFacebookJson, UserFacebook.class);


Aqui estou utilizando o framework Gson do Google, logo abaixo você encontrará o Bean UserFacebook.java, o que eu faço é mapear no Bean as propriedades do Json retornadas pelo Facebook, e o Gson faz a conversão do Json do Facebook para o nosso Bean.

Ou seja, um Json com o atributo user{“firstName”: “Denis”} será serializado para o objeto pela annotation @SerializedName(“firstName”).

package br.com.denissys.social.facebook;

import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.Reader;

import org.apache.http.HttpResponse;
import org.apache.http.HttpStatus;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.impl.client.DefaultHttpClient;

import br.com.caelum.vraptor.ioc.Component;

import com.google.gson.Gson;

/**
 * @author Denis Santos
 */
@Component
public class UserFacebookFactory {

	private static final String URL_USER_DATA = "https://graph.facebook.com/me?access_token=";

	private FacebookAccessTokenFactory facebookAccessTokenFactory;

	public UserFacebookFactory(
			FacebookAccessTokenFactory facebookAccessTokenFactory) {
		this.facebookAccessTokenFactory = facebookAccessTokenFactory;
	}

	public UserFacebook get(final String code) {

		final String accessToken = getAccessToken(code);

		Reader userFacebookJson = new InputStreamReader(getFacebookJson(URL_USER_DATA + facebookAccessTokenFactory.get(code)));
		UserFacebook userFacebook = new Gson().fromJson(userFacebookJson, UserFacebook.class);

		return userFacebook;
	}

	private InputStream getFacebookJson(final String url) {

		HttpGet getRequest = new HttpGet(url);

		try {
			HttpResponse getResponse = new DefaultHttpClient().execute(getRequest);

			if (getResponse.getStatusLine().getStatusCode() != HttpStatus.SC_OK) {
				return null;
			}
			return getResponse.getEntity().getContent();
		} catch (IOException e) {
			getRequest.abort();
		}
		return null;
	}

}

E aqui vai o nosso Bean que representa um usuário do Facebook

package br.com.denissys.social.facebook;

import java.io.Serializable;
import lombok.Getter;
import com.google.gson.annotations.SerializedName;

/**
 * @author Denis Santos
 */
public class UserFacebook implements Serializable {

	private static final long serialVersionUID = 1L;

	@Getter
	@SerializedName("id")
	private Long id;

	@Getter
	@SerializedName("name")
	private String name;

	@Getter
	@SerializedName("first_name")
	private String firstName;

	@Getter
	@SerializedName("last_name")
	private String lastName;

	@Getter
	@SerializedName("link")
	private String link;

	@Getter
	@SerializedName("username")
	private String username;

	// MM/DD/YYYY
	@Getter
	@SerializedName("birthday")
	private String birthday;

	@Getter
	@SerializedName("gender")
	private String gender;

	@Getter
	@SerializedName("email")
	private String email;

	@Getter
	@SerializedName("timezone")
	private Integer timezone;

	@Getter
	@SerializedName("locale")
	private String locale;

	@Getter
	@SerializedName("verified")
	private Boolean verified;

	// 2013-03-22T02:14:27+0000
	@Getter
	@SerializedName("updated_time")
	private String updatedTime;

}

Repare que não estou escrevendo os Getters (getIdI() … etc), estou usando um framework bem produtivo chamado Lombok, ele torna o seu código menos verboso, recomendo que você leia esse post da Caelum http://blog.caelum.com.br/java-menos-verboso-com-lombok/ para aprender a implementá-lo (é muito fácil e produtivo).

Marcado com: , , , , , , , , , , , ,
Publicado em API, Java

Deixe um comentário