其實我剛剛得到這個工作在我的JSP的項目!好的這是你需要知道的。你正在嘗試的方法被稱爲「服務器端」方法(也有一個客戶端方法,它可以共享很多相同的代碼,有兩個URL將被使用(我已經將這一切都包裝到了一個幫助程序中歸我叫FacebookConfig讀取它從一個facebook.properties文件需要:
import java.io.IOException;
import java.io.InputStream;
import java.util.Properties;
import lombok.Cleanup;
import st.fan.model.users.Listener;
public class FacebookConfig {
public static String auth_uri;
public static String id;
public static String key;
static{
Properties properties = new Properties();
try {
@Cleanup InputStream in = Thread.currentThread().getContextClassLoader().getResourceAsStream("facebook.properties");
properties.load(in);
auth_uri = (String)properties.get("auth_uri");
id = (String)properties.get("id");
key = (String)properties.get("key");
} catch (IOException e) {
e.printStackTrace();
}
}
public static String getOAuthDialogUrl() {
return "https://www.facebook.com/dialog/oauth?client_id="+id+"&redirect_uri="+auth_uri+"&scope=email";
}
public static String getOAuthUrl(String code) {
return "https://graph.facebook.com/oauth/access_token?client_id="+id+"&redirect_uri="+auth_uri+"&client_secret="+key+"&code="+code;
}
public static String getGraphUrl(String token) {
return "https://graph.facebook.com/me?access_token="+token;
}
public static String getProfilePictureUrl(Listener profile) {
return "https://graph.facebook.com/"+profile.getFacebookId()+"/picture";
}
public static String getProfilePictureUrl(Listener profile, String size) {
return "https://graph.facebook.com/"+profile.getFacebookId()+"/picture?type="+size;
}
}
現在,用戶被重定向到包含一個名爲http://example.com/auth/facebook/Auth的servlet具有這種的doGet的URL getOAuthDialogUrl()()方法
public void doGet(HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException {
Transaction tx = null;
Session dao = SessionFactoryUtil.getInstance().getCurrentSession();
String redirect = "/auth/facebook/sorry";
try {
String code = request.getParameter("code");
if(code != null) {
String[] pairs = NetUtils.fetch(new URL(FacebookConfig.getOAuthUrl(code))).toString().split("&");
String accessToken = null;
Integer expires = null;
for (String pair : pairs) {
String[] kv = pair.split("=");
if (kv.length == 2) {
if (kv[0].equals("access_token")) {
accessToken = kv[1];
}
if (kv[0].equals("expires")) {
expires = Integer.valueOf(kv[1]);
}
}
}
if(accessToken != null && expires != null) {
try {
JSONObject fb_profile = new JSONObject(NetUtils.fetch(new URL(FacebookConfig.getGraphUrl(accessToken))));
tx = dao.beginTransaction();
ListenerSession session = authenticate(request, dao);
if(session == null) {
session = createSession(response, dao);
}
String facebookid = fb_profile.getString("id");
String name = fb_profile.getString("name");
String email = fb_profile.getString("email");
String username = facebookid;
if(fb_profile.has("username")) {
username = fb_profile.getString("username");
}
Listener user = ListenerDAO.findByFacebookId(facebookid, dao);
if(user != null) {
user.setDisplayName(name);
user.setEmail(email);
dao.save(user);
} else {
user = new Listener();
user.setUsername(username);
user.setDisplayName(name);
user.setEmail(email);
user.setDateCreated(new DateTime());
user.setFacebookId(facebookid);
user.setStatus(ListenerStatus.ACTIVE);
dao.save(user);
}
ListenerSessionDAO.link(session, user, dao);
redirect = "/";
tx.commit();
} catch (JSONException e) {
log.error("Parsing Facebook Graph Response", e);
}
} else {
log.error("Expected values not found!");
log.error("accessToken="+accessToken);
log.error("expires="+expires);
}
} else {
log.error("Missing 'code' param!");
}
} catch(Exception e) {
e.printStackTrace(System.out);
} finally {
if(dao.isOpen()) {
dao.close();
}
}
response.sendRedirect(redirect);
}
而且(除了使用Hibernate,龍目島項目和一個簡單的JSON庫調用org.json )我使用一個稱爲一個簡單的輔助函數取(),接受一個URL,並返回內容爲具有該代碼的字符串:
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.URL;
import java.net.URLConnection;
public class NetUtils {
public static String fetch(URL url) throws IOException {
URLConnection connection = url.openConnection();
String line;
StringBuilder builder = new StringBuilder();
BufferedReader reader = new BufferedReader(new InputStreamReader(connection.getInputStream()));
while((line = reader.readLine()) != null) {
builder.append(line);
}
return builder.toString();
}
}
這應該讓你離開地面:)
好的。我使用了response_type = code。並且我得到了代碼作爲請求參數。現在如何獲得令牌? – Piscean
http://pinoyphp.blogspot.com/2010/12/oath-tutorial-how-to-get-facebook.html我發現這個教程,但我有點困惑。我得到的代碼,但那我怎麼得到access_token。如果我嘗試將它重定向到其他一些servlet,那麼它會給出錯誤。這意味着request_uri應該與獲取代碼和access_token相同。怎麼可能?它將像對同一頁面的無限呼叫一樣。不是嗎? – Piscean