Bắt đầu thành lập vào tháng 2/2004, Facebook là mạng xã hội lớn nhất thế giới, với hơn 900 triệu người dùng đang sử dụng trang này để chia sẻ nội dung với bạn bè của họ. Facebook Platform (Nền tảng Facebook), phát hành vào tháng 5/2007, cho phép các bên thứ ba viết các ứng dụng tích hợp với Facebook. Nền tảng này ban đầu đã hỗ trợ một loạt các ngôn ngữ lập trình — gồm cả Java — nhưng bây giờ nó chỉ cung cấp các bộ SDK (Bộ công cụ cho nhà phát triển phần mềm) nguyên gốc dành cho JavaScript và PHP (cũng như hỗ trợ cho các ứng dụng trên các thiết bị iOS và Android). Tuy nhiên, dự án mã nguồn mở RestFB vẫn đang duy trì Java API (API của Java) kể từ khi Facebook ngừng sử dụng nó (xem phần Tài nguyên).
Google App Engine (GAE) là một Nền tảng Dịch vụ (PaaS) cho phép các nhà phát triển đăng ký để chạy các ứng dụng mà họ viết bằng Python, Java hoặc Go trên cơ sở hạ tầng của Google. Bài này cho bạn thấy cách đăng ký một ứng dụng Facebook, phát triển nó bằng Java và triển khai nó miễn phí trên GAE để sử dụng với bất kỳ người dùng Facebook nào. (Lưu ý rằng Google giới hạn phần tài nguyên hàng ngày mà mỗi ứng dụng được triển khai trên GAE có thể sử dụng).
Ứng dụng đơn giản mà bạn sẽ tạo ra liệt kê tất cả các bạn bè của người dùng với ID và ảnh đại diện của họ — tương tự như trang Thông tin bạn bè (Friends page) trong mục Hồ sơ (Profile) trên Facebook. Để phát triển ứng dụng này, bạn cần:
- Một tài khoản Facebook.
- Một tài khoản Google.
- IDE Eclipse với trình cắm thêm (plug-in) GAE đã cài đặt (xem phần Tài nguyên)
- Hiểu rõ cách sử dụng Eclipse.
Bạn có thể tải về mã nguồn của ứng dụng mẫu này tại đây.
Đầu tiên cần đăng ký thông tin ứng dụng trên Facebook và GAE. Tốt nhất là bạn nên sử dụng thông tin giống nhau khi đăng ký ở cả hai nơi để bảo đảm rằng sau này, thông tin mà bạn nhập vào trùng khớp khi cần.
Đăng nhập vào Facebook và khởi chạy ứng dụng của nhà phát triển tại https://developers.Facebook.com/apps. (Nếu bạn đang khởi chạy lần đầu tiên, bạn phải cấp quyền truy cập ứng dụng cho lược tả của mình để tiếp tục chạy).
Nhấn Create New App (Tạo ứng dụng mới) ở phía trên bên phải của trang Apps để hiển thị hộp thoại Create New App, như trong Hình 1:
Hình 1. Hộp thoại Create New App của Facebook
Nhập vào một tên hợp lệ và một vùng tên (namespace) có sẵn cho ứng dụng. Vùng tên là một mã
định danh chỉ có một từ duy nhất được sử dụng trong một URL của ứng dụng Facebook. (Trong Hình 1, tôi đã nhập My Old Friends làm tên ứng
dụng và myoldfriends làm vùng tên). Bỏ dấu chọn ở tùy chọn lưu
trữ trên máy chủ (host) miễn phí được cung cấp bởi Heroku và nhấn Continue.
Nhập mã CAPTCHA ở hộp thoại tiếp theo và nhấn Submit để mở ra hộp thoại
thiết lập cho ứng dụng mới của bạn, như trong Hình 2:
Hình 2. Hộp thoại các thiết lập cơ bản của ứng dụng Facebook
Lưu ý các khóa App ID và App Secret ở phía trên của màn hình (đã được làm ẩn đi trong Hình 2). Facebook sử dụng chúng để nhận biết ứng dụng của bạn. Hãy giữ chúng bí mật và không cho phép các nhà phát triển khác sử dụng chúng, vì người ta có thể sử dụng chúng một cách ác ý không theo hiểu biết của bạn.
Nhập một tên miền ứng dụng vào trường App Domains. Đây phải là tên miền GAE
mà bạn sẽ đăng ký cho ứng dụng này trên trang web nhà phát triển GAE, vì vậy nó phải kết
thúc bằng .appspot.com. Ví dụ, trong Hình 2,
tôi đã nhập myoldfacebookfriends.appspot.com. Vì tên miền này đã
dùng rồi, nên bạn sẽ phải sử dụng một một tên miền khác. Chỉ cần chắc chắn rằng nó phù hợp
với mã định danh ứng dụng mà bạn sử dụng khi bạn đăng ký ứng dụng
GAE.
Trong Select how your app integrates with Facebook (Chọn cách ứng dụng của bạn tích hợp với
Facebook), hãy chọn Website with Facebook Login (Trang Web có đăng nhập
Facebook) và nhập vào URL của trang web có tên miền GAE mà bạn đã nhập trong trường
App Domains, cần có http:// ở đầu. (Trong Hình 2, tôi đã nhập http://myoldfacebookfriends.appspot.com.)
Chọn App on Facebook (Ứng dụng trên Facebook) và nhập canvas URL cho một
servlet mà ứng dụng sẽ chạy trong đó. Với ứng dụng này, canvas URL kết thúc bằng một dấu
chấm hỏi để cho biết rằng các tham số cho ứng dụng này sẽ được chuyển giao qua URL yêu cầu
được gửi tới ứng dụng. Secure canvas URL (URL của khung nền ảnh bảo mật) giống như canvas
URL, trừ việc sử dụng https thay cho http. Một lần nữa, dấu hỏi ở cuối URL là quan trọng. (URL cho servlet của ứng dụng
của tôi là http://myoldfacebookfriends.appspot.com/myoldfacebookfriends, do đó, trong Hình 2, tôi đã nhập http://myoldfacebookfriends.appspot.com/myoldfacebookfriends? cho canvas URL và
https://myoldfacebookfriends.appspot.com/myoldfacebookfriends?
cho secure canvas URL).
Đây là tất cả những gì bạn cần làm để thiết lập một ứng dụng trên Facebook, nhưng tốt nhất là nên cấu hình các thiết lập theo cách của bạn, chẳng hạn như biểu tượng của ứng dụng, thể loại của nó, để đổi mới cách trình bày ứng dụng cho người dùng.
Bây giờ, với ứng dụng đã đăng ký với Facebook, tiếp theo bạn sẽ đăng ký nó với GAE.
Đăng nhập vào trang các ứng dụng trên GAE — https://appengine.google.com/ — và nhấn Create Application. Trong Application Identifier (Mã định danh ứng dụng), nhập tên miền ứng dụng giống như tên miền bạn đã sử dụng trong các giá trị thiết lập cơ bản của ứng dụng Facebook. (Phần appspot.com sẽ được cung cấp cho bạn). Bạn có thể đặt tiêu đề ứng dụng tùy ý, tiêu đề này được dùng trong quá trình tìm kiếm. Giữ nguyên các thiết lập mặc định còn lại.
Hình 3. Tạo một hộp thoại ứng dụng cho GAE
Nhấn vào Create Application để kết thúc quá trình đăng ký GAE.
Trong Eclipse, hãy tạo một dự án GAE mới bằng cách nhấn vào nút ấnFile > New > Web Application Project hoặc nhấn nút ấn New Web Application Project trong trình đơn Google Services and Deployment Tools (Các công cụ triển khai và các dịch vụ Google). Nhập vào tên project và package. Bỏ dấu chọn Use Google Web Toolkit. Tải về tệp JAR của RestFB (xem phần Tài nguyên) và thêm nó vào thư mục WEB-INF/lib của dự án (project).
Thêm định nghĩa servlet cho ứng dụng này vào tệp web.xml của dự án. Liệt kê 1 cho thấy định nghĩa mà tôi đã sử dụng:
Liệt kê 1. Định nghĩa servlet
<?xml version="1.0" encoding="utf-8"?> <web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://java.sun.com/xml/ns/javaee" xmlns:web="http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" version="2.5"> <servlet> <servlet-name>myoldFacebookfriendsServlet</servlet-name> <servlet-class>com.Facebook.friends.MyOldFacebookFriendsServlet</servlet-class> </servlet> <servlet-mapping> <servlet-name>myoldFacebookfriendsServlet</servlet-name> <url-pattern>/myoldFacebookfriends</url-pattern> </servlet-mapping> </web-app> |
Lưu ý rằng <url-pattern> cũng giống như canvas URL trong hộp
thoại các giá trị thiết lập cơ bản của ứng dụng Facebook, nhưng không có dấu chấm hỏi.
Kể từ tháng 10 năm 2011, các ứng dụng Facebook yêu cầu kích hoạt Secure Sockets Layer (SSL); mặc định trên GAE thì tính năng này bị vô hiệu hóa. Để mở nó, hãy thêm dòng appengine-web.xml sau:
<ssl-enabled>true</ssl-enabled> |
Yêu cầu chứng thực của Facebook
Khi sử dụng phương thức POST của HTTP, Facebook sẽ gửi một yêu cầu
đã chứng thực tới servlet của ứng dụng để tạo ra nội dung của ứng dụng. Yêu cầu này chứa một
dải tin được mã hóa 64-bit có chứa thẻ xác thực OAuth với ứng dụng này cho người dùng hiện
tại, trong số các siêu dữ liệu khác. Thẻ này được đưa vào dải tin của yêu cầu đó chỉ khi
người dùng cho phép truy cập thông tin của họ. Bạn cần chuyển đổi nó thành đối tượng Java để
ứng dụng có thể sử dụng nó.
Liệt kê 2 cho thấy mã nguồn cho đối tượng Java của yêu cầu đã chứng thực. Tôi đã bỏ qua tất cả các phương thức get và set thích hợp để cho rõ ràng; đoạn mã này cũng chứa trong phần mã nguồn (xem phần Tải về).
Liệt kê 2. Đối tượng yêu cầu-đã ký
import org.apache.commons.codec.binary.Base64;
import org.codehaus.jackson.map.ObjectMapper;
public class FacebookSignedRequest {
private String algorithm;
private Long expires;
private Long issued_at;
private String oauth_token;
private Long user_id;
private FacebookSignedRequestUser user;
public static class FacebookSignedRequestUser {
private String country;
private String locale;
private FacebookSignedRequestUserAge age;
public static class FacebookSignedRequestUserAge {
private int min;
private int max;
}
}
}
|
Bạn có thể giải mã dải tin này bằng Base64 trong thư viện Apache Commons Codec (Mã hóa và
giải mã dữ liệu được chia sẻ chung của Apache). Dải tin được giải mã nằm trong JavaScript
Object Notation (JSON) và có thể được biến đổi thành một đối tượng Java khi sử dụng bộ vi xử
lý JSON của Jackson. Hãy tải về các tệp JAR của chúng và thêm chúng vào dự án (xem phần Tài nguyên). Thêm phương thức tĩnh helper (trình trợ giúp) được hiển
thị trong Liệt kê 3 vào lớp FacebookSignedRequest để tạo ra đối
tượng này:
Liệt kê 3. Phương thức helper để mã hóa và giải mã tải tin
public static FacebookSignedRequest getSignedRequest(String signedRequest)
throws Exception {
String payload = signedRequest.split("[.]", 2)[1];
payload = payload.replace("-", "+").replace("_", "/").trim();
String jsonString = new String(Base64.decodeBase64(payload.getBytes()));
return new ObjectMapper().readValue(jsonString,
FacebookSignedRequest.class);
}
|
Bây giờ bạn có thể bắt đầu phát triển ứng dụng sẽ chạy trong servlet. Hãy tạo một lớp mới có
chữ ký giống như định nghĩa <servlet-class> trong web.xml.
Trước tiên, bạn cần trích ra thẻ xác thực OAuth từ dải tin này, bằng cách sử dụng lớp SignedRequest, như trong Liệt kê 4:
Liệt kê 4. Trích ra thẻ xác thực OAuth
String signedRequest = (String) request.getParameter("signed_request");
FacebookSignedRequest FacebookSR = null;
try {
FacebookSR = FacebookSignedRequest.getSignedRequest(signedRequest);
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
String oauthToken = FacebookSR.getOauth_token(); |
Nếu đối tượng oauthToken là null, thì người dùng không được cấp
quyền truy cập vào ứng dụng và phải được chuyển hướng đến URL xác thực. URL này, là tiêu
chuẩn cho tất cả các ứng dụng, theo định dạng sau:
https://www.Facebook.com/dialog/oauth?client_id=API
KEY&redirect_uri=
https://apps.Facebook.com/Application
Namespace/&scope=Permissions |
API KEY và Application
Namespace trong URL xác thực là những thứ được hiển thị trong hộp thoại các
giá trị thiết lập cơ bản của Facebook cho ứng dụng. Permissions là danh sách các các quyền hạn cần thiết cho ứng dụng của
bạn. Tất cả các ứng dụng có quyền truy cập cơ bản theo mặc định và bạn không cần phải thêm
bất kỳ các quyền hạn nào khác với mục đích của bài này. (Xem phần Tài
nguyên để biết một liên kết đến danh sách đầy đủ về quyền hạn có sẵn).
Bạn có thể tùy chỉnh dáng vẻ và cảm nhận của trang này trong trang Settings > Auth
Dialog (Các giá trị thiết lập > Hộp thoại xác thực) của ứng dụng nhà phát triển Facebook.
Thông thường, bạn sẽ sử dụng phương thức HttpServletRequest.sendRedirect() của servlet, nhưng do ứng dụng sẽ chạy trong một
<iframe> trên tên miền apps.Facebook.com, nên một đoạn mã
JavaScript ngắn, được hiển thị trong Liệt kê 5, sẽ thay đổi vị trí của cửa sổ trình duyệt
sang URL ứng dụng:
Liệt kê 5. Mã JavaScript chuyển hướng sang URL ứng dụng
PrintWriter writer = response.getWriter();
if(oauthToken == null) {
response.setContentType("text/html");
String authURL = "https://www.Facebook.com/dialog/oauth?client_id="
+ API_KEY
+ "&redirect_uri=https://apps.Facebook.com/myoldfriends/&scope=";
writer.print("<script> top.location.href='" + authURL + "'</script>");
writer.close();
} |
Với một thẻ xác thực OAuth hợp lệ, bạn có thể tạo ra một DefaultFacebookClient từ thư viện RestFB và sử dụng nó để lấy ra dữ liệu từ Graph
API của Facebook khi gọi hàm fetchConnection(). Truy cập Graph
Explorer (Trình thám hiểm Đồ thị) trên Facebook tại địa chỉ
https://developers.Facebook.com/tools/explorer. Chọn ứng dụng mà bạn đang phát triển từ hộp
thả xuống ở phía trên bên phải và nhấn vào Get access token (Lấy thẻ xác
thực truy cập) để cấp quyền truy cập. Nhấn vào các liên kết khác nhau trong tiêu đề
Connections (Các kết nối) để xem kết quả.
Để nhận được danh sách bạn bè, hãy nhấn vào liên kết friends và xem các kết
quả. Lưu ý rằng giá trị của URL trong trình thám hiểm explorer là user id/friends. Tham số kết nối trong cuộc gọi hàm thường sử dụng giá
trị giống như trong Graph Explorer. Nhưng vì ứng dụng sử dụng dữ liệu của người dùng đã đăng
nhập, nên bạn có thể thay thế ID người dùng bằng me, tạo nên giá
trị là me/friends. Bước gọi này trả về kiểu Connection thô và vì kiểu lớp là User, nên bạn cần thêm
nó vào như một tham số. Bước gọi cuối cùng là:
Connection<User> myFriends = FacebookClient.fetchConnection("me/friends", User.class); |
Kết quả của việc gọi phương thức fetchConnection() được chứa trong
một List các đối tượng List trong lớp
Connection. Lớp Connection thực hiện
giao diện Iterable (có thể lặp lại), vì vậy bạn có thể thu được
từng đối tượng List trong List bằng
cách sử dụng vòng lặp for:
for (List<User> myFriendsList : myFriends) |
Dựa vào mỗi lần lặp của vòng lặp, đối tượng myFriendsList chứa danh
sách người dùng hiện tại với trang dữ liệu được trả về đó. Mỗi đối tượng User trong danh sách này được sử dụng để tạo ra một hàng trong bảng người dùng
(table of users) mà servlet sẽ tạo ra. Mặc dù ID và tên người dùng có thể được lấy ra từ đối
tượng User, nhưng không thể lấy được ảnh đại diện. Tuy nhiên,
Facebook cung cấp một URL để lấy về ảnh đại diện của bất kỳ người dùng nào:
https://graph.facebook.com/User ID/picture. Như vậy, URL của ảnh đại diện được
tạo ra bằng cách thay User ID trong URL bằng user ID của đối tượng User. Khi sử dụng đối tượng PrintWriter
giống như trước, hãy viết một bảng có một hàng tiêu đề cho khung nền ảnh:
writer.print("<table><tr><th>Photo</th><th>Name</th><th>Id</th></tr>"); |
Hãy lặp lại qua danh sách các đối tượng User, như vừa được mô
tả, sau đó viết một hàng mới cho bảng này, bằng cách sử dụng các biến cá thể của từng đối
tượng User:
for (List<User> myFriendsList : myFriends) {
for(User user: myFriendsList)
writer.print("<tr><td>" +
"<img src=\"https://graph.facebook.com/" + user.getId() + "/picture\"/>" +
"</td><td>" + user.getName() +"</td><td>" + user.getId() + "</td></tr>");
}
|
Cuối cùng, hãy đóng thẻ <table> và đóng đối tượng PrintWriter để hoàn thành servlet này:
writer.print("</table>");
writer.close();
|
Liệt kê 7 hiển thị phương thức servlet doPost():
Liệt kê 7. Phương thức
doPost()
public void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
String signedRequest = (String) request.getParameter("signed_request");
FacebookSignedRequest facebookSR = null;
try {
facebookSR = FacebookSignedRequest.getSignedRequest(signedRequest);
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
String oauthToken = facebookSR.getOauth_token();
PrintWriter writer = response.getWriter();
if(oauthToken == null) {
response.setContentType("text/html");
String authURL = "https://www.facebook.com/dialog/oauth?client_id="
+ Constants.API_KEY +
"&redirect_uri=https://apps.facebook.com/myoldfriends/&scope=";
writer.print("<script> top.location.href='" + authURL + "'</script>");
writer.close();
}
else {
FacebookClient facebookClient = new DefaultFacebookClient(oauthToken);
Connection<User> myFriends = facebookClient.fetchConnection("me/friends",
User.class);
writer.print("<table><tr><th>Photo</th><th>Name</th><th>Id</th></tr>");
for (List<User> myFriendsList : myFriends) {
for(User user: myFriendsList)
writer.print("<tr><td><img src=\"https://graph.facebook.com/" +
user.getId() + "/picture\"/></td><td>" + user.getName() +
"</td><td>" + user.getId() + "</td></tr>");
}
writer.print("</table>");
writer.close();
}
}
|
Với servlet được tạo ra, ứng dụng đã sẵn sàng được triển khai. Nhấn vào biểu tượng Google trong Eclipse và chọn Deploy to App Engine (Triển khai vào App Engine). Sau khi ứng dụng được biên dịch và được tải lên máy chủ, bạn (và bất kỳ người dùng Facebook khác nào) có thể cài đặt ứng dụng trong Facebook tại http://apps.facebook.com/APP ID/ và xem các kết quả.
Bài này đã trình bày cách đăng ký, thực hiện và triển khai một ứng dụng Facebook viết bằng Java, được lưu trữ trên dịch vụ Google App Engine. Bây giờ bạn đã quen với những điều cơ bản, tôi đề nghị bạn hãy thử nghiệm.
Thay vì viết HTML với nội dung trực tiếp vào trang, bạn có thể thực hiện một cách tiếp cận
Model-View-Controller (MVC) truyền thống hơn bằng cách sử dụng cuộc gọi RequestDispatcher.forward() tiêu chuẩn đến một trang JavaServer Pages (JSP).
Bạn có thể thử tạo ra một ứng dụng có sử dụng thêm một số các quyền hạn cho dữ liệu do
Graph API cung cấp. Bạn chuyển danh sách các quyền hạn mà một ứng dụng cần vào URL xác thực
bằng cách thêm từng quyền hạn vào tham số yêu cầu scope. RestFB
cung cấp một phương thức helper —
StringUtils.join()
— để tạo chính xác danh sách đó. Nó lấy một mảng String
duy nhất làm một tham số; mỗi mục nhập trong mảng là một tên quyền hạn.
Cuối cùng, bạn có thể thử tạo lại ứng dụng mẫu bằng cách sử dụng dự án Facebook-java-api Google Code (Mã Google của Facebook-java-api) — một cách thực hiện thay thế của Facebook API — để thay cho RestFB (xem phần Tài nguyên).
| Mô tả | Tên | Kích thước | Phương thức tải |
|---|---|---|---|
| Sample code for this article | j-fb-gaecode.zip | 5KB | HTTP |
Học tập
-
Trang web của nhà phát triển Facebook: Đây là
trang chủ của Facebook Platform, Graph API Explorer và các công cụ khác cho các nhà phát triển Facebook của bên thứ
ba.
-
Signed
Request: Đọc về vai trò của tham số
signed_requesttrong xác thực các ứng dụng Facebook. -
Xác thực ứng dụng Facebook Canvas — Java: Xem bài đăng blog này về giải mã yêu
cầu do Facebook ký.
-
Tài liệu tham
khảo các quyền hạn của Facebook: Bạn sẽ tìm thấy danh sách đầy đủ về các quyền hạn của
ứng dụng Facebook có sẵn ở đây.
-
Google App Engine: Xem trang web GAE.
- "Cuộc chiến
Java PaaS" (Michael Yuan, developerWorks, , 04.2011: Bài này so sánh 3 dịch vụ PaaS
chủ yếu cho Java, gồm có GAE.
-
Sử dụng Trình cắm
thêm (plug-in) Google cho Eclipse: Đọc về trình cắm thêm GAE cho Eclipse và cách cài
đặt nó.
-
RestFB: Truy cập vào trang web dự án RestFB.
-
JavaScript Object Notation (JSON): Tìm hiểu thêm về định
dạng mà dữ liệu được chuyển giao theo định dạng đó giữa Facebook và ứng dụng của bạn.
-
facebook-java-ai: Xem lựa chọn
thay thế này cho RestFB.
- Duyệt hiệu sách công
nghệ để biết các cuốn sách về các chủ đề kỹ thuật này hay khác.
-
Vùng công nghệ Java trên
developerWorks: Tìm hàng trăm bài viết về mọi khía cạnh về lập trình Java.
Lấy sản phẩm và công nghệ
-
RestFB:
Tải về RestFB.
-
Eclipse: Tải về Eclipse IDE.
-
Apache Commons Codec: Tải
về Commons Codec.
-
Jackson: Tải bộ xử lý Jackson JSON.
- Tải về các phiên bản đánh giá sản phẩm của IBM hoặc khám phá các bản dùng thử trực tuyến trong SOA Sandbox
của IBM và nhận các công cụ phát triển ứng dụng thực hành của bạn và các sản phẩm phần
mềm trung gian từ DB2®, Lotus®, Rational®, Tivoli® và
WebSphere®.
Thảo luận
-
Các blog trên developerWorks: Nhận những
lời khuyên và sự hỗ trợ kỹ thuật cho RestFB.
- Xem các blog
developerWorks và tham gia vào cộng đồng
developerWorks.

Joseph McCarthy là một nhà phát triển Java thuộc Dun & Bradstreet tại Dublin. Kể từ khi tốt nghiệp trường Đại học Limerick với bằng cử nhân khoa học về hệ thống máy tính và bằng kỹ thuật máy tính, ông đã làm nhiều về công nghệ Java trong 10 năm phát triển các nhiệm vụ Ant tùy chỉnh và làm việc với các API công cộng khác nhau, gồm có Twitter, Facebook và GetGlue.