PDF:

Ajax cho các nhà phát triển Java: Xây dựng các ứng
dụng Java động
Ajax mở đường cho các ứng dụng Web tốt hơn
Philip McCarthy ([email protected])
Nhà Phát triển
SmartStream Technologies Ltd
04 12 2009
Chu trình nạp lại-trang trình bày một trong những trở ngại của tiện ích lớn nhất trong việc phát
triển ứng dụng Web và là một thách thức quan trọng cho các nhà phát triển Java™. Trong loạt
bài này, tác giả Philip McCarthy giới thiệu một cách tiếp cận có tính đột phá để tạo ra những trải
nghiệm ứng dụng Web động. Ajax (Asynchronous JavaScript và XML) là một kỹ thuật lập trình
cho phép bạn kết hợp các công nghệ Java, XML và JavaScript cho các ứng dụng Web dựa trên
Java để ngắt mô hình nạp lại-trang.
Xem thêm bài trong loạt bài này
Ajax hoặc JavaScript và XML không đồng bộ, là một cách tiếp cận để phát triển ứng dụng Web có
sử dụng tạo kịch bản lệnh phía-khách để trao đổi dữ liệu với máy chủ Web. Kết quả là, các trang
Web được cập nhật động mà không phải làm mới toàn bộ trang khi ngắt luồng tương tác. Với Ajax,
bạn có thể tạo các giao diện người dùng ứng dụng Web động hơn, phong phú hơn để tiếp cận trực
tiếp và khả năng sử dụng các ứng dụng máy tính bản địa.
Ajax không là một công nghệ, nó còn hơn một mẫu -- một cách để nhận biết và mô tả một kỹ thuật
thiết kế có lợi. Về ý nghĩa nào đó Ajax là mới nên nhiều nhà phát triển chỉ đang bắt đầu nhận biết
về nó, nhưng tất cả các thành phần triển khai thực hiện một ứng dụng Ajax đã tồn tại trong nhiều
năm. Các tin đồn hiện nay là do sự nổi lên trong năm 2004 và 2005 của các giao diện người dùng
(UI) động quan trọng dựa vào công nghệ Ajax, đáng chú ý nhất là các ứng dụng GMail và Maps của
Google và trang chia sẻ hình ảnh Flickr. Các UI này đã có đủ tính đột phá được một số nhà phát
triển gọi là "Web 2.0", khiến người ta quan tâm nhiều đến ứng dụng Ajax.
Trong loạt bài này, tôi sẽ cung cấp cho bạn tất cả các công cụ mà bạn cần để bắt đầu phát triển các
ứng dụng riêng của bạn khi sử dụng Ajax. Trong bài viết đầu tiên này, tôi sẽ giải thích các khái niệm
đằng sau Ajax và trình diễn các bước cơ bản để tạo ra một giao diện Ajax cho ứng dụng Web dựa
trên Java. Tôi sẽ sử dụng các ví dụ mã để biểu thị cả mã Java phía máy chủ lẫn mã JavaScript phía
máy khách để tạo ra các ứng dụng Ajax động. Cuối cùng, tôi sẽ chỉ ra một số khó khăn của cách
© Copyright IBM Corporation 2009
Ajax cho các nhà phát triển Java: Xây dựng các ứng dụng Java
động
Nhẫn hiệu đăng ký
Trang 1 của 14
developerWorks®
ibm.com/developerWorks/vn/
tiếp cận Ajax, cũng như các khả năng sử dụng rộng hơn và về khả năng tiếp cận mà bạn cần cân
nhắc khi tạo các ứng dụng Ajax.
Một giỏ mua hàng tốt hơn
Bạn có thể sử dụng Ajax để nâng cao các ứng dụng Web truyền thống, sắp xếp hợp lý hóa tương
tác bằng cách loại bỏ việc nạp trang. Để giải thích điều này, tôi sẽ sử dụng các ví dụ đơn giản về một
giỏ mua hàng được tự động cập nhật khi các mục hàng được thêm vào giỏ. Được tích hợp trong cửa
hàng trực tuyến, cách tiếp cận này sẽ cho phép những người dùng tiếp tục duyệt và thêm các mục
hàng vào giỏ hàng của họ mà không cần phải chờ sau mỗi lần nhấp chuột để cập nhật một trang
đầy đủ. Trong khi một số mã trong bài viết này dành riêng cho ví dụ giỏ hàng, các kỹ thuật được
minh họa có thể được áp dụng cho bất kỳ ứng dụng Ajax nào. Liệt kê 1 cho thấy mã HTML được ví
dụ giỏ mua hàng này sử dụng. Tôi sẽ quay lại mã HTML này trong suốt bài viết.
Liệt kê 1. Các đoạn mã có liên quan của ví dụ giỏ mua hàng
<!-- Table of products from store's catalog, one row per item -->
<th>Name</th> <th>Description</th> <th>Price</th> <th></th>
...
<tr>
<!-- Item details -->
<td>Hat</td> <td>Stylish bowler hat</td> <td>$19.99</td>
<td>
<!-- Click button to add item to cart via Ajax request -->
<button onclick="addToCart('hat001')">Add to Cart</button>
</td>
</tr>
...
<!-- Representation of shopping cart, updated asynchronously -->
<ul id="cart-contents">
<!-- List-items will be added here for each item in the cart -->
</ul>
<!-- Total cost of items in cart displayed inside span element -->
Total cost: <span id="total">$0.00</span>
Chu trình vòng tròn (roundtrip) của Ajax
Một tương tác Ajax bắt đầu bằng một đối tượng JavaScript tên là XMLHttpRequest (Yêu cầu
XMLHttp). Như tên cho thấy, nó cho phép một kịch bản lệnh phía máy khách thực hiện các yêu cầu
HTTP và nó sẽ phân tích cú pháp câu trả lời của máy chủ XML. Bước đầu tiên trong chu trình vòng
tròn Ajax là tạo một cá thể XMLHttpRequest. Phương thức HTTP để sử dụng cho các yêu cầu (GET
hoặc POST) và URL đích sau đó được đặt trên đối tượng XMLHttpRequest.
Bây giờ, bạn có nhớ tại sao chữ a đầu tiên trong Ajax là chữ viết tắt của không đồng bộ
(asynchronous) không? Khi bạn gửi yêu cầu HTTP đó, bạn không muốn trình duyệt bị treo khi chờ
máy chủ trả lời. Thay vào đó, bạn muốn nó tiếp tục phản ứng lại với sự tương tác của người dùng
với trang đó và xử lý trả lời đến từ máy chủ. Để thực hiện việc này, bạn có thể đăng ký một hàm gọi
lại với XMLHttpRequest rồi gửi đi XMLHttpRequest không đồng bộ. Rồi kiểm soát các trả về tới trình
duyệt, trừ ra hàm gọi lại sẽ được gọi khi trả lời của máy chủ đến.
Ajax cho các nhà phát triển Java: Xây dựng các ứng dụng Java
động
Trang 2 của 14
ibm.com/developerWorks/vn/
developerWorks®
Trên máy chủ Web Java, yêu cầu đến giống như bất kỳ HttpServletRequest khác nào. Sau khi
phân tích cú pháp các tham số yêu cầu, servlet gọi logic ứng dụng cần thiết, tuần tự hóa trả lời của
nó thành XML và ghi nó vào HttpServletResponse.
Quay lại phía máy khách, hàm gọi lại được đăng ký trên XMLHttpRequest bây giờ được gọi để xử lý
tài liệu XML do máy chủ trả về. Cuối cùng, giao diện người dùng được cập nhật đáp lại dữ liệu từ
máy chủ, khi sử dụng JavaScript để thao tác HTML DOM của các trang. Hình 1 là một sơ đồ trình
tự của chu trình vòng tròn Ajax.
Hình 1. Chu trình vòng tròn Ajax
Bây giờ bạn có một khung nhìn mức cao về chu trình vòng tròn Ajax, tôi sẽ phóng to để xem xét chi
tiết hơn ở mỗi bước trên đường đi. Quay trở lại Hình 1 nếu bạn không tìm thấy vị trí của mình, trình
tự này không hoàn toàn dễ hiểu do tính chất không đồng bộ của cách tiếp cận Ajax.
Gửi đi một XMLHttpRequest
Tôi sẽ xuất phát tại điểm bắt đầu của trình tự Ajax: tạo và gửi đi một XMLHttpRequest từ trình duyệt.
Thật không may, phương thức để tạo ra một XMLHttpRequest khác với từ trình duyệt đến trình
duyệt. Hàm JavaScript trong Liệt kê 2 làm phẳng các nếp gấp phụ thuộc trình duyệt này, tìm ra
Ajax cho các nhà phát triển Java: Xây dựng các ứng dụng Java
động
Trang 3 của 14
developerWorks®
ibm.com/developerWorks/vn/
cách tiếp cận đúng cho trình duyệt hiện tại và trả về một XMLHttpRequest đã sẵn sàng để sử dụng.
Thật tốt để nghĩ về điều này như là mã soạn sẵn: chỉ cần chép nó vào trong thư viện JavaScript của
bạn và sử dụng nó khi bạn cần một XMLHttpRequest.
Liệt kê 2. Tạo một XMLHttpRequest của trình duyệt chéo
/*
* Returns a new XMLHttpRequest object, or false if this browser
* doesn't support it
*/
function newXMLHttpRequest() {
var xmlreq = false;
if (window.XMLHttpRequest) {
// Create XMLHttpRequest object in non-Microsoft browsers
xmlreq = new XMLHttpRequest();
} else if (window.ActiveXObject) {
// Create XMLHttpRequest via MS ActiveX
try {
// Try to create XMLHttpRequest in later versions
// of Internet Explorer
xmlreq = new ActiveXObject("Msxml2.XMLHTTP");
} catch (e1) {
// Failed to create required ActiveXObject
try {
// Try version supported by older versions
// of Internet Explorer
xmlreq = new ActiveXObject("Microsoft.XMLHTTP");
} catch (e2) {
// Unable to create an XMLHttpRequest with ActiveX
}
}
}
return xmlreq;
}
Sau đó, tôi sẽ thảo luận các kỹ thuật để xử lý các trình duyệt không hỗ trợ XMLHttpRequest. Bây
giờ, các ví dụ giả định rằng hàm newXMLHttpRequest từ Liệt kê 2 sẽ luôn luôn trả về một cá thể
XMLHttpRequest.
Quay trở lại kịch bản ví dụ giỏ mua hàng, tôi muốn gọi một sự tương tác Ajax bất cứ khi nào người
dùng nhấn vào nút Add to Cart (Thêm vào giỏ hàng) với một mục hàng. Trình xử lý (handler)
onclick có tên là addToCart() có trách nhiệm cập nhật trạng thái giỏ hàng thông qua một cuộc gọi
Ajax (xem Liệt kê 1). Như thể hiện trong Liệt kê 3, điều đầu tiên mà addToCart() cần làm là nhận
một cá thể XMLHttpRequest bằng cách gọi hàm newXMLHttpRequest() từ Liệt kê 2. Tiếp theo, nó
đăng ký một hàm gọi lại để nhận được trả lời của máy chủ (tôi sẽ giải thích chi tiết điều này sau;
xem Liệt kê 6).
Ajax cho các nhà phát triển Java: Xây dựng các ứng dụng Java
động
Trang 4 của 14
ibm.com/developerWorks/vn/
developerWorks®
Do yêu cầu này sẽ thay đổi trạng thái trên máy chủ, tôi sẽ sử dụng một HTTP POST để làm chứng
thư. Việc gửi dữ liệu thông qua POST yêu cầu ba bước. Đầu tiên, tôi cần phải mở một kết nối POST
tới nguồn tài nguyên của máy chủ mà tôi giao tiếp -- trong trường hợp này một servlet được ánh xạ
đến địa chỉ URL cart.do. Tiếp theo, tôi đặt ra một tiêu đề trên XMLHttpRequest để nói rằng nội dung
của yêu cầu là dữ liệu biểu mẫu có mã hóa. Cuối cùng, tôi gửi yêu cầu đó với dữ liệu biểu mẫu có
mã hóa làm phần thân.
Liệt kê 3 kết hợp các bước này lại với nhau.
Liệt kê 3. Gửi một XMLHttpRequest Thêm vào giỏ hàng
/*
* Adds an item, identified by its product code,
* to the shopping cart
* itemCode - product code of the item to add.
*/
function addToCart(itemCode) {
// Obtain an XMLHttpRequest instance
var req = newXMLHttpRequest();
// Set the handler function to receive callback notifications
// from the request object
var handlerFunction = getReadyStateHandler(req, updateCart);
req.onreadystatechange = handlerFunction;
// Open an HTTP POST connection to the shopping cart servlet.
// Third parameter specifies request is asynchronous.
req.open("POST", "cart.do", true);
// Specify that the body of the request contains form data
req.setRequestHeader("Content-Type",
"application/x-www-form-urlencoded");
// Send form encoded data stating that I want to add the
// specified item to the cart.
req.send("action=add&item="+itemCode);
}
Và ngay sau đó, bạn đã nhìn thấy phần đầu tiên của việc thiết lập chu trình vòng tròn Ajax -- cụ
thể là việc tạo ra và gửi đi yêu cầu HTTP từ phía máy khách. Tiếp theo là mã servlet Java được sử
dụng để xử lý yêu cầu này.
Xử lý yêu cầu servlet
Việc xử lý một XMLHttpRequest bằng một servlet phần lớn giống như việc xử lý một yêu cầu HTTP
thông thường từ trình duyệt. Dữ liệu biểu mẫu đã mã hóa được gửi trong phần thân của yêu cầu của
POST có thể được các cuộc gọi HttpServletRequest.getParameter() thu nhận. Các yêu cầu Ajax
tham gia vào HttpSession giống như các yêu cầu Web thông thường từ ứng dụng. Điều này có ích
cho kịch bản trong ví dụ giỏ mua hàng vì nó cho phép tôi tóm lược trạng thái giỏ hàng của người
dùng trong một JavaBean và vẫn tiếp tục trạng thái đó cho phiên làm việc giữa các yêu cầu.
Liệt kê 4 là một phần của một servlet đơn giản có xử lý các yêu cầu Ajax để cập nhật giỏ hàng. Một
bean Cart được lấy từ phiên làm việc của người dùng và trạng thái của nó được cập nhật theo các
tham số yêu cầu. Cart sau đó được tuần tự hóa tới XML và XML đó được ghi vào ServletResponse.
Ajax cho các nhà phát triển Java: Xây dựng các ứng dụng Java
động
Trang 5 của 14
developerWorks®
ibm.com/developerWorks/vn/
Quan trọng là thiết lập kiểu nội dung cho application/xml, nếu không XMLHttpRequest sẽ không
phân tích cú pháp nội dung trả lời trong một XML DOM.
Liệt kê 4. Mã servlet để xử lý các yêu cầu Ajax
public void doPost(HttpServletRequest req,
HttpServletResponse res)
throws java.io.IOException {
Cart cart = getCartFromSession(req);
String action = req.getParameter("action");
String item = req.getParameter("item");
if ((action != null)&&(item != null)) {
// Add or remove items from the Cart
if ("add".equals(action)) {
cart.addItem(item);
} else if ("remove".equals(action)) {
cart.removeItems(item);
}
}
// Serialize the Cart's state to XML
String cartXml = cart.toXml();
// Write XML to response.
res.setContentType("application/xml");
res.getWriter().write(cartXml);
}
Liệt kê 5 cho thấy một ví dụ về XML được phương thức Cart.toXml() tạo ra. Nó khá dễ
hiểu. Lưu ý thuộc tính generated (được tạo ra) trên phần tử cart, là một dấu thời gian được
System.currentTimeMillis() tạo ra.
Liệt kê 5. Ví dụ tuần tự hóa XML của đối tượng Cart
<?xml version="1.0"?>
<cart generated="1123969988414" total="$171.95">
<item code="hat001">
<name>Hat</name>
<quantity>2</quantity>
</item>
<item code="cha001">
<name>Chair</name>
<quantity>1</quantity>
</item>
<item code="dog001">
<name>Dog</name>
<quantity>1</quantity>
</item>
</cart>
Nếu bạn xem xét Cart.java trong mã nguồn ứng dụng có sẵn từ phần Tải về, bạn sẽ thấy rằng XML
được tạo ra đơn giản bằng cách gắn thêm các chuỗi lại với nhau. Khi chỉ vừa đủ cho ví dụ này, thị
việc này gần như cũng là cách xấu nhất để tạo ra XML từ mã Java. Tôi sẽ đề xuất một số cách tiếp
cận tốt hơn trong phần tiếp theo của loạt bài này.
Ajax cho các nhà phát triển Java: Xây dựng các ứng dụng Java
động
Trang 6 của 14
ibm.com/developerWorks/vn/
developerWorks®
Vì vậy, bây giờ bạn đã biết cách CartServlet đáp ứng với một XMLHttpRequest. Điều kế tiếp là trả
về phía máy khách, ở đó bạn có thể xem cách trả lời của XML được sử dụng để cập nhật trạng thái
trang.
Xử lý trả lời bằng JavaScript
Đặc tính readyState của XMLHttpRequest là một giá trị số cho trạng thái chu trình của yêu cầu.
Nó thay đổi từ 0 ứng với "chưa khởi động" đến 4 ứng với "hoàn thành". Mỗi khi readyState thay
đổi, sự kiện readystatechange bắt đầu thực hiện và gọi hàm trình xử lý được gắn kèm qua đặc tính
onreadystatechange.
Trong Liệt kê 3, bạn thấy cách hàm getReadyStateHandler() đã được gọi để tạo ra một hàm
trình xử lý. Hàm trình xử lý này sau đó đã được gán cho đặc tính onreadystatechange. Hàm
getReadyStateHandler() khai thác một thực tế rằng các hàm là đối tượng lớp đầu tiên trong
JavaScript. Điều này có nghĩa là các hàm có thể là các tham số cho các hàm khác và cũng có thể
tạo và trả về các hàm khác. Đây là công việc của getReadyStateHandler() để trả về một hàm kiểm
tra xem XMLHttpRequest đã hoàn thành chưa và chuyển trả lời XML lên hàm trình xử lý được trình
gọi xác định. Liệt kê 6 là mã cho hàm getReadyStateHandler().
Liệt kê 6. Hàm getReadyStateHandler ()
/*
* Returns a function that waits for the specified XMLHttpRequest
* to complete, then passes its XML response
* to the given handler function.
* req - The XMLHttpRequest whose state is changing
* responseXmlHandler - Function to pass the XML response to
*/
function getReadyStateHandler(req, responseXmlHandler) {
// Return an anonymous function that listens to the
// XMLHttpRequest instance
return function () {
// If the request's status is "complete"
if (req.readyState == 4) {
// Check that a successful server response was received
if (req.status == 200) {
// Pass the XML payload of the response to the
// handler function
responseXmlHandler(req.responseXML);
} else {
// An HTTP problem has occurred
alert("HTTP error: "+req.status);
}
}
}
}
Các mã trạng thái HTTP
Trong Liệt kê 6, đặc tính status (trạng thái) của XMLHttpRequest được thử nghiệm để xem
yêu cầu đó đã hoàn thành thành công chưa. status chứa mã trạng thái HTTP của trả lời của
máy chủ. Khi thực hiện các yêu cầu đơn giản GET và POST bạn có thể giả định rằng bất kỳ
Ajax cho các nhà phát triển Java: Xây dựng các ứng dụng Java
động
Trang 7 của 14
developerWorks®
ibm.com/developerWorks/vn/
mã nào khác 200 (OK) là một lỗi. Nếu máy chủ gửi một trả lời chuyển hướng (ví dụ, 301 hoặc
302), thì trình duyệt tiếp tục chuyển hướng trong suốt và tìm nguồn tài nguyên từ vị trí mới;
XMLHttpRequest không thấy mã trạng thái chuyển hướng. Ngoài ra, trình duyệt sẽ tự động
thêm một tiêu đề Cache-Control: no-cache cho tất cả các XMLHttpRequest, do đó
mã máy khách sẽ không bao giờ phải đối phó với trả lời máy chủ 304 (không đổi).
Về getReadyStateHandler()
là một đoạn mã tương đối phức tạp, đặc biệt là nếu bạn không sử dụng để
đọc JavaScript. Thỏa hiệp ở đây là việc đặt hàm này trong thư viện JavaScript, bạn chỉ có thể xử lý
các trả lời máy chủ Ajax mà không cần phải đối phó với các phần nội tại của XMLHttpRequest. Điều
quan trọng là bạn hiểu cách sử dụng getReadyStateHandler() trong mã của riêng mình.
getReadyStateHandler()
Trong Liệt kê 3, bạn thấy getReadyStateHandler() được gọi như sau: handlerFunction =
getReadyStateHandler(req, updateCart). Hàm được getReadyStateHandler() trả về trong trường
hợp này sẽ kiểm tra xem XMLHttpRequest trong biến req đã hoàn thành chưa và rồi gọi một hàm có
tên updateCart với XML trả lời.
Trích xuất dữ liệu giỏ hàng
Liệt kê 7 là mã updateCart() của chính nó. Hàm kiểm tra tư liệu XML giỏ mua hàng bằng cách sử
dụng các cuộc gọi DOM và cập nhật trang Web (xem Liệt kê 1) để phản ánh các nội dung giỏ hàng
mới. Ở đây tập trung vào các cuộc gọi được sử dụng để trích xuất dữ liệu từ XML DOM. Thuộc tính
generated (được tạo ra) trên phần tử cart (giỏ mua hàng), một dấu thời gian được tạo ra khi Cart
được tuần tự hóa theo XML, được kiểm tra để đảm bảo rằng dữ liệu giỏ hàng mới hơn không bị dữ
liệu giỏ hàng cũ ghi đè lên. Các yêu cầu Ajax vốn không đồng bộ, do đó việc kiểm tra này đảm bảo
an toàn đối với các trả lời từ máy chủ đến không theo trình tự.
Liệt kê 7. Cập nhật trang để phản ánh tư liệu XML của giỏ hàng
function updateCart(cartXML) {
// Get the root "cart" element from the document
var cart = cartXML.getElementsByTagName("cart")[0];
// Check that a more recent cart document hasn't been processed
// already
var generated = cart.getAttribute("generated");
if (generated > lastCartUpdate) {
lastCartUpdate = generated;
// Clear the HTML list used to display the cart contents
var contents = document.getElementById("cart-contents");
contents.innerHTML = "";
// Loop over the items in the cart
var items = cart.getElementsByTagName("item");
for (var I = 0 ; I < items.length ; I++) {
var item = items[I];
// Extract the text nodes from the name and quantity elements
var name = item.getElementsByTagName("name")[0]
.firstChild.nodeValue;
var quantity = item.getElementsByTagName("quantity")[0]
.firstChild.nodeValue;
Ajax cho các nhà phát triển Java: Xây dựng các ứng dụng Java
động
Trang 8 của 14
ibm.com/developerWorks/vn/
developerWorks®
// Create and add a list item HTML element for this cart item
var li = document.createElement("li");
li.appendChild(document.createTextNode(name+" x "+quantity));
contents.appendChild(li);
}
}
// Update the cart's total using the value from the cart document
document.getElementById("total").innerHTML =
cart.getAttribute("total");
}
Và ngay sau đó, hành trình có các lần dừng lại ngắn của chu trình vòng tròn Ajax hoàn thành, mặc
dù bạn có thể muốn nhận được ứng dụng Web đang chạy và xem nó hoạt động (xem phần Tải về).
Ví dụ này rất đơn giản, có nhiều phạm vi để cải tiến. Hiện tại tôi đã tính đến mã phía máy chủ để
loại bỏ các mục khỏi giỏ hàng, nhưng không có cách nào để truy cập nó từ giao diện người dùng.
Để có một bài tập tốt, hãy cố gắng cải thiện hơn mã JavaScript hiện có của ứng dụng để thực hiện
chức năng này.
Những thách thức của việc sử dụng Ajax
Như với bất kỳ công nghệ nào, có rất nhiều cách sai lầm với Ajax. Một số trong những vấn đề tôi
thảo luận ở đây hiện đang thiếu các giải pháp dễ dàng nhưng sẽ được cải tiến khi Ajax đã hoàn
thiện. Khi cộng đồng nhà phát triển thu được kinh nghiệm phát triển ứng dụng Ajax, các cách thực
hành và hướng dẫn tốt nhất sẽ được viết thành tài liệu.
Tính sẵn sàng của XMLHttpRequest
Một trong những vấn đề lớn nhất ở phía trước các nhà phát triển Ajax là cách trả lời khi
XMLHttpRequest chưa sẵn sàng. Trong khi đa số các trình duyệt hiện đại hỗ trợ XMLHttpRequest, sẽ
luôn có một số ít người dùng có trình duyệt của mình không hỗ trợ hay trình duyệt của họ thiết lập
bảo mật ngăn việc sử dụng XMLHttpRequest. Nếu bạn đang phát triển một ứng dụng Web được triển
khai trên một mạng nội bộ công ty, bạn có thể có đủ tiện nghi để xác định những trình duyệt nào
được hỗ trợ và giả định XMLHttpRequest luôn luôn có sẵn. Nếu bạn đang triển khai trên Web công
cộng, tất nhiên phải lưu ý rằng với cách quá tự tin vào XMLHttpRequest có sẵn, bạn đang có khả
năng ngăn người dùng sử dụng các trình duyệt cũ hơn, các trình duyệt cho người khuyết tật hoặc
trình duyệt đơn giản trên các thiết bị cầm tay sử dụng ứng dụng của bạn.
Vì vậy, bạn nên cố gắng để làm cho ứng dụng của bạn "giảm duyên dáng" đi và duy trì chức năng
trong các trình duyệt không hỗ trợ XMLHttpRequest. Trong ví dụ giỏ mua hàng, cách tốt nhất làm
giảm là ứng dụng sẽ có nút Add to Cart thực hiện gửi đi biểu mẫu thường xuyên, làm mới trang để
phản ánh trạng thái cập nhật của giỏ hàng. Hành vi của Ajax có thể được thêm vào trang thông qua
JavaScript một khi trang được nạp, gắn thêm một hàm trình xử lý JavaScript cho mỗi nút Add to
Cart chỉ khi XMLHttpRequest đã có sẵn. Một cách tiếp cận khác là để phát hiện XMLHttpRequest khi
người dùng đăng nhập vào và sau đó dùng hoặc làm một phiên bản Ajax của ứng dụng hoặc một
phiên bản dựa trên biểu mẫu thông thường khi thích hợp.
Các mối quan tâm về khả năng sử dụng
Một số vấn đề về khả năng sử dụng xung quanh các ứng dụng Ajax phổ biến hơn. Chẳng hạn, điều
quan trọng là cho người dùng biết rằng nguồn vào của họ đã được đăng ký, vì các cơ chế phản hồi
Ajax cho các nhà phát triển Java: Xây dựng các ứng dụng Java
động
Trang 9 của 14
developerWorks®
ibm.com/developerWorks/vn/
thông thường của con trỏ đồng hồ cát và việc quay tròn trình duyệt "throbber" không áp dụng cho
các XMLHttpRequest. Một kỹ thuật dùng để thay thế các nút Submit (Gửi đi) với một thông báo kiểu
" Now updating..." (Bây giờ đang cập nhật ...) để người dùng không liên tục nhấn vào các nút trong
khi chờ đợi trả lời.
Vấn đề khác là người dùng có thể không nhận thấy rằng các phần của trang mà họ đang xem đã
được cập nhật. Bạn có thể làm dịu bớt vấn đề này bằng cách sử dụng nhiều kỹ thuật trực quan để
thu hút một cách khôn khéo mắt của người dùng đến các vùng cập nhật của trang. Các vấn đề khác
do việc cập nhật các trang với Ajax gây ra bao gồm "phá vỡ" nút quay về của trình duyệt và URL
trong thanh địa chỉ không phản ánh toàn bộ trạng thái của trang, ngăn ngừa đánh dấu. Xem phần
Tài nguyên với các bài viết tập trung đặc biệt vào các vấn đề về khả năng sử dụng của các ứng
dụng Ajax.
Nạp máy chủ
Việc triển khai thực hiện một giao diện người dùng Ajax thay cho một giao diện người dùng theo
mẫu thông thường có thể làm tăng đáng kể số lượng các yêu cầu được thực hiện với máy chủ. Ví
dụ, một tìm kiếm Web của Google thường xuyên gây ra một sự truy cập vào máy chủ, xảy ra khi
người sử dụng gửi biểu mẫu tìm kiếm. Tuy nhiên, Google Suggest thường cố gắng tự động hoàn
thành thời hạn tìm kiếm của bạn, sẽ gửi một số các yêu cầu đến máy chủ như các kiểu người dùng.
Khi phát triển một ứng dụng Ajax, hãy có ý thức về việc bạn sắp gửi đến máy chủ bao nhiêu yêu
cầu và kết quả nạp máy chủ mà việc này sẽ gây ra. Bạn có thể làm giảm nhẹ việc nạp máy chủ bằng
cách tạo tầng đệm cho các yêu cầu trên máy khách và nhớ nhanh các trả lời của máy chủ trên máy
khách, khi thích hợp. Bạn cũng nên cố gắng thiết kế các ứng dụng Ajax Web của bạn để cho có thể
thực hiện càng hợp lí càng tốt trên máy khách, không cần phải liên lạc với máy chủ.
Đối phó với sự không đồng bộ
Để hiểu rằng không có một sự bảo đảm nào là các XMLHttpRequest sẽ hoàn thành theo thứ tự mà
chúng được gửi đi là rất quan trọng. Thật vậy, bạn nên cho rằng chúng sẽ không thực hiện theo thứ
tự và thiết kế ứng dụng của bạn với điều này trong tâm trí. Trong ví dụ giỏ mua hàng, một dấu cập
nhật thời gian cuối cùng đã được sử dụng để đảm bảo rằng dữ liệu giỏ mua hàng mới hơn sẽ không
bị dữ liệu cũ ghi đè (xem Liệt kê 7). Cách tiếp cận rất thô sơ này thực hiện cho kịch bản giỏ mua
hàng, nhưng không thể cho các kịch bản khác. Hãy xem xét tại thời điểm thiết kế bạn sẽ đối phó
với các trả lời của máy chủ không đồng bộ như thế nào.
Kết luận
Bây giờ bạn cần phải có một sự hiểu biết tốt về các nguyên tắc cơ bản của Ajax và một kiến thức
về các thành phần cơ bản của các thành phần phía máy khách và phía máy chủ có tham gia tương
tác Ajax. Đây là các khối tạo dựng của một ứng dụng Web Ajax dựa trên Java. Ngoài ra, bạn cũng
nên hiểu một số vấn đề thiết kế mức cao đi kèm tiếp cận Ajax. Việc tạo một ứng dụng Ajax thành
công đòi hỏi một cách tiếp cận toàn diện -- từ thiết kế giao diện người dùng thông qua thiết kế
JavaScript đến kiến trúc phía máy chủ -- nhưng bây giờ bạn nên được trang bị những kiến thức
Ajax lõi cần thiết để xem xét các khía cạnh khác này.
Đó là tin tốt nếu bạn đang cảm thấy nản lòng bởi sự phức tạp của việc viết một ứng dụng Ajax lớn
bằng cách sử dụng các kỹ thuật được thể hiện ở đây. Tùy theo các khung công tác như Struts,
Ajax cho các nhà phát triển Java: Xây dựng các ứng dụng Java
động
Trang 10 của 14
ibm.com/developerWorks/vn/
developerWorks®
Spring và Hibernate đã tiến triển tới việc phát triển ứng dụng Web trừu tượng cách xa khỏi các chi
tiết mức thấp của Servlet API và JDBC, do đó các bộ công cụ đang xuất hiện để phát triển Ajax dễ
dàng. Một số trong các khung công tác này chỉ tập trung vào phía khách, cung cấp các cách thức
dễ dàng để thêm các hiệu ứng trực quan vào các trang web của bạn hoặc sắp xếp hợp lý việc sử
dụng XMLHttpRequest. Các khung công tác khác tiến xa hơn, đưa ra các phương tiện để tự động
tạo các giao diện Ajax từ mã phía máy chủ. Các khung công tác này cố gắng để hoàn thành công
việc cho bạn, để bạn có thể tham gia một cách tiếp cận mức cao hơn để phát triển Ajax. Tôi sắp
xem xét một số trong số các khung công tác đó trong loạt bài này.
Cộng đồng Ajax đang phát triển nhanh và có rất nhiều thông tin có giá trị ngoài cộng đồng này.
Trước khi đọc bài viết tiếp theo trong loạt bài này, tôi khuyên bạn nên tham khảo các bài viết được
liệt kê trong phần tài nguyên, đặc biệt khi bạn mới bắt đầu đến với Ajax hoặc phát triển phía máy
khách. Bạn cũng nên dành một chút thời gian để nghiên cứu mã nguồn ví dụ và suy nghĩ về cách
để cải thiện nó.
Trong phần tiếp theo của loạt bài này, tôi sẽ thảo luận về API XMLHttpRequest chi tiết hơn và đề
xuất các cách để tạo ra XML dễ dàng từ JavaBeans của bạn. Tôi cũng sẽ cho bạn thấy các cách
lựa chọn XML để chuyển dữ liệu Ajax, chẳng hạn như định dạng trao đổi dữ liệu đơn giản JSON
(JavaScript Object Notation – Ký hiệu đối tượng JavaScript).
Ajax cho các nhà phát triển Java: Xây dựng các ứng dụng Java
động
Trang 11 của 14
developerWorks®
ibm.com/developerWorks/vn/
Các tải về
Mô tả
Tên
Kích thước
Sample code
j-ajax1.zip
8 KB
Ajax cho các nhà phát triển Java: Xây dựng các ứng dụng Java
động
Trang 12 của 14
ibm.com/developerWorks/vn/
developerWorks®
Tài nguyên
Học tập
• "Beyond the DOM" (Dethe Elza, developerWorks, 05.2005): Các kỹ thuật JavaScript có ích
để truy cập tài liệu XML.
• "Ajax cho các nhà phát triển Java: Tuần tự hóa đối tượng Java cho Ajax" (Philip McCarthy,
developerWorks, 10.2005): Tìm hiểu các cách tiếp cận tới tuần tự hóa dữ liệu trong các ứng
dụng Ajax.
• "Ajax cho các nhà phát triển Java: Ajax với Direct Web Remoting" (Philip McCarthy,
developerWorks, 11.2005): Tìm hiểu cách sử dụng Direct Web Remoting (DWR-Việc truy cập
trực tiếp Web từ xa).
• "Ajax và viết kịch bản lệnh các dịch vụ Web với E4X" (Paul Fremantle and Anthony Elder,
developerWorks, 04.2005): Sử dụng Ajax để thực hiện cuộc gọi SOAP trong các trình duyệt
có hỗ trợ phần mở rộng E4X JavaScript.
• "Ajax: Một cách tiếp cận mới vào các ứng dụng Web" (Jesse James Garrett, Adaptive Path,
02.2005): Các bài tham luận hội thảo đã cho Ajax tên của nó.
• Danh mục giải pháp kế hoạch chi tiết Java: Đưa ra tài liệu ứng dụng của Ajax với một số các
kịch bản ứng dụng Web phổ biến.
• AjaxPatterns.org: Một wiki bao gồm một vài kỹ thuật UI để cải thiện các giao diện ứng dụng
Ajax.
• Các hướng dẫn tiện ích XMLHttpRequest: Các gợi ý cho việc sử dụng Ajax để nâng cao kinh
nghiệm của người dùng.
• Các lỗi Ajax: Các vấn đề tiện ích mà các ứng dụng Ajax nên tránh.
• Vùng công nghệ Java: Tìm các bài viết về mọi khía cạnh của lập trình Java.
Lấy sản phẩm và công nghệ
• Mozilla Firefox: Trình kiểm tra DOM và mở rộng trình gỡ rối JavaScript bỏ nhiều công sức
ngoài sự phát triển Ajax.
Thảo luận
• developerWorks blogs: Dành tâm trí cho cộng đồng developerWorks.
Ajax cho các nhà phát triển Java: Xây dựng các ứng dụng Java
động
Trang 13 của 14
developerWorks®
ibm.com/developerWorks/vn/
Đôi nét về tác giả
Philip McCarthy
Philip McCarthy là nhà tư vấn phát triển phần mềm chuyên về các công nghệ Java
và Web. Ông hiện đang làm việc trong dự án nền tảng phương tiện kỹ thuật số của
Hewlett Packard tại HP Labs, Bristol. Trong những năm gần đây Phil đã phát triển một
số các khách hàng Web phong phú sử dụng truyền dẫn máy chủ không đồng bộ và
kịch bản lệnh DOM. Ông vui mừng vì chúng ta có một tên cho chúng. Bạn có thể liên
lạc với Phil tại [email protected].
© Copyright IBM Corporation 2009
(www.ibm.com/legal/copytrade.shtml)
Nhẫn hiệu đăng ký
(www.ibm.com/developerworks/vn/ibm/trademarks/)
Ajax cho các nhà phát triển Java: Xây dựng các ứng dụng Java
động
Trang 14 của 14