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, Nhà Phát triển, SmartStream Technologies Ltd
Tóm tắt: 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.
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
<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.
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
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
}
}
* 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.
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">
Đâ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 {
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];
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 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, 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