Tóm tắt: Đây là phần cuối cùng trong loạt bài hướng dẫn ba phần về phát triển
một ứng dụng Facebook đầy đủ chức năng trong các ngôn ngữ PHP và Java™ để
cung cấp một giao diện Facebook cho một ứng dụng buôn bán môi giới cổ phiếu
hiện có. Trong hướng dẫn này bạn sử dụng tất cả các công cụ mà bạn đã cài đặt và
các thành phần bạn đã phát triển trong hai phần đầu của loạt bài này để thực hiện
các chi tiết của ứng dụng Facebook
72 trang |
Chia sẻ: tlsuongmuoi | Lượt xem: 2401 | Lượt tải: 0
Bạn đang xem trước 20 trang tài liệu Làm chủ việc phát triển ứng dụng Facebook bằng PHP, IBM Rational Application Developer, IBM WebSphere Application Server và DB2, Phần 3: Hoàn thành ứng dụng trình diễn môi giới chứng khoán Facebook, để xem tài liệu hoàn chỉnh bạn click vào nút DOWNLOAD ở trên
cung cấp các chứng khoán cho khung nhìn khi được tìm nạp từ DAO,
StockListController bây giờ gọi một đối tượng StockPriceSource để lấy giá cả của
từng cổ phiếu, vì giá cả này thay đổi theo thời gian thực, đối lập với được cho theo
cơ sở dữ liệu. Một cuộc môi giới chứng khoán thực sự sẽ triển khai thực hiện lớp
StockPriceSource để lấy ra giá chứng khoán từ một nguồn dữ liệu ở đâu đó, có độ
an toàn cao và theo đặc thù của ngành công nghiệp. Tuy nhiên ứng dụng này sẽ
mô phỏng biến động giá cổ phiếu bằng một lớp StockPriceSource chứa một ánh xạ
“tin điện báo cổ phiếu với mức giá” (stock ticker to price), và mọi yêu cầu về giá
của một cổ phiếu sẽ cập nhật giá đó trong ánh xạ này, thay đổi nó lên xuống một
cách ngẫu nhiên trong biên độ thay đổi lập sẵn (xem mã kèm theo trong phần Tải
về để biết thêm chi tiết).
Để cung cấp StockPriceSource cho StockListController, sửa đổi các định nghĩa
bean của StockListController trong spring-servlet.xml và cung cấp một định nghĩa
bean mới cho đối tượng StockPriceSource, như Liệt kê 2.
Liệt kê 2. Cung cấp cho StockListController một StockPriceSource trong
spring-servlet.xml
<bean id="stockPriceSource"
class="com.jm.fbstockdemo.StockPriceSource">
<bean id="stockListController"
class="com.jm.fbstockdemo.StockListController">
<property name="stockPriceSource"
ref="stockPriceSource"/>
stockList.jsp
Thuộc tính của bean stockPriceSource cấu hình hành vi của nó: tất cả các cổ phiếu
bắt đầu với giá 5000 cent ($50), có thể thay đổi đến 50 cent mỗi tích tắc (thuộc
tính volatility ), và không được phép rớt giá xuống dưới $5 hoặc lên trên $100
trong dải biến thiên ngẫu nhiên của chúng theo thời gian. Thuộc tính
stockPriceSource trên bean stockListController cung cấp cho stockListController
một cá thể stockPriceSource có phạm vi trên toàn ứng dụng. Vì StockPriceSource
là một bean, cùng một cá thể như vậy sẽ vẫn nằm trong bộ nhớ cho đến khi ứng
dụng web hoặc IBM WebSphere được khởi động lại, và như vậy biến thiên giá cổ
phiếu sẽ vẫn ổn định trong trang vải nền Facebook cho đến khi ứng dụng còn đang
chạy.
Sử dụng thư viện thẻ JSP JSON để tạo ra nguồn cấp JSON
Bây giờ bạn đã có một nguồn cổ phiếu và giá cả của chúng được mô phỏng theo
thời gian thực, hãy cung cấp thông tin này như là dữ liệu JSON cho các lần gọi
Javascript AJAX mà sẽ chạy trong trang vải nền. JSON (ký pháp đối tượng
JavaScript), đặc tả của nó hiện có tại là một định dạng thay
thế cho XML để chuyển dữ liệu đối tượng, và đang trở thành được ưa thích đối với
dữ liệu AJAX. Nó cô đọng hơn (do đó truyền tải nhanh hơn), cung cấp một ký
pháp dễ hiểu cho các thuộc tính của một đối tượng (trái ngược với sự pha trộn của
các thuộc tính và các thẻ con của XML), và không như XML cung cấp một cấu tạo
rõ ràng để biểu thị một danh sách các mục. Các tính năng này làm cho nó nhanh
hơn, đơn giản, và không nhập nhằng khi chuyển dữ liệu JSON thành các đối tượng
trong một ngôn ngữ như Javascript mà hỗ trợ các đối tượng và mảng.
Tuy nhiên, các khung nhìn của ứng dụng là JSPs, và các JSP gồm cả XML, nên sử
dụng một thư viện thẻ JSP cho phép bạn dựng nên các đối tượng bằng cách sử
dụng XML, trong khi các thẻ biểu hiện dữ liệu đối tượng ở định dạng JSON. Để
làm điều đó, hãy sử dụng thư viện thẻ JSON JSP sẵn có tại
taglib.sourceforge.net/index.html. Tải về json-taglib JAR vào thư mục WEB-
INF/lib của bạn. Sau đó sửa đổi stockList.jsp -- khung nhìn được
StockListController biểu hiện -- để cung cấp dữ liệu dưới dạng JSON, như Liệt kê
3.
Liệt kê 3. Sử dụng thư viện thẻ JSON JSP để biểu hiện nguồn cấp giá cổ
phiếu JSON
<%@ taglib prefix="c"
uri="" %>
<%@ taglib prefix="json"
uri="" %>
<c:forEach items="${stocks}"
var="stock">
<json:property
name="id"><c:out
value="${stock.id}"/>
<json:property
name="ticker"><c:out
value="${stock.ticker}"/>
<json:property
name="price"><c:out
value="${stock.price}"/>
Một đối tượng JSON gồm có các cặp tên/giá trị, trong đó một giá trị có thể là giá
trị kiểu nguyên thủy như một chuỗi ký tự, một đối tượng JSON khác, hoặc một
mảng JSON. Trong stockList.jsp, thẻ tạo ra một đối tượng JSON
như là vỏ bọc bậc cao nhất của nó. Nhãn tạo ra một thuộc tính của
đối tượng bậc cao nhất gọi là stocks là một mảng của các đối tượng JSON, trong
trường hợp này là cổ phiếu. JSP lặp qua các cổ phiếu do StockListController cung
cấp để xây dựng nên mảng JSON, tạo ra một đối tượng JSON cho mỗi cổ phiếu,
mỗi cái với một mã nhận dạng (id), tin điện báo (ticker) và thuộc tính giá cả
(price).
Chú ý rằng contentType ở đây là text (văn bản) nên bạn có thể xem các kết quả
trong một trình duyệt và gỡ lỗi Javascript dễ dàng hơn, nhưng một cách khác nó
có thể là “text/json”. Cũng lưu ý rằng bạn không thể bao gồm các chú thích <!--
xml comments --> trong JSP này, vì mặc dù chúng sẽ bị bỏ qua nếu đầu ra là
XML, nhưng chúng sẽ được diễn giải như là dữ liệu hỏng khi kết quả được diễn
giải như là JSON.
Để kiểm tra nguồn cấp JSON của giá cả cổ phiếu, hãy triển khai lại ứng dụng Web
lên WebSphere (như trong Phần 2 của hướng dẫn này), di chuyển đến
trong trình duyệt của bạn, và bạn sẽ thấy
các cổ phiếu và giá cả của chúng ở định dạng JSON. Tải lại trình duyệt và giá cả
cổ phiếu trong dữ liệu JSON sẽ thay đổi, vì StockPriceSource sẽ thay đổi giá cả
của chúng với mỗi yêu cầu.
Xem nguồn cấp JSON này đang hoạt động khi bạn thực hiện việc gọi ra AJAX
trong FBJS của trang vải nền (Facebook JavaScript). Tuy nhiên, trước khi bạn đến
đó bạn cần phải nhận ra người sử dụng Facebook đang xem trang danh mục đầu tư
(portfolio page), do đó hãy chuyển sự chú ý của bạn trở lại phía bên PHP của ứng
dụng để kết nối với Facebook và nhận dạng người sử dụng Facebook trong cơ sở
dữ liệu DB2 của bạn.
Kết nối với ứng dụng và với Facebook trong PHP
Bây giờ hãy thực hiện trang vải nền của ứng dụng, gồm cả việc kết nối với
Facebook và nối kết người sử dụng Facebook với mã nhận dạng của họ trong cơ
sở dữ liệu DB2 IBM, và thực hiện trang danh mục đầu tư chính của người sử
dụng, dùng nguồn cấp JSON.
Sửa đổi URL gọi lại để sử dụng tập tin .htaccess
Trong Phần 1 của hướng dẫn này bạn đã sử dụng một tệp index.php đơn giản để
kiểm tra cấu hình ứng dụng Facebook. Do bạn đã bổ sung hoàn thiện cơ sở hạ tầng
và đang sử dụng tập tin .htaccess để gửi đi các yêu cầu, bạn cần phải thay đổi URL
gọi lại của ứng dụng trong thiết lập của ứng dụng. Trong Facebook, nhấn vào ứng
dụng Applications ngay bên dưới hộp tìm kiếm (Search box). Trong ứng dụng
Applications bạn có thể nhìn thấy toàn bộ các ứng dụng được cài đặt của bạn.
Nhấn vào ứng dụng Developer nó chứa một danh sách các ứng dụng mà bạn là
nhà phát triển, hiển thị dưới dạng một danh sách nằm ở phía bên phải (xem Hình
1).
Hình 1. Danh sách ứng dụng của bạn trong ứng dụng Developer
Nhấn vào tên ứng dụng của bạn để xem trang thiết lập của nó, nhấn Edit Settings,
và đổi Callback URL thành thay SERVER bằng
URL của máy chủ web Apache 2 ở xa của ứng dụng của bạn. Nếu bạn đặt
Callback URL như trong Phần 1, việc này chỉ đòi hỏi loại bỏ tên tệp index.php
khỏi phần cuối của URL.
Sửa đổi .htaccess để hỗ trợ ứng dụng đầy đủ
Do trang vải nền của bạn trỏ đến thư mục fb_stock_demo, được điều quản bởi
RewriteRules, của tập tin .htaccess, hãy sửa đổi .htaccess như trong Liệt kê 4 để
cung cấp tất cả các quy tắc cần thiết để hoàn tất ứng dụng.
Liệt kê 4. Tập tin .htaccess đầy đủ
RewriteEngine on
# php dispatcher request
RewriteCond
%{QUERY_STRING} (.*)
RewriteRule ^php/(.*)
index.php?controller=$1&%1
[last]
# index
RewriteRule ^$
php/defaultCanvas [next]
# php actions
RewriteRule ^login$ php/login
[next]
RewriteRule ^portfolio$
php/portfolio [next]
RewriteRule
^recommendStockToFriends$
php/recommendStockToFriends
[next]
# java actions
RewriteRule ^tradeStock$
java/tradeStock [next]
RewriteRule ^stockList$
java/stockList [next]
RewriteRule đầu tiên định tuyến tất cả các yêu cầu có tiền tố “php/” đến index.php
như trong Phần 2 của hướng dẫn này. Quy tắc tiếp theo tiến hành so khớp
Callback URL nhưng không có phần đường dẫn tiếp theo được xác định, và nó uỷ
quyền cho yêu cầu PHP defaultCanvas. Các hành động PHP khác hoạt động tương
tự, và các hành động Java hiện nay bao gồm cả một yêu cầu tradeStock mà bạn sẽ
triển khai thực hiện sau trong hướng dẫn này.
Sửa đổi app.properties
Trong Phần 2 bạn đã phát triển lớp ActionDispatcher nó định tuyến các yêu cầu
đến các lớp của trình điều khiển bằng cách sử dụng các tệp thuộc tính trong lớp
Injectable. Để cung cấp cho trình điều khiển các ánh xạ định nghĩa trong tập tin
.htaccess mới, hãy sửa đổi app.properties (trong thư mục conf, dưới thư mục
fb_stock_demo, là nơi chứa tệp .htaccess) như Liệt kê 5.
Liệt kê 5. Tập tin app.properties đầy đủ
ActionDispatcher/defaultCanvas=DefaultCanvasController
ActionDispatcher/login=LoginController
ActionDispatcher/portfolio=PortfolioController
ActionDispatcher/recommendStockToFriends=RecommendStockToFriendsContro
ller
AbstractStockDemoFacebookController/facebook_api_key=[YOUR FACEBOOK
API_KEY]
AbstractStockDemoFacebookController/facebook_secret=[YOUR FACEBOOK
SECRET]
AbstractStockDemoFacebookController/facebookAppUrl=
m/
[YOUR CANVAS PAGE URL] AbstractStockDemoFacebookController/siteUrl=
http://[YOUR SERVER URL]/fb_stock_demo
DefaultCanvasController/loggedInForward=portfolio
DefaultCanvasController/loginView=loginView.php
LoginController/alreadyHasUserForward=portfolio
LoginController/validUserForward=portfolio
LoginController/invalidUserView=loginView.php
Vào thời điểm này, dòng đầu tiên là hệ trọng nhất, bởi vì nó sẽ ánh xạ khoá của
trình điều khiển defaultCanvas (được cung cấp bởi quy tắc viết lại trong .htaccess)
đến lớp DefaultCanvasController sao cho lớp ActionDispatcher sẽ tạo ra một cá
thể DefaultCanvasController và cho chạy nó khi có người truy cập trang vải nền
của ứng dụng của bạn. Các thuộc tính khác sẽ trở nên hữu ích khi bạn thực hiện
phần còn lại của ứng dụng.
DefaultCanvasController
DefaultCanvasController xử lý các yêu cầu được gửi tới trang vải nền của ứng
dụng Facebook (mà không có URI phụ), và cần để xử lý hai khả năng. Một khả
năng là, nếu đây là lần đầu tiên người sử dụng truy cập trang vải nền của ứng dụng
này, có nghĩa là bây giờ họ chỉ vừa mới thêm ứng dụng vào. Khi họ truy cập lần
đầu tiên, bạn có được mã nhận dạng người sử dụng Facebook vì Facebook gửi nó
trong yêu cầu, nhưng bạn còn chưa biết người sử dụng facebook này là ai về mặt
môi giới chứng khoán, nghĩa là tên người sử dụng là gì theo hệ thống hiện hành, vì
vậy bạn cần đến chúng để đăng nhập và thiết lập liên kết đó. Khả năng thứ hai là
trường hợp người sử dụng đã đăng nhập vào hệ thống, trong trường hợp này họ có
thể bỏ qua màn hình đăng nhập tuỳ chỉnh của bạn và xem danh mục đầu tư của họ.
Trong trường hợp đầu, DefaultCanvasController biểu hiện khung nhìn đăng nhập
tùy chỉnh của ứng dụng, và trong trường hợp thứ hai, nó chuyển điều khiển đến
PortfolioController (mà bạn sẽ thực hiện sau đây), như Liệt kê 6.
Liệt kê 6. Lớp DefaultCanvasController
class DefaultCanvasController extends
AbstractStockDemoFacebookController
{
public function __construct() {
parent::__construct(false);
}
protected function
executeFacebookRequest() {
return $this->user
? new ControllerForward ($this-
>loggedInForward)
: new ModelAndView ($this-
>loginView);
}
}
DefaultCanvasController Chuyển giao kết quả là false đến hàm tạo của lớp cha,
chỉ rõ rằng không yêu cầu người sử dụng đã được đăng nhập vào hệ thống môi
giới chứng khoán. Thuộc tính loginView được thêm vào từ app.properties và
tương ứng với loginView.jsp. loggedInForward cũng được thiết lập trong
app.properties, và nó xác định rõ khoá của trình điều khiển “portfolio”, ánh xạ đến
lớp PortfolioController (tham khảo liệt kê mã lệnh của app.properties để biết các
giá trị khoá khác nhau được ánh xạ vào).
Trong trường hợp đầu, khi mà người sử dụng lần đầu tiên thêm ứng dụng
Facebook và cần đăng nhập vào môi giới chứng khoán, loginView.jsp là một trang
đăng nhập đơn giản (xem Liệt kê 7) mà sau đó được hiển thị như trang vải nền của
ứng dụng của bạn (xem Mã nguồn để có toàn bộ tập tin).
Liệt kê 7. Thẻ form trong loginView.php
<span
class="label">Username:<input
name="username"/>
<span
class="label">Password:<input
name="password"
type="password"/>
<input type="submit"
value="Submit"/>
Đây thực sự là FBML, mặc dù nó không sử dụng bất kỳ thẻ FBML đặc trưng
Facebook nào. Chú ý rằng hành động (action) của biểu mẫu liên quan đến
Callback URL của ứng dụng; Facebook uỷ nhiệm yêu cầu post tới máy chủ của
bạn. Lớp LoginController xử lý yêu cầu post (gửi dữ liệu) đăng nhập (xem Mã
nguồn để biết thêm chi tiết), bằng cách chèn thêm vào một hàng trong bảng
facebook_user, liên kết mã nhận dạng người sử dụng facebook của người sử dụng
với ID nhà kinh doanh môi giới chứng khoán của họ.
Thực hiện một trình điều khiển cơ sở chung
Do tất cả các trình điều khiển, ngoại trừ LoginController đều yêu cầu rằng người
sử dụng Facebook được nhận biết trong hệ thống môi giới chứng khoán, và do tất
cả các trình điều khiển này sẽ yêu cầu một kết nối với trình khách Facebook, sẽ
hữu ích nếu sử dụng một lớp cơ sở chung, kết nối với Facebook và tìm kiếm người
sử dụng trong cơ sở dữ liệu trước khi thực hiện các chi tiết của yêu cầu đó. Để làm
điều này, hãy thực hiện lớp điều khiển cơ sở
AbstractStockDemoFacebookController, như Liệt kê 8.
Liệt kê 8. Lớp AbstractStockDemoFacebookController (PHP)
abstract class AbstractStockDemoFacebookController
extends AbstractStockDemoController {
protected $facebook = null;
private $requiresUser;
protected $user = null;
public function __construct($requiresUser = true) {
parent::__construct();
$this-
>addPrefix('AbstractStockDemoFacebookController');
$this->requiresUser = $requiresUser;
}
public function executeSpecific() {
$this->facebook = new StockDemoFacebookClient
($this->facebook_api_key,
$this->facebook_secret);
$this->user = $this->dao->fetchUserByFacebookId
($this->getFacebookUserId());
if ($this->user == null && $this->requiresUser) {
throw new Exception
("AbstractStockDemoFacebookController --
no matching user found in stocks database.");
}
return $this->executeFacebookRequest();
}
protected function getFacebookUserId() {
return $this->facebook->user;
}
protected function getUser() {
return $this->user;
}
protected abstract function
executeFacebookRequest();
}
Hãy nhớ lại rằng ActionDispatcher sẽ tạo ra một cá thể của trình điều khiển thích
hợp, thiết lập đối tượng Properties của nó từ tệp tin thuộc tính, và gọi ra phương
thức execute() của nó. Lớp AbstractStockDemoFacebookController mở rộng lớp
AbstractStockDemoController, mà phương thức execute() của lớp này sẽ kết nối
với cơ sở dữ liệu IBM DB2, đưa ra một thông báo lỗi nếu không kết nối được, và
gọi phương thức trừu tượng executeSpecific(). Mã triển khai thực hiện phương
thức executeSpecific() của lớp AbstractStockDemoFacebookController tạo ra một
cá thể StockDemoFacebookClient (mà bạn sẽ thực hiện tiếp theo) để kết nối với
Facebook và xác nhận rằng người sử dụng đã đăng nhập vào ứng dụng Facebook.
Sau đó nó tìm kiếm người sử dụng Facebook trong cơ sở dữ liệu thông qua
StocksDAO, nhận được đối tượng User liên kết mã nhận dạng Facebook của họ
với ID người sử dụng nhà kinh doanh cổ phiếu của họ. Nếu người sử dụng
Facebook không tương ứng với một người sử dụng trong cơ sở dữ liệu, lớp này
huỷ bỏ bằng một lỗi ngoại lệ (Exception), trừ phi hàm tạo của lớp con chuyển tới
kết quả là false dành cho cờ báo $requiresUser -- chỉ có DefaultCanvasController
làm việc này vì nó cần có khả năng điều phối LoginController dành cho đăng nhập
ban đầu.
Tạo một lớp bọc xung quanh trình khách Facebook PHP
Để bao kín các lần gọi ban đầu đến Facebook và cung cấp các phương thức đặc
thù cho ứng dụng mà chính nó cũng bao gói các lần gọi đến trình khách Facebook,
hãy tạo lớp StockDemoFacebookClient như trong Liệt kê 9.
Liệt kê 9. Lớp StockDemoFacebookClient (PHP)
class
StockDemoFacebookClient
extends Facebook {
public function
__construct($apiKey,
$secret) {
parent::__construct
($apiKey, $secret);
$this->require_frame();
$this->require_install();
$this->require_login();
}
}
Đây cũng là mã mà bạn trông thấy trong Phần 1 của hướng dẫn, trong tệp
index.php khung sườn bạn đã sử dụng để kiểm tra kết nối giữa Zend Core for IBM
với các máy chủ của Facebook. Khi AbstractStockDemoFacebookClient tạo ra
một cá thể của đối tượng khách này nó sẽ kết nối với Facebook và yêu cầu rằng
người sử dụng phải có ứng dụng đã cài đặt và đã đăng nhập vào nó (theo
Facebook, chứ không phải là đăng nhập vào môi giới chứng khoán). Các lời gọi
require_install() và require_login() chuyển hướng đến các trang tương ứng trên
Facebook nếu người sử dụng hoặc chưa thêm vào ứng dụng này hoặc chưa được
đăng nhập vào nó trên Facebook. Lớp Facebook sử dụng các tham số yêu cầu gửi
trong yêu cầu từ Facebook để xác định người sử dụng. Ngoài ra, sau này bạn sẽ
thêm các lời gọi trình khách đặc thù của ứng dụng vào đây.
Kết nối với Facebook và thực hiện giao dịch mua bán phía Java
Do bạn đã được kết nối với Facebook và đã đồng bộ hoá người sử dụng với cơ sở
dữ liệu cổ phiếu bên phía PHP, theo đó hoàn tất mã giao dịch mặt sau (backend
transaction code) ở đó, sẽ hữu ích khi viết mã tương tự như thế ở phía Java, để bạn
có một mặt sau hoàn chỉnh sẵn sàng khi bạn thực hiện trang vải nền chính để hiển
thị thông tin kết quả từ các hoạt động mặt sau khác nhau.
Sử dụng một lớp cơ sở để kết nối với Facebook phía Java
Giống như bạn đã làm cho bên PHP của ứng dụng, trong Rational Application
Developer của IBM hãy tạo ra lớp AbstractStockDemoFacebookController như
Liệt kê 10.
Liệt kê 10. Lớp AbstractStockDemoFacebookController (Java)
public abstract class AbstractStockDemoFacebookController
extends
AbstractStockDemoController {
private FacebookKeys facebookKeys;
private User user;
private StockDemoFacebookClient facebookClient;
public ModelAndView handleRequest(HttpServletRequest
request,
HttpServletResponse response) throws Exception {
this.facebookClient =
new StockDemoFacebookClient (request, response,
getFacebookKeys());
this.user =
getDao().fetchUserByFacebookId(getFacebookClient().getUser());
if (this.user == null) {
throw new
RuntimeException("AbstractStockDemoFacebookController --
no user in database matching facebook id");
}
return handleFacebookRequest (request, response);
}
protected abstract ModelAndView handleFacebookRequest
(HttpServletRequest request, HttpServletResponse response);
public void setFacebookKeys(FacebookKeys facebookKeys) {
this.facebookKeys = facebookKeys;
}
protected FacebookKeys getFacebookKeys() {
return facebookKeys;
}
protected StockDemoFacebookClient getFacebookClient() {
return this.facebookClient;
}
protected User getUser() {
return this.user;
}
}
Mã này trông hầu như giống hệt lớp PHP tương ứng -- handleRequest() kết nối với
Facebook bằng cách sử dụng một lớp StockDemoFacebookClient (mà bạn sẽ viết
ngay bây giờ), tìm kiếm người sử dụng Facebook trong cơ sở dữ liệu cổ phiếu, đưa
ra một lỗi RuntimeException nếu không tìm thấy người sử dụng nào như vậy, và
gọi phương thức trừu tương handleFacebookRequest() Tiếp theo, sử dụng thư viện
phía khách Java để kết nối với Facebook như bạn đã làm trong PHP.
Kết nối với Facebook trong Java
Vấn đề đầu tiên của bạn khi kết nối với Facebook từ Java là ở chỗ Facebook gần
đây đã đình chỉ thư viện khách Java của nó, không tiếp tục duy trì việc cập nhật
nữa. May mắn là, một dự án có tên facebookjava-api (xem Các điều kiện tiên
quyết), được chứa trên máy chủ Google Code, đã tự đặt ra sứ mệnh của mình là để
“cung cấp một phiên bản chất lượng cao, cập nhật hơn của API Facebook phía
khách cho các nhà phát triển Java, và cho phép nó được bảo trì đều đặn thường kỳ
sau này để duy trì các hỗ trợ khi các API nền Facebook thay đổi và tiến hoá lên.”
Với việc đình chỉ thư viện khách chính thức, dường như đã coi nó là một chuẩn
thực tế (de facto standard), và nó chính là thư viện mà bạn sẽ sử dụng trong ứng
dụng này.
May mắn là dự án facebook-java-api cũng đã cung cấp Tiện ích Bạn bè
(Companion), trong đó chủ yếu cung cấp cùng một lớp Facebook mà bạn đã sử
dụng bên phía PHP. Nó bao bọc lớp khách REST Facebook thực tế, và cung cấp
các phương thức thuận tiện như requireLogin() làm cho việc kết nối một ứng dụng
PHP với Facebook một cách đúng đắn trở thành rất dễ dàng. Thư viện khách Java
ban đầu không bao gồm lớp này, đòi hỏi bạn phải tự xử lý một số bước xác thực
và mang lại một rào chắn quan trọng để bước vào phát triển ứng dụng Facebook.
Vì vậy trước tiên tải về tất cả các JAR đã đề cập trên địa chỉ trang ấy, trừ
activation.jar, vì hầu hết các máy chủ ứng dụng đã bao gồm nó trong biến đường
dẫn lớp dùng chung (shared classpath). Ở đây gồm có năm tệp JAR được liệt kê
dưới Quick Start và hai tệp JAR dưới Companion Utility. Hãy đặt các JAR này
vào thư mục WEB-INF/lib trong dự án ứng dụng web của bạn.
Để sử dụng thư viện khách, hãy thực hiện lớp StockDemoFacebookClient như
thấy trong Liệt kê 11.
Liệt kê 11. Lớp StockDemoFacebookClient (Java)
public class StockDemoFacebookClient
extends Facebook {
public
StockDemoFacebookClient(HttpServletRequest
request,
HttpServletResponse response, FacebookKeys
keys) {
// connect to facebook
super(request, response, keys.getApiKey(),
keys.getSecret());
// will redirect if we're not logged in already
String next =
request.getServletPath().substring(1);
if (requireLogin(next)) {
throw new RuntimeException ("User not
logged into facebook!");
}
}
}
Giống như trong phiên bản PHP, trình khách Facebook đặc thù riêng cho ứng
dụng của bạn là lớp con của trình khách thật. Còn lớp Facebook, để cách ly bạn
khỏi các chi tiết của các tham số yêu cầu liên quan gửi đến từ Facebook (giống
như phiên bản PHP đã làm), sẽ lấy các đối tượng HttpServletRequest và
HttpServletResponse để xử lý việc nhận biết người sử dụng đang gọi Facebook và
khả năng chuyển hướng đến trang đăng nhập ứng dụng Facebook khi cần thiết.
StockDemoFacebookClient cũng lấy một đối tượng FacebookKeys, một lớp đơn
giản chứa API Key và Secret của ứng dụng Facebook.
Thực hiện giao dịch mua bán phía Java
Do việc môi giới chứng khoán có lẽ đã cho phép buôn bán cổ phiếu trước khi ứng
dụng Facebook xuất hiện, hãy triển khai mã lệnh giao dịch cổ phiếu phía Java. Để
làm điều đó, tạo ra một bean Spring tradeStockController như Liệt kê 12.
Liệt kê 12. bean Spring tradeStockController
<bean id="tradeStockController"
class="com.jm.fbstockdemo.TradeStockController">
<property name="stockPriceSource"
ref="stockPriceSource"/>
Mã lệnh này cung cấp cho trình điều khiển bean Dao (StocksDao), bean
stockPriceSource một cờ báo cho nó biết có gửi lên nguồn cung cấp tin tức
Facebook hay không (để không quấy nhiễu bạn bè của nhà phát triển trong khi gỡ
lỗi), một thuộc tính successView chứa URL của ứng dụng Facebook mà trình điều
khiển này sẽ chuyển hướng đến khi hoàn thành, và một bean facebookKeys. Bean
facebookKeys chứa API Facebook Key và Secret, như Liệt kê 13.
Liệt kê 13. Bean spring facebookKeys
<bean id="facebookKeys"
class="com.jm.fbstockdemo.FacebookKeys">
<constructor-arg
value="b7d42ca56cd47fc94274ecb8428f9d8d"/>
<constructor-arg
value="a42ce25076de43546f886aa2fec77321"/>
Đưa các giá trị này vào một bean Spring cho phép bạn giữ các giá trị đó tách khỏi
mã và cho phép bạn dễ dàng thêm chúng vào bất kỳ trình điều khiển nào cần kết
nối với Facebook.
Để làm công việc buôn bán, hãy tạo lớp StockTradeController như Liệt kê 14.
Liệt kê 14. Lớp TradeStockController (Java)
public class TradeStockController extends
AbstractStockDemoFacebookController {
private boolean postToNewsFeed = false;
@Override
protected ModelAndView
handleFacebookRequest(HttpServletRequest
request,
HttpServletResponse response) {
int stockId =
Integer.parseInt(request.getParameter("stockId"));
int shares =
Integer.parseInt(request.getParameter("shares"));
long stockPriceInCents =
getStockPriceSource().getPriceInCents(stockId);
long previousSum =
getDao().fetchTradeSum(getUser().getTraderId(),
stockId);
// effect the trade
Trade trade = getDao().createTrade
(getUser().getTraderId(),
stockId, shares,
stockPriceInCents);
long newSum =
getDao().fetchTradeSum(getUser().getTraderId(),
stockId);
long net = newSum - previousSum;
trade.setNetInCents (net);
// notify the user
getFacebookClient().sendNotificationToUser
(createTradeNotificationText (trade));
// if a profit, post to mini/news feeds
if (trade.getNetInCents() > 0 &&
this.postToNewsFeed) {
getFacebookClient().postToNewsAndMiniFeeds
(createTradeNewsItemText (trade,
getFacebookClient().getAddUrl("")));
}
// redirect to portfolio page with result of trade
try {
response.sendRedirect(getSuccessView() +
"?tradeResult=" +
trade.getNetInCents() +
"&tradeResultStockId=" +
trade.getStock().getId());
} catch (IOException e) {
throw new RuntimeException (e);
}
return null;
}
public void setPostToNewsFeed (boolean b) {
this.postToNewsFeed = b;
}
}
TradeStockController lấy các tham số yêu cầu stockId và shares xác định mã
chứng khoán và số lượng cổ phiếu để mua hoặc bán (một giá trị số cổ phiếu âm =
một cuộc bán), xúc tiến việc mua bán và ghi lại nó trong cơ sở dữ liệu, và sau đó
thực hiện hai lời gọi Facebook thông qua trình khách Facebook. Trước nhất, nó
gửi một thông báo cho người sử dụng xác nhận việc mua bán. Và thứ hai là, nếu
người sử dụng đã mua các cổ phần của mã chứng khoán, vì ứng dụng Facebook
này cũng là một trò chơi xã hội, trình khách gửi một hành động đến nguồn cấp tin
mini (Mini Feed) của người sử dụng, mà có thể sẽ được lan truyền đến các Nguồn
cung cấp tin tức (News Feeds) của bạn bè họ. Sau đó nó gửi một chuyển hướng
HTTP đến trang vải nền danh mục đầu tư chính (xác định trang ứng dụng
Facebook, không phải là URL của trang theo máy chủ ở xa), cung cấp các tham số
yêu cầu tradeResult và tradeResultStockId để hiển thị ở đó.
Gửi lên các thông báo Facebook và các hành động Nguồn cấp tin mini / Nguồn
cung cấp tin tức từ Java
Để thêm chức năng thông báo và gửi hành động, hãy thêm các phương thức
sendNotificationToUser() và postToNewsAndMiniFeeds() vào
StockDemoFacebookClient, như trong Liệt kê 15.
Liệt kê 15. StockDemoFacebookClient.sendNotificationToUser() và
StockDemoFacebookClient.postToNewsAndMiniFeeds()
public void sendNotificationToUser(String fbml) {
try {
getFacebookRestClient().notifications_send (fbml);
} catch (FacebookException e) {
throw new RuntimeException (e);
} catch (IOException e) {
throw new RuntimeException (e);
}
}
public void postToNewsAndMiniFeeds(String fbml) {
try {
getFacebookRestClient().feed_publishTemplatizedAction
(fbml);
} catch (FacebookException e) {
throw new RuntimeException (e);
} catch (IOException e) {
throw new RuntimeException (e);
}
}
Đối tượng Facebook tự nó là một vỏ bọc bao quanh đối tượng trình khách hiện
thời, thu được qua getFacebookRestClient(). Các phương thức phía khách (trong
cả hai thư viện khách Java và PHP) sử dụng một quy ước đặt tên bắt chước tên của
các lời gọi hàm API REST thực tế, danh sách những API này bạn có thể xem tại
Chú ý rằng khi sử dụng thư
viện khách Java, tất cả các lời gọi phương thức phải xử lý các lỗi ngoại lệ được
kiểm tra là FacebookException và IOException -- một lý do để sử dụng lớp
StockDemoFacebookClient.
Để tạo ra lời văn của thông báo, thêm createTradeNotificationText() vào lớp
TradeStockController, như Liệt kê 16.
Liệt kê 16. TradeStockController.createTradeNotificationText()
private String
createTradeNotificationText (Trade
trade) {
return "Trade confirmation: " +
trade.getShares() + " @ "
+
trade.getStock().getPriceFormatted();
}
Mã lệnh này sẽ được xử lý như FBML khi gửi đến Facebook, nhưng thông báo cụ
thể này không sử dụng thẻ FBML nào.
Để tạo ra hành động Nguồn cấp tin mini/Nguồn cung cấp tin tức, hãy thêm
createTradeNewsItemText() vào lớp TradeStockController như trong Liệt kê 17.
Liệt kê 17. TradeStockConroller.createTradeNewsItemText()
private String
createTradeNewsItemText
(Trade trade, String
addUrl) {
return "{actor} is buying
" +
trade.getStock().getTicker()
+
"using the <a href=\""
+ addUrl + "\">" +
"DeveloperWorks
Stock Demo Application!"
+ "";
}
}
Chú ý rằng StockDemoFacebookClient gọi phương thức
feed_publishTemplatizedAction() của trình khách Facebook với FBML đã cung
cấp. Hành động được đưa vào khuôn mẫu cho phép bạn đặt tên của người sử dụng
vào lời văn của thông báo bằng cách sử dụng thẻ bài {actor}, thẻ bài này sẽ được
thay thế bằng tên của người sử dụng khi gửi đi hành động này.
Do mặt sau đã xong xuôi, bạn sẽ thực hiện trang vải nền danh mục đầu tư chính,
nơi ghép mọi thứ ở trên cùng với nhau.
Thực hiện trang vải nền danh mục đầu tư cổ phiếu
Trang vải nền chính sẽ hiển thị tất cả các mã chứng khoán sẵn có trong hệ thống,
và số cổ phiếu của người sử dụng của bất cứ mã chứng khoán nào mà họ sở hữu.
Nó sẽ cũng cung cấp các điều khiển để buôn bán cổ phiếu và đề xuất một cổ phiếu
đến bạn bè trên Facebook. Hãy thực hiện trang danh mục đầu tư trong PHP, bằng
cách sử dụng FBML và FBJS.
Tạo tệp PortfolioController.php
Đầu tiên hãy tạo tệp PortfolioController.php, trong đó sẽ tạo ra mô hình cho khung
nhìn, như trong Liệt kê 18.
Liệt kê 18. Lớp PortfolioController (PHP)
class PortfolioController extends
AbstractStockDemoFacebookController
{
public function
executeFacebookRequest() {
$stocks = $this->dao-
>fetchStocksAndPortfolio($this->user-
>TRADER_ID);
$tradeResult =
isset($_REQUEST['tradeResult']) ?
$_REQUEST['tradeResult'] : null;
$tradeResultStockId = $tradeResult ?
$_REQUEST['tradeResultStockId'] :
null;
$this->facebook->updateProfile
($this-
>createProfileBoxFBML($stocks));
return new ModelAndView
('portfolio.php',
array ('facebookId' => $this-
>getFacebookUserId(),
'tradeResult' => $tradeResult,
'tradeResultStockId' =>
$tradeResultStockId,
'stocks' => $stocks,
'appUrl' => $this->siteUrl));
}
}
Sau khi lớp cơ sở đã kết nối với Facebook, xác nhận rằng người sử dụng đã đăng
nhập vào ứng dụng Facebook và môi giới chứng khoán,
executeFacebookRequest() tìm kiếm tất cả các mã chứng khoán và tất cả các số cổ
phiếu của người sử dụng của những mã chứng khoán đó qua DAO (xem mã nguồn
để biết thêm chi tiết). Vì chính là trình điều khiển xử lý yêu cầu chuyển hướng từ
kết quả của việc buôn bán (được chuyển hướng từ TradeStockController đang
chạy trong WebSphere IBM), nó cũng sẽ tìm kiếm các tham số yêu cầu
tradeResult và tradeResultStockId đặt chúng vào mô hình của khung nhìn.
PortfolioController thực hiện một việc khác: nó cập nhật Hộp lược tả của người sử
dụng bằng cách gọi StockDemoFacebookClient.updateProfile(). Hãy thêm phương
thức này vào StockDemoFacebookClient như Liệt kê 19.
Liệt kê 19. StockDemoFacebookClient.updateProfile()
public function
updateProfile($profileBox) {
$this->facebook->api_client-
>profile_setFBML($profileBox);
}
Về phía Java, đối tượng Facebook là một bao gói cho trình khách API REST của
Facebook hiện tại, mà các phương thức của nó lặp lại đúng tên của tất cả các API
REST giống như trong trình khách Java.
Để tạo văn bản cho hộp lược thảo, hãy thêm createProfileBoxFBML() vào
PortfolioController như trong Liệt kê 20.
Liệt kê 20. PortfolioController.createProfileBoxFBML()
private function createProfileBoxFBML($stocks) {
$tickers = join(", ", $this-
>collectStockTickers($stocks));
$facebookId = $this->getFacebookUserId();
return
<<<FBML
<fb:name uid="$facebookId" useyou="false"
possessive="true"
firstnameonly="true" linked="false"/>
portfolio:
$tickers
<a
href="">
Join the stock game!
FBML;
}
Phương thức này trước tiên tìm nạp toàn bộ các mã chứng khoán của người sử
dụng, và sử dụng một đoạn Heredoc PHP (PHP Heredoc segment) để xây dựng dễ
dàng hơn nội dung của FBML. Thẻ cung cấp nhiều chức năng để hiển
thị tên của một người sử dụng hoặc một số từ khác để trỏ đến người sử dụng. Ví
dụ, theo mặc định khi Facebook biểu hiện nhãn này, nếu người sử dụng đang xem
lược thảo là người sử dụng mà thuộc tính uid chỉ ra, nó sẽ biểu hiện từ bạn (you)
chứ không phải tên của người sử dụng. Useyou="false" ngăn chặn hành vi này.
Tương tự như vậy, firstnameonly="true" quy định chỉ hiển thị tên riêng của người
sử dụng, linked="false" nói rằng không được tạo một liên kết từ tên này đến lược
thảo của người sử dụng (do người xem đã có trên lược thảo của người sử dụng
rồi), và possessive="true" chuyển tên người sang dạng sở hữu cách, ví dụ, “Jake's”
(của Jake). Phần còn lại của hộp lược thảo liệt kê các chứng khoán mà người sử
dụng này sở hữu và cung cấp một liên kết đến ứng dụng. Nếu người sử dụng nhấn
vào nó và chưa cài đặt sẵn ứng dụng nào, họ sẽ được nhắc nhở để cài đặt nó trước
đã.
Khung nhìn danh mục đầu tư
Do PortfolioController đã nạp vào mô hình, bây giờ là lúc để biểu hiện khung
nhìn. Trong thư mục app, tạo tệp portfolio.php, trong đó bạn sẽ xây dựng lên dần
từng mảnh, cái đầu tiên trong số đó được hiển thị trong Liệt kê 21.
Liệt kê 20. portfolio.php
<link rel="stylesheet" type="text/css"
media="screen" href="<?=
$model['appUrl']
?>/app/stylesheet/portfolio.css?v=1.0"
/>
var STOCK_PRICE_AJAX_URL =
'/stockList';
<script src="<?= $model['appUrl']
?>/app/javascript/
portfolio.js">
Mã lệnh này chỉ thiết lập phần còn lại của trang với một phiểu định kiểu từ bên
ngoài (Facebook gần đây đã thêm hỗ trợ cho các phiếu định kiểu từ bên ngoài) và
tệp FBJS (Javascript). Nó cũng tạo ra một biến FBJS là
STOCK_PRICE_AJAX_URL, cho phép PortfolioController cung cấp URL của
lời gọi AJAX đến FBJS.
Tiếp theo thêm nội dung của Liệt kê 22 để chào người sử dụng.
Liệt kê 22. portfolio.php: Chào người sử dụng
Hi
<fb:name
firstnameonly="true"
useyou="false"
uid="<?=
$model['facebookId']
?>"/>.
Welcome to Stocks
R Us
Ở đây một lần nữa bạn sử dụng thẻ để chèn thêm tên riêng của người
sử dụng. Cũng chú ý rằng trang vải nền được gói trong một thẻ div với ID là
“content” để cung cấp thông tin tạo kiểu dáng trên toàn bộ trang vải nền (ví dụ,
các lề).
Tiếp theo thêm phần thịt của trang, bảng chứng khoán, như Liệt kê 23.
Liệt kê 23. portfolio.php - bảng cổ phiếu
Ticker
Price
Shares
Total
(negative shares =
sell)
<? foreach ($model['stocks'] as $stock):
?>
TICKER ?>
ID
?>">
ID
?>">
SHARES ?>
SHARES): ?>
portfolioShares[ID ?>]
= SHARES ?>;
ID
?>">
<form action="<?= $model['appUrl']
?>/tradeStock">
<input type="submit"
value="Buy/Sell" class="trade-button"/>
<input type="hidden"
name="stockId" value="<?=
$stock->ID ?>"/>
<input type="text" name="shares"
class="shares"/>
shares.
<!-- recommend this stock to your
friends -->
<a href="<?= $model['appUrl']
?>/recommendStockToFriends?ticker=<?=
$stock->TICKER ?>"
class="recommend-control">
Recommend to your friends!
<? if ($model['tradeResult'] &&
$model['tradeResultStockId']
== $stock->ID): ?>
Change: <span id="trade-
result">
<!-- leave the formatting to the
javascript -->
tradeResult = <?=
$model['tradeResult'] ?>;
Total:
<a id="toggle-refresh"
onclick="toggleRefresh()">Start
refresh
init();
Bảng này là một bảng HTML tiêu chuẩn, chứa một chứng khoán trên mỗi hàng,
mỗi hàng cũng gồm một mẫu biểu cho phép người sử dụng Mua/Bán các cổ phiếu
chứng khoán đó. Chú ý rằng hành động của mẫu biểu này là URL của ứng dụng
trên máy chủ ở xa (nghĩa là
Hành động đó cũng
có thể là tương đối như trong loginView. Nếu người sử dụng sở hữu các cổ phiếu
của chứng khoán trên hàng đó, PHP này đưa vào thêm một mẩu nhỏ mã lệnh FBJS
để cập nhật mảng portfolioShares (được định nghĩa trong portfolio.js, sẽ xuất hiện
bên dưới). Đây là một mảng kết hợp toàn cục của các “tin điện báo cổ phiếu” mà
người sử dụng sở hữu, được dùng trong tệp tin FBJS đã bao gồm vào. Mỗi hàng
cũng chứa một liên kết cho phép người sử dụng đề xuất chứng khoán của hàng này
với bạn bè Facebook của họ, và nếu portfolio.php đang biểu hiện kết quả của một
giao dịch buôn bán, nó đưa thêm vào một biến FBJS là tradeResult chứa kết quả
của việc buôn bán này.
Do trang này sẽ được làm mới lại các giá cổ phiếu một lần trong một giây bằng
cách sử dụng AJAX, phần dưới đáy của trang bao gồm một đường liên kết “Pause
refresh” (Tạm dừng làm mới), hữu ích chủ yếu trong việc gỡ lỗi, và nó cũng gọi
hàm FBJS init() ở phần đáy dưới cùng của trang để khởi động việc làm mới AJAX
khi trang vải nền được nạp lần đầu.
Thêm FBJS và danh mục đầu tư bước vào hoạt động
Bây giờ bạn đã có một khung nhìn trang vải nền đã sẵn sàng, cần phải hiển thị một
số giá chứng khoán. Trong phần này hãy thêm vào mã FBJS để thực hiện việc đó,
và sau đó chạy ứng dụng môi giới chứng khoán và xem nó trông như thế nào trên
Facebook.
Bắt đầu với tệp tin FBJS
Tạo một thư mục Javascript dưới thư mục “fb_stock_demo/app” và một tệp tin
portfolio.js, như trong Liệt kê 24.
Liệt kê 24. portfolio.js
var refreshTimer;
var
REFRESH_DELAY
= 1000;
var portfolioShares
= [];
var tradeResult =
null;
function init() {
updateTradeResult();
toggleRefresh();
}
Trước tiên nó tạo ra một số biến được sử dụng trong phần còn lại của kịch bản và
trang - một đối tượng refreshTimer, nắm giữ đối tượng Timer (đồng hồ) dùng để
kích hoạt các lời gọi AJAX, portfolioShares, mảng kết hợp các “tin điện báo cố
phiếu” được tham khảo trong portfolio.php trên đây, và tradeResult, mà giá trị của
nó cũng được thiết đặt trong portfolio.php trên đây để thông báo cho FBJS về kết
quả của một cuộc mua bán. init() là hàm được gọi tại phần dưới cùng của
porfolio.php, khi trang vải nền hoàn tất việc tải về.
Cập nhật kết quả buôn bán trong trang
Việc đầu tiên mà init() làm là cập nhật kết quả của việc buôn bán trên trang này,
như Liệt kê 25.
Liệt kê 25. portfolio.js: updateTradeResult()
function updateTradeResult() {
if (tradeResult) {
var resultElement =
getTradeResultElement();
resultElement.toggleClassName
(tradeResult > 0 ? 'increase' :
'decrease');
resultElement.setTextValue
(formatMoney(tradeResult));
}
}
function
getTradeResultElement() {
return
document.getElementById('trade-
result');
}
Nếu biến tradeResult không rỗng (null) (nghĩa là được portfolio.php thiết đặt giá
trị), updateTradeResult() tìm kiếm phần tử 'trade-result' (kết quả buôn bán) do
portfolio.php đưa vào để đáp ứng lại việc buôn bán đó. Sau đó nó sử dụng hai
phương thức DOM FBJS đặc biệt, toggleClassName() và setTextValue(). FBJS
sửa đổi DOM và cung cấp các phương thức DOM đặc biệt để truy cập các phần tử
như phần tử này. Bạn có thể dễ dàng thêm vào hoặc loại bỏ một tên lớp, hoặc thiết
lập tên lớp của phần tử đó bằng cách sử dụng toggleClassName(). Phương thức
SetTextValue() là một phương thức đặc biệt nữa cho phép bạn thiết lập giá trị
thuần văn bản của một phần tử DOM. Thay cho innerHTML, mà Facebook không
hỗ trợ, bạn có thể thực hiện điều tương tự bằng cách sử dụng setTextValue() để
thiết lập văn bản thuần, hoặc setInnerFBML() để thiết lập FBML bên trong của
một phần tử. Chú ý rằng FBJS không cung cấp một phương thức getInnerFBML()
để nhận được nội dung của một phần tử, cho nên nó không mang lại một sự thay
thế hoàn toàn cho innerHTML. Đây là một lý do cho việc sử dụng một mảng FBJS
portfolioShares toàn cục, ngược với việc cho FBJS kiểm tra innerHTML của phần
tử share (hoặc tương đương) để thu được các cổ phiếu của chứng khoán trên hàng
đó của người sử dụng. Cũng có phương cách có thể là tốt hơn để giữ thông tin này
trong mã FBJS, nhưng là một sự biểu diễn một cách giải quyết khả dĩ khác.
Cũng lưu ý rằng getTradeResultElement() gọi ra document.getElementById() với
ID mà bạn đã sử dụng trong portfolio.php. Nếu bạn xem mã nguồn trang của trang
vải nền trong trình duyệt, bạn sẽ thấy rằng Facebook nối thêm một mã vào phần
đầu của toàn bộ các ID của phần tử và các lớp CSS của bạn. Nó cũng nối mã này
làm phần đầu vào toàn bộ các tên hàm FBJS và các tên biến của bạn. Nó làm việc
này để gói gọn ứng dụng của bạn trong vùng tên trình duyệt riêng của chính mình,
nên bạn có thể viết mã cứ như là bạn đang ở trong một hệ thống khép kín trái
ngược với việc phải lo lắng về các xung đột với trang Facebook xung quanh.
Làm mới trang về giá chứng khoán mỗi giây một lần
Để khởi động việc làm mới định kỳ giá chứng khoán, thêm vào phương thức
toggleRefresh() như trong Liệt kê 26.
Liệt kê 26. portfolio.js: toggleRefresh()
function toggleRefresh() {
var button =
document.getElementById('toggle-
refresh');
if (refreshTimer) {
clearInterval(refreshTimer);
refreshTimer = null;
button.setTextValue('Start
refresh');
} else {
refreshTimer =
setInterval(refreshPrices,
REFRESH_DELAY);
button.setTextValue('Pause
refresh');
}
}
Đồng hồ (timer) và đồng hồ đếm giờ (interval timer) của FBJS làm việc cũng
giống như các đồng nhiệm của chúng trong Javascript, trừ setInterval() và
setTimer() nhận đầu vào là một đối tượng Function nghĩa là
setInterval(refreshPrices), không phải là một đoạn Javascript để thi hành như trong
setInterval('refreshPrices()'). ClearInterval() nhận đầu vào là đối tượng đồng hồ
đếm giờ lặp lại Timer và ngừng nó lại.
Thực hiện lời gọi AJAX để gọi nguồn cấp JSON các giá chứng khoán
Do bạn đã có một đồng hồ đếm giờ lặp lại, hãy thêm vào hàm refreshPrices() thực
hiện lời gọi AJAX để lấy giá chứng khoán, như Liệt kê 27.
Liệt kê 27. portfolio.js: refreshPrices()
function refreshPrices() {
var ajax = new Ajax();
ajax.responseType =
Ajax.JSON;
ajax.ondone = function (data)
{
updateStockPrices
(data.stocks);
}
ajax.onerror =
onStockListError;
ajax.requireLogin = 1;
ajax.post
(STOCK_PRICE_AJAX_URL);
}
Việc này sử dụng đối tượng Ajax dễ dùng của FBJS. Bạn quy định kiểu đáp ứng
(Ajax.JSON, Ajax.XML hoặc Ajax.RAW), cung cấp một đối tượng hàm ondone,
được gọi cùng với dữ liệu trả về, và một đối tượng hàm onerror, được gọi nếu một
lỗi đã xảy ra trong khi thực hiện lời gọi Ajax. Bạn cũng có thể quy định rõ người
sử dụng có buộc phải đăng nhập vào ứng dụng hay không để thực hiện lời gọi
Ajax (trường hợp của chúng ta là phải đăng nhập vào). Sau đó bạn gọi phương
thức post() của nó với URL cần gọi, và nó sẽ gọi ra hoặc hàm ondone hoặc hàm
onerror của bạn khi yêu cầu hoàn tất. Vì cá thể này sử dụng responseType, JSON,
nó sẽ gọi hàm ondone với dữ liệu JSON được dịch sang thành một hệ phân cấp các
đối tượng Javascript thực tế tương ứng với các đối tượng JSON mà bạn đã chỉ rõ
trong stockList.jsp.
UpdateStockPrices() tự nó chạy qua mảng các đối tượng chứng khoán, tìm kiếm
mỗi hàng của từng mã chứng khoán trong bảng chứng khoán và cập nhật giá cổ
phiếu của nó (và tổng tiền bằng đồng đô la nếu người sử dụng sở hữu các cổ phiếu
của mã chứng khoán này), bằng cách sử dụng setTextValue() giống như là với kết
quả buôn bán. Xem Tải về để biết thêm chi tiết.
Trang danh mục đầu tư đang hoạt động
Vào lúc này bạn có thể xem ứng dụng đang hoạt động. Vào trang vải nền của bạn,
đăng nhập vào hệ thống môi giới chứng khoán (qua LoginController), và trang
môi giới chứng khoán sẽ xuất hiện. Nó sẽ tạm ngừng một giây, sau đó bắt đầu cập
nhật giá cả và tính tổng số lên xuống của danh mục đầu tư trang này như Hình 2.
Hình 2. Trang danh mục đầu tư đang hoạt động
Nhập vào một số cổ phiếu của một mã chứng khoán để mua, nhấn Buy/Sell, và
quan sát cuộc mua bán trên được phản ánh trên hàng đó như trong Hình 3.
Hình 3. Trang danh mục đầu tư sau một cuộc mua bán
Cuộc mua bán cũng gửi cho bạn một thông báo Facebook, như bạn có thể thấy
trong trang Các thông báo của bạn (xem Hình 4).
Hình 4. Các thông báo mua bán
Và cuộc mua bán cũng gửi đi một hành động đến Nguồn cấp nhỏ của bạn (xem
Hình 5) và có thể là đến các Nguồn cung cấp tin tức của bạn bè của bạn (tùy thuộc
vào một thuật toán chưa biết).
Hình 5. Hành động Nguồn cấp tin mini các giao dịch mua bán
Đoạn cuối cùng của ứng dụng này là một liên kết trên mỗi hàng trong bảng chứng
khoán cho phép người sử dụng giới thiệu mã chứng khoán cho bạn bè trên
Facebook, bằng cách sử dụng một yêu cầu Facebook. Việc này đòi hỏi một trình
điều khiển PHP khác, đó là, RecommendStockToFriendsController (xem Mã
nguồn), nó đặt ID người sử dụng Facebook của người sử dụng, URL của ứng
dụng, và biểu tượng của tin điện báo giá thị trường chứng khoán (stock's ticker)
vào mô hình và biểu hiện khung nhìn recommendStockToFriendsView.php, như
Liệt kê 28.
Liệt kê 28. recommendStockToFriendsView.php
<?
$content = <<<FBML
<fb:name uid="$model['userId']
firstnameonly="true"
requests that you check out the hot stock "
<a
href="$model['appUrl']">$model['ticker'].
FBML;
?>
<fb:request-form
action=""
method="post"
invite="true"
type="Hot Stock"
content="">
<fb:multi-friend-selector
showborder="false"
actiontext="Invite your friends to check
out "/>
Thẻ tạo ra một mẫu biểu yêu cầu Facebook, mà khi được đệ
trình lên sẽ gửi một yêu cầu đến cho người sử dụng đã chỉ ra. Thuộc tính action
(hành động) chỉ rõ sẽ lấy người sử dụng từ đâu sau khi họ đệ trình yêu cầu hoặc
nhấn vào nút Skip (Bỏ qua). Thuộc tính phương thức sẽ chỉ rõ POST/GET như
thường lệ, và thuộc tính kiểu sẽ chỉ rõ tên của yêu cầu, sử dụng trên nút được biểu
hiện như nút đệ trình (submit button) của mẫu biểu . Thuộc tính
mời (invite) thay đổi một số lời văn sử dụng trên yêu cầu và nhãn của nút đệ trình.
Thuộc tính nội dung chứa nội dung để biểu hiện trong yêu cầu. Do nội dung là một
thuộc tính của một thẻ FBML tất cả các thực thể HTML phải được kèm dấu thoát,
giống như với htmlentities() ở đây. Nội dung của yêu cầu này chỉ cung cấp một
liên kết đến trang vải nền của ứng dụng, nhưng có thể làm bất cứ điều gì mà ứng
dụng của bạn có thể làm.
Có các loại thẻ cho phép người sử dụng chọn ra bạn bè để gửi yêu cầu đến họ --
một trong số thẻ bạn dùng ở đây là thẻ , sẽ xuất hiện ra
như là một danh sách cuộn của tất cả bạn bè của người sử dụng với một hộp tìm
kiếm gõ ký tự trước (typeahead) tiện dụng, như thấy trong Hình 6.
Hình 6. Mẫu biểu yêu cầu Giới thiệu Cho Bạn bè
Nhấn vào Skip sẽ đưa bạn trở lại trang danh mục đầu tư (như thuộc tính hành động
của đã xác định). Chọn một hay nhiều bạn bè và nhấn vào 'Send Hot
Stock Invitation' sẽ hiện ra một màn hình xác nhận yêu cầu (xem Hình 7).
Hình 7. Màn hình xác nhận yêu cầu
Nhấn Send sẽ gửi đi yêu cầu, và bạn bè của bạn sẽ trông thấy yêu cầu đó trên
trang Các yêu cầu của họ như thấy trong Hình 8.
Hình 8. Yêu cầu mà bạn bè sẽ nhìn thấy
Nội dung của yêu cầu này là nội dung được xác định trong phần Heredoc của
recommendStockToFriendsView.php.
Đưa vào cuộc sống
Bước cuối cùng là phát hành ứng dụng của bạn vào nơi chưa được khai phá. Vào
trang thiết đặt của ứng dụng của bạn, chuyển chế độ Dev sang off để những người
không phải là các nhà phát triển có thể thêm vào ứng dụng. Bạn sẽ cũng muốn tạo
ra một trang About tĩnh cho Danh mục Sản phẩm (Product Directory) (và làm sạch
một số chi tiết trong ứng dụng; ví dụ, hạn chế truy cập vào các tập tin và thư mục
khác nhau trong tập tin .htaccess), và sau đó nhấn vào liên kết Submit (xem Hình
9).
Hình 9. Nộp ứng dụng vào Product Directory
Sẽ có một vài trường để điền vào (và ứng dụng của bạn sẽ cần ít nhất 5 người sử
dụng trước khi nó có thể được gửi đến Danh mục Sản phẩm), nhưng sau đó ứng
dụng của bạn sẽ sẵn sàng để sử dụng công cộng.
Tóm tắt
Bạn đã đề cập đến nhiều nền móng cơ sở trong loạt bài hướng dẫn này, khi xây
dựng một ứng dụng Facebook đầy đủ từ nền đất trống bằng cả Java và PHP, nửa
Java chạy trong Máy chủ ứng dụng WebSphere của IBM và được phát triển bằng
cách sử dụng Rational Application Developer của IBM, nửa PHP chạy dưới Zend
Core for IBM; hai nửa này dùng chung một cơ sở dữ liệu IBM DB2. Bạn đã khám
phá các điểm tích hợp của Facebook và cách truy cập chúng từ cả PHP và Java
bằng cách sử dụng các thư viện khách, FBML và FBJS. Bây giờ bạn có thể phát
triển các ứng dụng Facebook của riêng bạn bằng cách sử dụng tất cả các công
nghệ này. Hãy chắc chắn theo kịp với blog và wiki của nhà phát triển Facebook vì
Facebook thay đổi API và chức năng được hỗ trợ trên đây khá thường xuyên. Hãy
tận hưởng các kỹ năng mới của bạn và hãy viết một ứng dụng nổi bật.
Các file đính kèm theo tài liệu này:
- Làm chủ việc phát triển ứng dụng Facebook bằng PHP, IBM Rational Application Developer, IBM WebSphe_.pdf