Ajax cho các nhà phát triển Java: Tuần tự hóa đối tượng Java cho Ajax 
Năm cách để tuần tự hóa dữ liệu trong các ứng dụng Ajax 
Philip McCarthy, Nhà Phát triển, SmartStream Technologies Ltd 
Tóm tắt: Nếu bạn đang tiến hành phát triển Web ™ bằng cách sử dụng 
JavaScript và XML không đồng bộ (Ajax), thì việc phân phát dữ liệu từ máy chủ 
cho máy khách có lẽ là mối quan tâm hàng đầu của bạn. Trong bài viết thứ hai 
trong loạt bài Ajax for Java developers này, Philip McCarthy cùng bạn qua năm 
cách tiếp cận để tuần tự hóa đối tượng Java và cung cấp cho bạn tất cả các thông 
tin bạn cần để chọn định dạng và công nghệ dữ liệu thích hợp tốt nhất cho ứng 
dụng của bạn. 
Trong bài viết đầu tiên của loạt bài này, tôi đã giới thiệu cho bạn các khối tạo 
dựng của Ajax: 
 Cách sử dụng một đối tượng JavaScript XMLHttpRequest để gửi một yêu 
cầu không đồng bộ tới một máy chủ từ một trang Web. 
 Cách xử lý và trả lời yêu cầu đó bằng một Java servlet trả về một tài liệu 
XML tới máy khách. 
 Cách sử dụng tư liệu trả lời đó trên máy khách để cập nhật khung nhìn 
trang của bạn. 
Bây giờ, tôi sẽ tiếp tục thảo luận về các quy tắc cơ bản về phát triển của Ajax, 
nhưng tôi sẽ tập trung vào những gì quan trọng nhất đối với nhiều nhà phát triển 
Web với Java: tạo dữ liệu cho máy khách. 
Hầu hết các nhà phát triển Java đã áp dụng mẫu Model-View-Controller (MVC-
Trình điều khiển-Khung nhìn-Mô hình) cho các ứng dụng Web của họ. Trong một 
ứng dụng Web truyền thống, thành phần khung nhìn gồm các JSP hoặc có lẽ là 
một công nghệ trình bày khác như các khuôn mẫu Velocity (Tốc độ). Những thành 
phần trình bày này cập nhật giao diện người dùng bằng cách tạo một cách động 
toàn bộ trang HTML mới để thay thế những gì mà người dùng đã thấy trước đó. 
Trong trường hợp của ứng dụng Java Web với một giao diện người dùng Ajax, tất 
nhiên mã khách JavaScript có trách nhiệm cuối cùng cập nhật những gì người 
dùng thấy, dựa vào dữ liệu được thu nhận để trả lời một XMLHttpRequest. Từ góc 
nhìn của máy chủ, khung nhìn này trở thành nơi biểu diễn dữ liệu mà nó sẽ gửi trả 
lời các yêu cầu của máy khách. 
Bài viết này tập trung vào các kỹ thuật mà bạn có thể dùng để tạo các khung nhìn 
ở giữa dữ liệu của các đối tượng Java của bạn. Tôi sẽ giải thích nhiều phương thức 
mà bạn có thể sử dụng để biến JavaBeans của bạn thành các tài liệu XML và bạn 
sẽ tìm hiểu những ưu và khuyết điểm của mỗi phương thức. Bạn cũng sẽ thấy tại 
sao XML không phải luôn luôn là cách thực hiện: chuyển văn bản thuần có thể là 
một sự lựa chọn thích hợp cho các yêu cầu Ajax đơn giản. Cuối cùng, tôi sẽ giới 
thiệu cho bạn về JavaScript Object Notation (JSON- Ký hiệu đối tượng 
JavaScript). JSON cho phép dữ liệu được truyền đi dưới dạng các đồ thị đối tượng 
JavaScript được tuần tự hóa, các đồ thị này rất dễ làm việc với mã phía máy 
khách. 
Về ví dụ này 
Tôi sẽ sử dụng một ứng dụng ví dụ và một số các trường hợp sử dụng để trình bày 
các tính năng và các kỹ thuật công nghệ được thảo luận tại đây. Hình 1 hiển thị mô 
hình dữ liệu vô cùng đơn giản để minh họa các trường hợp sử dụng trong ví dụ 
này. Mô hình này trình bày một tài khoản của khách hàng tại một cửa hàng trực 
tuyến. Khách hàng có một bộ sưu tập của các đơn đặt hàng trước đó và mỗi đơn 
hàng có một số mục.  
Hình 1. Một mô hình đối tượng đơn giản  
Mặc dù XMLHttpRequest không đặt ra bất kỳ các hạn chế nào về định dạng được 
sử dụng để gửi dữ liệu yêu cầu, đối với hầu hết các mục đích nó thích hợp để gửi 
các tham số biểu mẫu truyền thống, nên do đó, việc thảo luận của tôi tập trung vào 
trả lời của máy chủ. Câu trả lời này cũng có thể có bất kỳ định dạng dựa trên văn 
bản nào nhưng, như tên gọi của nó cho thấy, XMLHttpRequest có các khả năng 
gắn sẵn để xử lý dữ liệu trả lời XML. Điều này làm cho XML là sự lựa chọn mặc 
định cho các trả lời của Ajax, vì vậy nó là một nơi tốt để bắt đầu.   
Tạo XML từ các lớp Java 
Có rất nhiều lý do phân phát các trả lời của Ajax như XML: mỗi trình duyệt có 
khả năng Ajax có các phương thức điều hướng các tài liệu XML và cũng có rất 
nhiều công nghệ phía máy chủ làm việc với dữ liệu XML. Thật dễ dàng xác định 
cam kết giữa máy khách và máy chủ Ajax của bạn bằng cách tạo một lược đồ mô 
tả các kiểu tài liệu sẽ được trao đổi và nếu bạn có một cách tiếp cận hướng dịch vụ 
tới kiến trúc phía máy chủ của bạn, việc sử dụng XML cho phép các khách hàng 
không phải Ajax cùng dùng các nguồn cung cấp dữ liệu của bạn. 
Tôi sẽ xem xét ba trong những cách mà bạn có thể tạo dữ liệu XML từ các đối 
tượng Java của bạn và thảo luận về những ưu và khuyết điểm của mỗi cách.   
Tự tuần tự hóa 
Trước hết, bạn có thể tạo XML theo cách lập trình từ đồ thị đối tượng của bạn. 
Cách tiếp cận này có thể đơn giản như việc thực hiện một phương thức toXml() 
trong mỗi một trong các lớp JavaBean của bạn. Sau đó, bạn sẽ chọn một XML 
API và có một bean phát ra các phần tử để thể hiện trạng thái của nó và gọi đồ thị 
đối tượng xuống theo cách đệ quy tới các thành viên của nó. Rõ ràng, cách tiếp 
cận này không mở rộng tốt với một số lượng lớn các lớp vì mỗi một lớp cần có mã 
tạo XML riêng của mình được viết riêng cho nó. Ở phía trên, đó là một phương 
thức đơn giản thực hiện, không có bất kỳ chi phí hoạt động nào về cấu hình tăng 
thêm hay một quá trình xây dựng phức tạp hơn và bất kỳ đồ thị nào gồm 
JavaBeans của bạn có thể được chuyển thành một tài liệu XML với cặp các cuộc 
gọi. 
Trong đoạn mã ví dụ cho bài viết trước trong loạt bài này, tôi đã thực hiện các 
phương thức toXml() bằng cách gắn thêm chuỗi đánh dấu XML với nhau. Như tôi 
đã đề cập lúc trước, đây là một cách tiếp cận xấu vì nó đặt gánh nặng nhằm bảo 
đảm các thẻ được cân bằng, các thực thể được mã hóa v.v trên mỗi mã của phương 
thức toXml(). Một số các XML API có sẵn trên nền Java thực hiện tất cả công 
việc này cho bạn, cho phép tập trung vào nội dung của XML. Liệt kê 1 sử dụng 
JDOM API để thực hiện toXml() trên lớp đang thể hiện một đơn đặt hàng trong ví 
dụ cửa hàng trực tuyến (xem Hình 1).  
Liệt kê 1. Thực hiện JDOM của toXml () cho lớp đơn hàng  
public Element toXml() 
{ Element elOrder = new Element("order"); 
 elOrder.setAttribute("id",id); 
 elOrder.setAttribute("cost",getFormattedCost()); 
 Element elDate = new Element("date").addContent(date); 
elOrder.addContent(elDate); 
 Element elItems = new Element("items"); 
 for (Iterator<Item> iter = items.iterator() ; iter.hasNext(); ) 
 { elItems.addContent(iter.next().toXml()); } 
 elOrder.addContent(elItems); 
 return elOrder; 
}  
Ở đây bạn có thể thấy để tạo các phần tử, thiết lập các thuộc tính và thêm nội dung 
phần tử bằng cách sử dụng JDOM đơn giản như thế nào. Các cuộc gọi đệ quy đến 
các phương thức toXml() của JavaBeans đã kết hợp lại được thực hiện để nhận 
được các thể hiện Element (phần tử) của đồ thị con của chúng. Ví dụ, nội dung của 
các phần tử items được tạo ở đây bằng cách gọi toXml() trên mỗi đối tượng Item 
được tập hợp theo Order (đơn hàng) này. 
Một khi tất cả các JavaBeans của bạn thực hiện một phương thức toXml(), nó chỉ 
đơn giản là tuần tự hóa bất kỳ đồ thị tùy ý nào vào trong một tài liệu XML và trả 
nó về tới một máy khách Ajax, như trong Liệt kê 2.  
Liệt kê 2. Tạo một trả lời XML từ một phần tử JDOM  
public void doGet(HttpServletRequest req, HttpServletResponse res) 
throws java.io.IOException, ServletException { 
String custId = req.getParameter("username"); 
Customer customer = getCustomer(custId); 
Element responseElem = customer.toXml(); 
Document responseDoc = new Document(responseElem); 
res.setContentType("application/xml"); 
new XMLOutputter().output(responseDoc,res.getWriter()); }  
Một lần nữa JDOM lại khiến mọi việc ở đây thành đơn giản. Bạn chỉ cần bọc một 
Document quanh phần tử XML được đồ thị đối tượng trả về và sau đó sử dụng 
XMLOutputter để viết tài liệu đầy đủ cho trả lời servlet. Liệt kê 3 hiển thị một 
mẫu XML được tạo theo cách này, được định dạng kỹ lưỡng bằng cách khởi tạo 
XMLOutputter với Format.getPrettyFormat(). Trong ví dụ này, khách hàng chỉ có 
một đơn hàng với hai mục.  
Liệt kê 3. Tài liệu XML mẫu thể hiện một khách hàng  
<?xml version="1.0" encoding="UTF-8"?> 
<customer username="jimmy66"> 
<realname>James Hyrax </realname> 
<orders> 
 <order id="o-11123" cost="$349.98"> 
 <date>08-26-2005</date> 
 <items> 
 <item id="i-55768"> 
 <name>Oolong 512MB CF Card</name> 
 <description>512 Megabyte Type 1 CompactFlash card. 
 Manufactured by Oolong Industries</description> 
 <price>$49.99</price> 
 </item> 
 <item id="i-74491"> 
 <name>Fujak Superpix72 Camera</name> 
 <description>7.2 Megapixel digital camera 
 featuring six shooting modes and 3x optical zoom. Silver.</description> 
 <price>$299.99</price> 
 </item> 
 </items> 
 </order> 
</orders> 
</customer>  
Nhược điểm của việc tự tuần tự hóa 
Điều thú vị là, các mã trong Liệt kê 3 cho thấy một trong những hạn chế chính của 
việc có JavaBeans tự tuần tự hóa thành XML. Giả sử tài liệu này đã được sử dụng 
để giới thiệu một khung nhìn Order History (Lịch sử đơn hàng) cho khách hàng. 
Trong trường hợp đó, không chắc là bạn sẽ muốn hiển thị mô tả đầy đủ về mọi 
mục trong mỗi đơn hàng đã qua hoặc báo cho người sử dụng tên của họ. Nhưng 
nếu ứng dụng có một lớp ProductSearch trả về các kết quả tìm kiếm của nó như là 
một danh sách các bean Item, sẽ có ích nếu tính đến các mô tả có trong thể hiện 
XML của các Item. Hơn nữa, một trường bổ sung trên lớp Item thể hiện mức cổ 
phiếu hiện nay sẽ là thông tin có ích để hiển thị trong khung nhìn Product Search 
(Tìm kiếm sản phẩm). Tuy nhiên, sau đó trường này sẽ được tuần tự hóa từ bất kỳ 
đồ thị đối tượng nào có liên quan đến Item, dù có sự không thích hợp của mức cổ 
phiếu hiện tại với Order History của khách hàng. 
Từ một góc nhìn thiết kế, đây là một vấn đề kinh điển của mô hình dữ liệu đang 
được kết hợp với việc tạo khung nhìn. Mỗi bean chỉ có thể tự tuần tự hóa theo một 
chiều và cách tiếp cận một kích cỡ phù hợp cho tất cả có nghĩa là các tương tác 
Ajax kết thúc trao đổi dữ liệu mà chúng không cần, làm cho công việc mã khách 
hàng khó định vị các thông tin được yêu cầu từ tài liệu, cũng như làm tăng việc sử 
dụng băng thông và thời gian phân tích cú pháp XML ở phía máy khách. Hệ quả 
khác của việc kết hợp này là ngữ pháp XML không thể phát triển một cách độc lập 
với các lớp Java. Ví dụ, việc thực hiện thay đổi lược đồ tài liệu khách hàng có thể 
tác động đến một số lớp Java mà sau đó sẽ phải được sửa đổi và được biên dịch 
lại. 
Tôi sẽ tập trung vào các mối quan tâm này sau, nhưng trước tiên hãy xem xét một 
giải pháp cho các vấn đề mở rộng cách tiếp cận tự tuần tự hóa: các khung công tác 
liên kết XML.   
Các khung công tác liên kết XML 
Trong những năm gần đây, một số các Java API đã được phát triển để đơn giản 
hóa quá trình liên kết các tài liệu XML với các thể hiện đồ thị đối tượng Java. Hầu 
hết cung cấp cả hai cách sắp xếp theo thứ tự và không sắp xếp theo thứ tự XML, 
nghĩa là chúng thực hiện các chuyển đổi hai chiều giữa các đồ thị đối tượng Java 
và XML. Các khung công tác này chứa tất cả công việc xử lý XML, nghĩa là mã 
ứng dụng chỉ phải xử lý với các đối tượng thuần Java. Chúng cũng có xu hướng 
cung cấp các hàm phụ thuộc có ích như việc xác nhận tài liệu hợp lệ. Nói chung, 
các khung công tác này có hai phương thức tiếp cận khác nhau: tạo mã và ánh xạ 
đối tượng tới XML. Tôi sẽ giải thích cả hai. 
Cách tiếp cận tạo mã 
Các khung công tác liên kết sử dụng việc tạo mã gồm XMLBeans, JAXB, Zeus và 
JBind. Castor cũng có thể sử dụng kỹ thuật này. Điểm khởi đầu cho bất kỳ các 
khung công tác này là lược đồ XML mô tả các kiểu dữ liệu của các tài liệu của 
bạn. Sử dụng các công cụ được khung công tác cung cấp, sau đó bạn tạo các lớp 
Java để thể hiện các kiểu lược đồ được định nghĩa này. Cuối cùng, bạn viết ứng 
dụng của bạn bằng cách sử dụng các lớp được tạo này để thể hiện dữ liệu mô hình 
của bạn và tuần tự hóa chúng sang XML thông qua một số cơ chế thuận tiện do 
khung công tác tạo ra. 
Cách tiếp cận tạo mã là một cách tiếp cận tốt khi ứng dụng của bạn sử dụng một 
ngữ pháp XML lớn. Vấn đề mở rộng cách viết các phương thức tuần tự hóa XML 
tùy chỉnh qua hàng chục lớp biến mất. Mặt khác, bạn không còn bắt đầu định 
nghĩa JavaBeans của riêng bạn. Các lớp Java của khung công tác được tạo thường 
làm theo rất giống các cấu trúc của XML, có thể làm cho chúng hơi khó sử dụng 
để tạo mã lại. Ngoài ra, các lớp được tạo trở thành các thùng chứa dữ liệu câm vì 
bạn không thể thêm hành vi vào chúng. Nói chung, bạn cần phải thực hiện các 
thỏa hiệp trong mã ứng dụng của bạn để xử lý với các kiểu lược đồ được tạo. Khó 
khăn khác là một sự thay đổi trong lược đồ gây ra các thay đổi cho các lớp được 
tạo ra, lần lượt có một phản ứng dây chuyền cho bất kỳ mã nào mà bạn đã viết 
xung quanh chúng. 
Các khung công tác liên kết XML của kiểu này có ích nhất trong việc không sắp 
xếp dữ liệu theo thứ tự (ví dụ, sử dụng các tài liệu XML và chuyển đổi chúng 
thành các đối tượng Java). Trừ khi bạn có một mô hình dữ liệu rất lớn và sẽ được 
lợi từ các lớp đã tạo cho bạn, các khung công tác dựa trên việc tạo mã có thể phá 
hỏng một ứng dụng Ajax. 
Cách tiếp cận ánh xạ 
Các khung công tác sử dụng ánh xạ gồm Castor và Apache Commons Betwixt 
(Giữa các dữ liệu chia sẻ chung của Apache). Nói chung, việc ánh xạ thường là 
giải pháp linh hoạt và đơn giản hơn so với việc tạo mã. Trước tiên, bạn tạo mã 
JavaBeans của bạn như bạn thường làm gồm bất kỳ hành vi nào và mọi phương 
thức tiện ích mà bạn muốn. Sau đó, trong thời gian chạy, bạn gọi trình sắp xếp thứ 
tự (marshaler) dựa vào nội tại của khung công tác và nó tạo một tài liệu XML dựa 
trên các kiểu, các tên và các giá trị của các bộ phận của đối tượng của bạn. Bằng 
cách định nghĩa các tệp ánh xạ cho các lớp, bạn có thể ghi đè lên chiến lược liên 
kết mặc định và báo cho trình sắp xếp thứ tự cách bạn muốn các lớp của bạn được 
thể hiện trong XML. 
Cách tiếp cận này là một sự thỏa hiệp tốt đẹp giữa khả năng mở rộng và tính linh 
hoạt. Bạn bắt đầu viết các lớp Java của bạn theo cách bạn muốn chúng như thế và 
trình sắp xếp thứ tự tiết kiệm cho bạn khỏi xử lý với XML. Tuy nhiên, mặc dù các 
tệp định nghĩa ánh xạ chỉ đơn giản để viết và mở rộng hợp lý, các quy tắc ánh xạ 
chỉ có thể thay đổi rất nhiều hành vi liên kết tiêu chuẩn và một số mức kết nối giữa 
cấu trúc của các đối tượng của bạn và sự thể hiện XML của chúng sẽ luôn luôn giữ 
nguyên. Cuối cùng, bạn có thể phải thỏa hiệp hoặc thể hiện Java của bạn hoặc định 
dạng XML cho cách tiếp cận ánh xa tới công việc. 
Tóm tắt liên kết dữ liệu 
Dennis Sosnoski đã viết sâu về đề tài của các API liên kết dữ liệu XML với cả tính 
chất độc đáo của việc tạo mã lẫn ánh xạ mã. Tôi muốn giới thiệu các bài viết xuất 
xắc của ông trên Castor và trên các khung công tác tạo mã nếu bạn muốn nghiên 
cứu kỹ hơn lĩnh vực này (xem Tài nguyên để có các liên kết). 
Về tổng thể, cách tiếp cận tạo mã thỏa hiệp quá nhiều tính linh hoạt và sự thuận 
tiện có ích cho ứng dụng Ajax điển hình. Mặt khác, các khung công tác dựa trên 
ánh xạ có thể phục vụ tốt cho bạn, miễn là bạn có thể thay đổi các chiến lược ánh 
xạ của mình đủ để tạo XML mong muốn từ các đối tượng của bạn. 
Tất cả các API liên kết XML có chung một hạn chế lớn với kỹ thuật tuần tự hóa 
thủ công: việc kết nối của mô hình và khung nhìn. Việc bị hạn chế với chỉ một thể 
hiện XML của mỗi kiểu đối tượng có nghĩa là có khả năng luôn có một số dữ liệu 
dư thừa dịch chuyển trên mạng. Một vấn đề quan trọng hơn là mã khách không thể 
có một khung nhìn chuyên dụng khi tình hình đòi hỏi nó và có thể có một thời 
gian khó khăn khi cố gắng đối phó với khung nhìn một kích cỡ phù hợp với tất cả 
đã thỏa hiệp của đồ thị đối tượng cụ thể. 
Trong việc phát triển ứng dụng Web truyền thống, các hệ thống tạo khuôn mẫu 
trang được sử dụng để dễ dàng tách việc tạo khung nhìn khỏi logic của trình điều 
khiển và dữ liệu mô hình. Đây là một cách tiếp cận cũng có thể trợ giúp trong một 
kịch bản Ajax.   
Các hệ thống tạo khuôn mẫu trang 
Bất kỳ công nghệ tạo khuôn mẫu trang nào cũng có thể dùng để tạo XML, cho 
phép các ứng dụng Ajax tạo bất kỳ tài liệu trả lời XML nào từ các mô hình dữ liệu 
của chúng. Một lợi ích phụ là các khuôn mẫu có thể được viết bằng cách sử dụng 
ngôn ngữ đánh dấu đơn giản và truyền cảm, trái với lần lượt từ dòng này sang 
dòng khác của mã Java. Liệt kê 4 là một trang JSP có một bean Customer (khách 
hàng) và trả lại một khung nhìn XML tùy chỉnh thích hợp với mã khách hàng để 
tạo một thành phần Order History.  
Liệt kê 4. Một trang JSP tạo một tài liệu lịch sử đơn hàng  
<?xml version="1.0"?> 
<%@ page contentType="application/xml" %> 
<%@ taglib uri=" prefix="c" %> 
<c:set var="cust" value="${requestScope.customer}"/> 
<orderhistory username="${cust.username}"> 
<c:forEach var="order" items="${cust.orders}"> 
 <order id="${order.id}" cost="${order.formattedCost}"> 
 <date>${order.date}</date> 
 <items> 
 <c:forEach var="item" items="${order.items}"> 
 <item id="${item.id}"> 
 <name><c:out value="${item.name}" escapeXml="true"/></name> 
 <price>${item.formattedPrice}</price> 
 </item> 
 </c:forEach> 
 </items> 
 </order> 
</c:forEach> 
</orderhistory>  
Khuôn mẫu ngắn gọn này chỉ cung cấp dữ liệu cần thiết cho một khung nhìn Order 
History và không phải là những thứ thích hợp như là mỗi sự mô tả của mục. Nó sẽ 
giống như việc dễ dàng để tạo XML tùy chỉnh cho khung nhìn Product Search, 
gồm sự mô tả đầy đủ và mức cổ phiếu cho mỗi mục. 
Các sự cố với khuôn mẫu 
Mặt trái của vấn đề là ở chỗ bây giờ cần phải tạo một JSP mới cho mỗi khung nhìn 
khác nhau mà tôi yêu cầu, trái với việc chỉ lắp ráp đồ thị đối tượng cần thiết và 
tuần tự hóa nó. Từ một góc nhìn thiết kế, nhiều người cho rằng dù thế nào đi nữa 
đây là một điều tốt vì nó có nghĩa là sự suy nghĩ chính thức về các kiểu tài liệu mà 
máy chủ sẽ tạo. Ngoài ra, vì tôi bây giờ đang làm việc với một môi trường tạo 
khuôn mẫu chung chung và không phải là một API XML cụ thể, đó là trách nhiệm 
của tôi để đảm bảo chắc chắn các thẻ được cân bằng, thứ tự của phần tử và thuộc 
tính là chính xác và bất kỳ các thực thể XML nào (ví dụ < hay &) được thoát khỏi 
chương trình. Thẻ out của lõi JSP làm cho nhiệm vụ sau này dễ dàng, nhưng 
không phải tất cả các công nghệ tạo khuôn mẫu cung cấp một cơ chế như vậy. 
Cuối cùng, không có cách dễ dàng nào để xác nhận hợp lệ các tài liệu XML được 
tạo so với một lược đồ ở phía máy chủ, nhưng dù thế nào đi nữa đây không phải là 
điều mà bạn muốn làm trong một môi trường sản xuất và bạn có thể dễ dàng làm 
việc xung quanh nó trong quá trình phát triển.   
Dữ liệu trả lời không có XML 
Cho đến nay, tôi đã trình bày tất cả các kỹ thuật tạo trả lời của máy chủ dưới dạng 
một tài liệu XML. Tuy nhiên có một vài vấn đề với XML. Một trong những vấn đề 
này liên quan đến độ trễ. Các trình duyệt không phân tích cú pháp các tài liệu 
XML và tạo các mô hình DOM ngay lập tức và điều này có thể làm giảm cảm giác 
"sống động" cần thiết bởi một số thành phần Ajax, đặc biệt là khi phân tích cú 
pháp các tài liệu lớn trên máy tính chạy chậm hơn. Một ví dụ là "live search" (tìm 
kiếm trực tiếp), ở đây các kết quả tìm kiếm được lấy từ máy chủ và được hiển thị 
cho người dùng khi họ gõ vào các điều kiện tìm kiếm của họ. Đó là điều quan 
trọng đối với một thành phần tìm kiếm trực tiếp để trả lời một cách nhanh chóng 
cho đầu vào, nhưng đồng thời nó cần phải phân tích cú pháp các trả lời của máy 
chủ một cách nhanh chóng và liên tục. 
Độ trễ là một lý do quan trọng, nhưng lý do lớn nhất để tránh XML là một DOM 
API phía máy khách rất rắc rối. Liệt kê 5 cho thấy các vòng mà bạn thường phải 
nhảy qua để đạt tới một giá trị thông qua DOM, theo cách tương thích của trình 
duyệt giao nhau.  
Liệt kê 5. Chuyển hướng một tài liệu trả lời XML trong JavaScript  
// Find name of first item in customer's last 
order var orderHistoryDoc = req.responseXML; 
var orders = orderHistoryDoc.getElementsByTagName("order"); 
var lastOrder = orders[orders.length - 1]; 
var firstItem = lastOrder.getElementsByTagName("item")[0]; 
var itemNameElement = firstItem.firstChild; 
var itemNameText = itemNameElement.firstChild.data;  
Những điều trở nên phức tạp hơn khi có khoảng trống giữa các thành phần, vì lúc 
nào mỗi firstChild của phần tử sẽ là một nút văn bản khoảng trống. Các thư viện 
JavaScript sẵn sàng xử lí các tài liệu XML ít khó khăn hơn. Chúng gồm Sarissa 
(xem Tài nguyên), và Google-ajaXSLT, cả hai đều thêm các khả năng XPath cho 
hầu hết các trình duyệt. 
Tuy nhiên, thật đáng suy nghĩ về các sự lựa chọn. Ngoài responseXML, đối tượng 
XMLHttpRequest cung cấp một đặc tính có tên là responseText, đặc tính này chỉ 
cung cấp phần thân trả lời của máy chủ như là một chuỗi. 
Đặc tính responseText 
Đặc tính responseText đặc biệt thuận tiện khi máy chủ cần gửi các giá trị rất đơn 
giản cho máy khách, tránh các chi phí băng thông và các chi phí xử lý XML. Ví 
dụ, một trả lời đúng/sai đơn giản có thể được máy chủ trả về như là văn bản thuần, 
có thể là một danh sách có phân tách dấu phẩy đơn giản của các số hay các tên. 
Nói chung, tuy nhiên, tốt nhất là không trộn lẫn và phối hợp các trả lời XML và 
các trả lời văn bản thuần trong cùng ứng dụng; việc bám chặt vào chỉ một định 
dạng dữ liệu làm cho mã trừu tượng và việc tái sử dụng đơn giản hơn. 
responseText cũng có thể có ích về dữ liệu trả lời XML. Trong một kịch bản ở đó 
bạn chỉ cần lấy một giá trị từ một tài liệu trả lời, nó có thể thuận tiện hơn cho "sự 
lừa đảo", xử lý XML như là một chuỗi các văn bản chứ không phải là một tài liệu 
có cấu trúc. Ví dụ, Liệt kê 6 cho thấy cách một biểu thức chính quy có thể được sử 
dụng để lấy ra ngày tháng của đơn hàng đầu tiên trong Order History của khách 
hàng. Điều này thực sự chỉ là một nỗ lực thành công, mặc dù nhìn chung bạn 
không nên dựa vào sự thể hiện từ vựng của một tài liệu XML.  
Liệt kê 6. Sử dụng một biểu thức chính quy với đối tượng responseText của 
XMLHttpRequest  
var orderHistoryText = req.responseText; 
var matches = orderHistoryText.match(/<date>(.*?)<\/date>/); 
var date = matches[1];  
Sử dụng responseText trong mẫu đặc biệt này có thể thuận tiện trong một số 
trường hợp. Tất nhiên, lý tưởng là có một cách để thể hiện dữ liệu có cấu trúc, 
phức tạp trong một định dạng có thể dễ dàng được chuyển hướng trong JavaScript 
và không có các chi phí xử lý của XML. Như vận may sẽ có nó, giống như một 
định dạng tồn tại.   
Ký hiệu đối tượng JavaScript 
Dưới vỏ đậy này, các đối tượng JavaScript cho hầu hết các phần gồm các mảng 
kết hợp, các mảng được lập chỉ mục theo số lượng, các chuỗi, các số hoặc các kết 
hợp lồng nhau của các kiểu này. Vì tất cả các kiểu có thể được khai báo theo dạng 
chữ trong JavaScript, có thể định nghĩa tĩnh một đồ thị đối tượng trong một câu 
lệnh. Liệt kê 7 khai báo một đối tượng khi sử dụng cú pháp JSON và chỉ ra cách 
truy cập nó. Các dấu ngoặc móc biểu thị một mảng kết hợp (tức là một đối tượng), 
với cặp giá trị quan trọng của nó được phân tách bằng dấu phẩy. Các dấu ngoặc 
vuông biểu thị một mảng được lập chỉ mục theo số lượng.  
Liệt kê 7. Khai báo một đối tượng đơn giản theo dạng chữ trong JavaScript, 
khi sử dụng JSON  
var band = { name: "The Beatles", 
members: [{ name: "John", instruments: ["Vocals","Guitar","Piano"] }, 
{ name: "Paul", instruments :["Vocals","Bass","Piano","Guitar"] }, 
{ name: "George", instruments: ["Guitar","Vocals"] }, 
{ name: "Ringo", instruments: ["Drums","Vocals"] } ] }; 
// Interrogate the band object 
var musician = band.members[3]; 
alert( musician.name + " played " + musician.instruments[0] + "with " + 
band.name );  
Do JSON là một tính năng ngôn ngữ thú vị, nhưng với Ajax nó phải làm gì? Phần 
cuối của câu chuyện là bạn có thể sử dụng JSON để gửi một đồ thị đối tượng 
JavaScript qua mạng dưới dạng trả lời của máy chủ Ajax. Điều này có nghĩa là 
một sự thoát ra khỏi chuyển hướng XML trên máy khách thông qua DOM API 
bạn chỉ cần đánh giá câu trả lời JSON và bạn ngay lập tức có một đồ thị đối tượng 
JavaScript có thể truy cập. Tất nhiên, trước tiên cần chuyển JavaBeans của bạn 
thành JSON. 
Tạo JSON từ các lớp Java 
Những ưu điểm và nhược điểm giống nhau áp dụng cho các kỹ thuật tạo XML 
khác nhau cũng áp dụng để tạo JSON. Người ta cho rằng, có một trường hợp để sử 
dụng các công nghệ tạo lại khuôn mẫu trình bày. Tuy nhiên, việc sử dụng JSON 
kỹ hơn để chuyển các đối tượng được tuần tự hóa giữa các tầng ứng dụng hơn là 
để tạo một khung nhìn trạng thái của ứng dụng. Tôi sẽ chỉ cho bạn cách sử dụng 
Java API org.json để tạo các phương thức toJSONObject() trên các lớp Java của 
bạn. Rồi các JSONObject của bạn có thể được tuần tự hóa đơn giản tới JSON. Liệt 
kê 8 kiểm tra lại Liệt kê 1 từ cuộc thảo luận XML, hiển thị việc thực hiện 
toJSONObject() cho lớp Order.  
Liệt kê 8. Thực hiện phương thức toJSONObject () cho lớp Order  
public JSONObject toJSONObject() 
{ JSONObject json = new JSONObject(); 
 json.put("id",id); 
 json.put("cost",getFormattedCost()); 
 json.put("date",date); 
 JSONArray jsonItems = new JSONArray(); 
 for (Iterator<Item> iter = items.iterator() ; iter.hasNext() ; ) 
 { jsonItems.put(iter.next().toJSONObject()); } 
 json.put("items",jsonItems); return json; 
}  
Như bạn có thể thấy, API org.json rất đơn giản. JSONObject thể hiện một đối 
tượng JavaScript (tức một mảng kết hợp) và có các phương thức put() khác nhau 
lấy một khoá String và giá trị là một kiểu nguyên thủy, một kiểu String, hoặc một 
kiểu JSON khác. JSONArray thể hiện một mảng có lập chỉ mục, để cho phương 
thức put() của nó chỉ có một giá trị. Lưu ý rằng trong Liệt kê 8, một sự lựa chọn 
cho việc tạo mảng jsonItems và sau đó gắn nó vào đối tượng json với put() sẽ gọi 
json.accumulate("items",iter.next().toJSONObject()); cho mỗi mục. Phương thức 
accumulate() giống như put() trừ việc nó gắn thêm giá trị của mình cho một mảng 
có lập chỉ mục được xác định bằng khoá. 
Liệt kê 9 cho thấy cách để tuần tự hóa một JSONObject và viết nó vào một trả lời 
của servlet.  
Liệt kê 9. Tạo một trả lời JSON được tuần tự hóa từ một JSONObject 
 public void doGet(HttpServletRequest req, HttpServletResponse res) 
throws java.io.IOException, ServletException 
{ String custId = req.getParameter("username"); 
 Customer customer = getCustomer(custId); 
 res.setContentType("application/x-json"); 
 res.getWriter().print(customer.toJSONObject()); 
}  
Như bạn thấy, thực sự không có gì với nó. Phương thức toString() trên 
JSONObject, được gọi ngầm ở đây, thực hiện tất cả công việc. Lưu ý rằng kiểu nội 
dung application/x-json ít tin cậy tại thời điểm của bài viết này không có sự nhất 
trí nào về những gì mà kiểu MIME của JSON sẽ có. Tuy nhiên, application/x-json 
là một lựa chọn nhạy cảm trong lúc này. Liệt kê 10 hiển thị một ví dụ trả lời từ mã 
servlet này.  
Liệt kê 10. Thể hiện JSON của một bean Customer  
{ "orders": 
 [ { "items": 
 [ { "price": "$49.99", 
 "description": "512 Megabyte Type 1 CompactFlash card. 
 Manufactured by Oolong Industries", 
 "name": "Oolong 512MB CF Card", 
 "id": "i-55768" }, 
 { "price": "$299.99", 
 "description": "7.2 Megapixel digital camera featuring 
 six shooting modes and 3x optical zoom. Silver.", 
 "name": "Fujak Superpix72 Camera", 
 "id": "i-74491" } 
 ],  
 "date": "08-26-2005", 
 "cost": "$349.98", 
 "id": "o-11123" } 
 ],  
 "realname": "James Hyrax", 
 "username": "jimmy66" 
}  
Sử dụng JSON trên máy khách 
Bước cuối cùng trong tiến trình là chuyển dữ liệu JSON thành các đối tượng 
JavaScript trên máy khách. Điều này có thể được thực hiện bằng một cuộc gọi đơn 
giản tới eval(), hàm diễn giải các chuỗi có chứa các biểu thức JavaScript đang hoạt 
động. Liệt kê 11 chuyển đổi một trả lời của JSON thành đồ thị đối tượng 
JavaScript và sau đó thực hiện nhiệm vụ của Liệt kê 5 về việc nhận được tên của 
mục đầu tiên từ đơn hàng cuối cùng của khách hàng.  
Liệt kê 11. Đánh giá một trả lời của JSON  
var jsonExpression = "(" + req.responseText + ")"; 
var customer = eval(jsonExpression); 
// Find name of first item in customer's last order 
var lastOrder = customer.orders[customer.orders.length-1]; 
var name = lastOrder.items[0].name;  
So sánh với Liệt kê 11 với Liệt kê 5 minh họa sự thuận lợi cho máy khách khi sử 
dụng JSON. Nếu dự án Ajax của bạn liên quan đến rất nhiều việc chuyển hướng 
của các trả lời máy chủ phức tạp trên máy khách, thì JSON cũng hấp dẫn với bạn. 
Việc đặt JSON và XMLHttpRequest với nhau cũng tạo một sự khởi đầu tương tác 
Ajax trông giống như một cuộc gọi RPC hơn là một yêu cầu SOA, có thể có sự 
liên quan đến việc thiết kế ứng dụng của bạn. Trong bài viết tiếp theo, tôi sẽ xem 
xét các khung công tác được thiết kế rõ ràng để cho phép mã JavaScript thực hiện 
các cuộc gọi phương thức từ xa trên các đối tượng phía máy chủ. 
Nhược điểm của JSON 
JSON có nhược điểm của nó. Việc sử dụng cách tiếp cận JSON minh họa ở đây, 
không có cách nào để điều chỉnh sự tuần tự hóa của đối tượng trên cơ sở cho mỗi 
yêu cầu, vì vậy các trường không cần thiết thường có thể được gửi qua mạng. 
Ngoài ra, việc bổ sung thêm phương thức toJSONObject() cho mỗi JavaBean 
không mở rộng hơn, mặc dù nó sẽ hoàn toàn dễ hiểu để viết JavaBean chung cho 
một trình tuần tự hóa (serializer) JSON khi sử dụng xem xét nội tại và các chú 
thích. Cuối cùng, nếu mã phía máy chủ của bạn theo hướng dịch vụ và không biến 
đổi chỉ để xử lý các yêu cầu từ một máy khách Ajax, thì XML là một lựa chọn tốt 
hơn do sự hỗ trợ phổ biến của nó.   
So sánh các kỹ thuật tuần tự hóa 
Bây giờ bạn đã thấy năm kỹ thuật khác nhau để chuyển trạng thái phía máy chủ 
Java cho một máy khách Ajax. Tôi đã thảo luận sự tuần tự hóa XML với mã hóa 
thủ công riêng của bạn, liên kết XML qua việc tạo mã, liên kết XML thông qua 
một cơ chế ánh xạ, việc tạo XML dựa trên khuôn mẫu và cuối cùng tuần tự hóa 
mã hóa thủ công tới JSON. Mỗi cái có những lợi thế và bất lợi riêng của nó và phù 
hợp tốt nhất với các kiến trúc ứng dụng khác nhau. 
Trong một nỗ lực tổng kết những lợi ích và hạn chế của từng cách tiếp cận, Bảng 1 
gán các điểm số gần đúng theo sáu loại: 
Khả năng mở rộng 
Mô tả cách tiếp cận thích nghi với một số lượng lớn các kiểu dữ liệu tốt như 
thế nào. Liệu khối lượng công việc mã hóa và cấu hình của bạn sẽ tăng theo 
mỗi kiểu bổ sung không? 
Dễ dàng tích hợp 
Đánh giá cách đơn giản để tích hợp công nghệ vào dự án của bạn. Nó có 
đòi hỏi quy trình xây dựng phức tạp hơn không? Liệu nó làm tăng tính phức 
tạp triển khai không? 
API của lớp Java 
Mô tả cách dễ dàng làm việc với các đối tượng Java phía máy chủ được sử 
dụng trong cách tiếp cận này. Bạn có bắt đầu viết các bean thông thường 
không hoặc bạn sẽ phải làm việc với các thể hiện tài liệu rắc rối không? 
Kiểm soát đầu ra 
Mô tả bạn có thể kiểm soát việc thể hiện tuần tự hóa của các lớp của bạn 
chính xác như thế nào. 
Tính linh hoạt của khung nhìn 
Đánh giá xem sự tuần tự hóa dữ liệu có tùy chỉnh, khác nhau có thể được 
tạo từ cùng một tập các đối tượng. 
Truy cập dữ liệu khách 
Mô tả mã JavaScript làm việc với dữ liệu trả lời của máy chủ dễ dàng như 
thế nào. 
Bảng 1. Các hành động có liên quan của các kỹ thuật tạo dữ liệu  
Tự 
XML 
Liên kết 
XML qua 
việc tạo mã 
Liên kết 
XML qua 
ánh xạ 
XML tạo 
khuôn mẫu 
trang 
Tuần tự hóa 
JSSON mã hóa 
thủ công 
Khả năng mở 
rộng 
Kém Tốt Trung bình Trung bình Kém 
Dễ tích hợp Tốt Kém Trung bình Trung bình Tốt 
API của lớp 
Java 
Tốt Kém Tốt Tốt Tốt 
Kiểm soát 
đầu ra 
Tốt Tốt Trung bình Tốt Tốt 
Tính linh ho
ạt 
của khung 
nhìn 
Kém Kém Kém Tốt Kém 
Truy cập dữ 
liệu khách 
Kém Kém Kém Trung bình Tốt   
Kết luận 
Dữ liệu được biên dịch trong Bảng 1 không có ý muốn nói rằng bất kỳ trong số 
các công nghệ tuần tự hóa nào tốt hơn so với các công nghệ khác. Xét cho cùng, 
tầm quan trọng tương đối của mỗi một trong sáu loại phụ thuộc vào các chi tiết 
của dự án của bạn. Ví dụ, nếu bạn đang làm việc với hàng trăm kiểu dữ liệu, bạn 
muốn có khả năng mở rộng, vì thế việc tạo mã có lẽ là suy nghĩ tốt nhất của bạn. 
Nếu bạn cần phải tạo các khung nhìn khác nhau cho cùng một mô hình dữ liệu, 
việc tạo khuôn mẫu trang là cách thực hiện. Nếu bạn đang làm việc với một dự án 
quy mô nhỏ và muốn giảm bớt số lượng mã JavaScript mà bạn sẽ phải viết, hãy 
xem JSON. 
Hy vọng rằng bài viết này đã cho bạn những thông tin cần thiết để chọn một công 
nghệ tuần tự hóa phù hợp với ứng dụng của bạn. Xem phần Tài nguyên để tìm 
hiểu thêm về các công nghệ đã thảo luận tại đây. Bạn cũng nên để ý đến các phần 
tiếp theo của loạt bài này, ở đây tôi sẽ cho bạn thấy cách viết một ứng dụng Java 
Ajax bằng cách sử dụng Direct Web Remoting (DWR-Truy cập Web trực tiếp từ 
xa). Khung công tác DWR cho phép bạn gọi các phương thức trên các lớp Java 
của bạn trực tiếp từ mã JavaScript. Nói cách khác, nó sẽ giữ gìn công việc tuần tự 
hóa dữ liệu cho bạn để cho bạn có thể sử dụng Ajax ở một mức độ trừu tượng cao 
hơn.  
Mục lục  
 Tạo XML từ các lớp Java 
 Tự tuần tự hóa 
 Các khung công tác liên kết XML 
 Các hệ thống tạo khuôn mẫu trang 
 Dữ liệu trả lời không có XML 
 Ký hiệu đối tượng JavaScript 
 So sánh các kỹ thuật tuần tự hóa 
 Kết luận