閑著沒事,在SUN.COM上看到一篇AJAX的文章,感覺不錯,所以試著譯成了中文。許多地方自己也把握不也作者的意思,加上個人英文水平不咋地,可能許多不正確的地方,希望大家指正。
樣例安裝的一段沒有翻譯,感覺沒有必要~~(例子中沒有附JSTL包,要自己到APACHE下載安裝。)
原文地址:http://java.sun.com/developer/EJTechTips/2005/tt1122.html#1
by Greg Murray
作者:格雷格-默里
AJAX stands for Asynchronous JavaScript and XML. In essence, AJAX is an efficient way for a web application to handle user interactions with a web page -- a way that reduces the need to do a page refresh or full page reload for every user interaction. This enables rich behavior (similar to that of a desktop application or plugin-based web application) using a browser. AJAX interactions are handled asynchronously in the background. As this happens, a user can continue working with the page. AJAX Interactions are initiated by the JavaScript in the web page. When the AJAX interaction is complete, JavaScript updates the HTML source of the page. The changes are made immediately without requiring a page refresh. AJAX interactions can be used to do things such as validate form entries (while the user is entering them) using server-side logic, retrieve detailed data from the server, dynamically update data on a page, and submit partial forms from the page.
AJAX代表著異步的JAVASCRIPT和XML。本質上,AJAX是一種在WEB應用中通過網頁與用戶交互的有效方式,它減少了用戶交互中刷新頁面或整頁重載的頻率。這樣使用瀏覽器可以進行更豐富的動作(與桌面應用或基于PLUGIN的WEB應用相似)。AJAX交互在后臺異步執行,此時用戶可以繼續在這個頁面上工作。AJAX是由網頁中的JAVASCRIPT驅動的。當AJAX交互完成后,JS更新網頁HTML代碼。這個動作在不需要刷新頁面的情況下迅速執行。AJAX可以用于許多方面,例如在用戶輸入的同時用服務器端規則驗證其輸入,獲得服務器端詳細數據并主動更新頁面數據,或者提交頁面表單的部分數據。
What is particularly attractive about this is that AJAX applications do not require a separate plug-in, and are platform and browser-neutral. That said, AJAX is not supported as well in older browsers. Care needs to be taken in writing client-side script that accounts for the differences between browsers. You might consider using a JavaScript library that abstracts the browser differences and in some cases support older browsers using alternative interaction techniques. For more details, see the AJAX FAQ for the Java Developer
是什么讓AJAX技術具體如此魅力呢?AJAX應用不需用單獨的插件,并且是平臺和瀏覽器中立的。也就是說,AJAX并不被舊的瀏覽器良好支持。但是不必太過擔心,你可以撰寫跨不同瀏覽器的腳本。你應該考慮使用跨不同瀏覽器的JS庫并且在一些情況下有選擇性的使用交互技術以支持舊的瀏覽器。了解更多,請查看JAVA開發者的AJAX FAQ。http://weblogs.java.net/blog/gmurray71/
So Where Does Java Technology Fit In?
那么JAVA技術適合在哪兒使用呢?
Java technology and AJAX work well together. Java technology provides the server-side processing for AJAX interactions. It can provide this through servlets, JavaServer Pages (JSP) technology, JavaServer Faces (JSF) technology, and web services. The programming model for handling AJAX requests uses the same APIs that you would use for conventional web applications. JSF technology can be used to create reusable components that generate the client-side JavaScript and corresponding server-side AJAX processing code. Let's look at an example that uses AJAX and servlets.
JAVA技術與AJAX搭配使用非常不錯。JAVA技術為AJAX交互提供服務器端處理,通過servlets、JavaServer Pages (JSP)、JavaServer Faces (JSF) 及web服務。AJAX請求的編程模式使用與常規WEB應用相同的API。JSF技術可以用來創建可重用的組件,這些組件生成客戶端JS并與服務器端AJAX處理代碼通信。下面讓我們來看一個使用AJAX和SERVLETS的例子。
Autocomplete Example
實例:自動完成
Imagine a web page in which a user can search for information about an employee. The page includes a field where the user can enter the name of the employee. In this example the entry field has an autocomplete feature. In other words, the user can type in part of the employee name, and the web application attempts to complete the name by listing all employees whose first or last name begins with the characters entered. The autocomplete feature saves the user from having to remember the complete name of the employee or from looking for the name on another page.
假設用戶在一個網頁中搜索雇員信息。這個頁面包含一個輸入域,用戶在其中輸入雇員的名字。在這個例子中輸入域具有自動完成的功能。換句話說,用戶輸入雇員名的一部分,WEB應用通過列出所有姓名以輸入字母開頭的雇員來幫助完成輸入。自動完成功能讓用戶可以無需記住員工的全名或者從另一個頁面查找名字。(此句偶之前百思不得其解,后來經永華指點,大約是這樣的:你可以有三種方式查詢員工信息,1.記住員工的名字、2.從別的地方,比如其它頁面找到后復制粘貼過來,3.使用自動完成功能,很顯然,第三種是最省事的,優于其它方式,所以說3 SAVE FROM 1/2.)
Implementing autocomplete in a search field is something that can be performed using AJAX. To do it, you need to provide code on the client and on the server.
可以使用AJAX實現搜索輸入域的自動完成。要實現這個,需要撰寫相應的客戶端和服務器端代碼。
On the Client
客戶端
First, the user specifies the URL of a page that is loaded by the browser. For this example let's assume the page is an HTML page that is generated by a JSF component, servlet, or JSP page. The page contains a form text field that has an attribute onkeyup with the name of a JavaScript function doCompletion(). This function is called each time a key is pressed in the form text field.
首先,用戶打開一個網頁。假設這個頁面是一個由JSF組件、SERVLET或JSP產生的HTML頁面。頁面中包含一個表單文本域,它有一個ONKEYUP屬性,其值為一個JS函數doCompletion()。這個每當文本域有輸入改變,這個函數就會被調用。
<input type="text"
size="20"
autocomplete="off"
id="complete-field"
name="id"
onkeyup="doCompletion();">
Let's assume that a user types in an "M" character in the form text field. In response, the doCompletion() function is called which, in turn, initializes an XMLHttpRequest object:
假設用戶在表單文本域輸入字母M,doCompletion()將被調用,初始化一個XMLHttpRequest對象。
function initRequest(url) {
if (window.XMLHttpRequest) {
return new XMLHttpRequest();
} else if (window.ActiveXObject) {
isIE = true;
return new ActiveXObject("Microsoft.XMLHTTP");
}
}
function doCompletion() {
if (completeField.value == "") {
clearTable();
} else {
var url = "autocomplete?action=complete&id=" +
escape(completeField.value);
var req = initRequest(url);
req.onreadystatechange = function() {
if (req.readyState == 4) {
if (req.status == 200) {
parseMessages(req.responseXML);
} else if (req.status == 204){
clearTable();
}
}
};
req.open("GET", url, true);
req.send(null);
}
}
The XMLHttpRequest object is not currently part of standard JavaScript (efforts are underway to standardize it), but is a de facto standard and is the heart of AJAX. This object is responsible for interacting over HTTP with a server-side component (in this case, a servlet).
XMLHttpRequest對象現在還不是JS標準中的一部分(正在努力將其標準化),但它卻是事實上的標準并且是AJAX的核心。這個對象對于在HTTP協議上與服務器端組件(此例中是一個SERVLET)交互很可靠.
Three parameters are specified when you create an XMLHttpRequest object: a URL, the HTTP method (GET or POST), and whether or not the interaction is asynchronous. In the XMLHttpRequest example, the parameters are:
當創建XMLHttpRequest對象時需指定三個參數:一個URL,HTTP方式(GET或POST), 交互是否異步。在這個XMLHttpRequest 例子中,這些參數如下:
* The URL autocomplete, and the text from the complete-field (an M character):
*自動完成的URL和從輸入域鍵入的文字:
var url = "autocomplete?action=complete&id=" +
escape(completeField.value);
* GET, signifying the HTTP interactions uses the GET method, and true, signifying that the interaction is asynchronous:
*GET,表示HTTP交互使用GET方法;TRUE,表示交互是異步的:
req.open("GET", url, true);
A callback function needs to be set when you use asynchronous calls. This callback function is called asynchronously at specific points during HTTP interaction when the readyState property on the XMLHttpRequest changes. In the example the callback function is processRequest(). It's set as the XMLHttpRequest.onreadystatechange property to a function. Notice the call to the parseMessages function when the readState is "4". The XMLHttpRequest.readyState of "4" signifies the successful completion of the HTTP interaction.
當使用異步調用時,需要建立一個回調函數。HTTP交互中當XMLHttpRequest中的readyState屬性改變時,回調函數被異步調用。此例中回調函數是processRequest()。它為一個函數建立了一個XMLHttpRequest.onreadystatechange屬性。(前兩句還不太明白什么意思——譯者注)。注意當readyState為4時對parseMessages函數的調用。XMLHttpRequest.readyState為4意味著HTTP交互的成功完成。
The HTTP interaction begins when XMLHttpRequest.send() is called. If the interaction is asynchronous, the browser continues to process events in the page.
HTTP交互以調用XMLHttpRequest.send()開始。如果交互是異步的,瀏覽器前繼續執行頁面事件(而不是中斷用戶當前動作去執行交互動作——譯者注)。
On the Server
服務器端
The XMLHttpRequest makes an HTTP GET request to the URL autocomplete, which is mapped to a servlet called AutoComplete. The doGet() method of the AutoComplete servlet is called. Here is what the doGet() method looks like:
XMLHttpRequest為自動完成的URL產生了一個HTTP GET請求,這個URL被映射到一個名為AutoComplete的Servlet上。AutoComplete servlet的doGet() 方法被調用。這里的doGet()方法如下:
public void doGet(HttpServletRequest request,
HttpServletResponse response)
throws IOException, ServletException {
...
String targetId = request.getParameter("id");
Iterator it = employees.keySet().iterator();
while (it.hasNext()) {
EmployeeBean e = (EmployeeBean)employees.get(
(String)it.next());
if ((e.getFirstName().toLowerCase().startsWith(targetId) ||
e.getLastName().toLowerCase().startsWith(targetId))
&& !targetId.equals("")) {
sb.append("<employee>");
sb.append("<id>" + e.getId() + "</id>");
sb.append("<firstName>" + e.getFirstName() +
"</firstName>");
sb.append("<lastName>" + e.getLastName() +
"</lastName>");
sb.append("</employee>");
namesAdded = true;
}
}
if (namesAdded) {
response.setContentType("text/xml");
response.setHeader("Cache-Control", "no-cache");
response.getWriter().write("<employees>" +
sb.toString() + "</employees>");
} else {
response.setStatus(HttpServletResponse.SC_NO_CONTENT);
}
}
As you can see in this servlet, there is nothing really new you need to learn to write server-side code for AJAX processing. The response content type needs to be set to text/xml for cases where you want to exchange XML documents. With AJAX, you can also exchange plain text or even snippets of JavaScript which may be evaluated or executed by the callback function on the client. Note too that some browsers might cache the results, and so it might be necessary to set the Cache-Control HTTP header to no-cache. In this example, the servlet generates an XML document that contains all employees with a first or last name beginning with the character M. Here is an example of an XML document that is returned to the XMLHttpRequest object that made the call:
如你在SERVLET中所看到,不需要為寫服務器端AJAX處理代碼而學習新知識。當你想要發送XML文檔,只需將響應內容類型設置為text/xml。使用AJAX,你甚至可以發送普通文本或者小段JS代碼,這些代碼可能在客戶端被回調函數計算或執行。注意:一些瀏覽器可能將結果緩存,所以有必要設置Cache-Control HTTP header為no-cache。此例中,SERVLET產生一個XML文檔,它包含所有姓或名以M開頭的雇員的姓名。下面是一個返回給XMLHttpRequest對象的XML文檔例子:
<employees>
<employee>
<id>3</id>
<firstName>George</firstName>
<lastName>Murphy</lastName>
</employee>
<employee>
<id>2</id>
<firstName>Greg</firstName>
<lastName>Murphy</lastName>
</employee>
<employee>
<id>11</id><firstName>Cindy</firstName>
<lastName>Murphy</lastName>
</employee>
<employee>
<id>4</id>
<firstName>George</firstName>
<lastName>Murray</lastName>
</employee>
<employee>
<id>1</id>
<firstName>Greg</firstName>
<lastName>Murray</lastName>
</employee>
</employees>
Returning to the Client
再來看客戶端
When the XMLHttpRequest object that made the initial call receives the response, it calls the parseMessages() function (see the initialization of the XMLHttpRequest earlier in this example for more details). Here is what the parseMessages() function looks like:
當最初發送請求的XMLHttpRequest對象收到回應,它調用parseMessages() 函數(參見此例前面XMLHttpRequest的初始化)。這個函數如下:
function parseMessages(responseXML) {
clearTable();
var employees = responseXML.getElementsByTagName(
"employees")[0];
if (employees.childNodes.length > 0) {
completeTable.setAttribute("bordercolor", "black");
completeTable.setAttribute("border", "1");
} else {
clearTable();
}
for (loop = 0; loop < employees.childNodes.length; loop++) {
var employee = employees.childNodes[loop];
var firstName = employee.getElementsByTagName(
"firstName")[0];
var lastName = employee.getElementsByTagName(
"lastName")[0];
var employeeId = employee.getElementsByTagName(
"id")[0];
appendEmployee(
firstName.childNodes[0].nodeValue,
lastName.childNodes[0].nodeValue,
employeeId.childNodes[0].nodeValue);
}
}
The parseMessages() function receives as a parameter an object representation of the XML document returned by the AutoComplete servlet. The function programmatically traverses the XML document, and then uses the results to update the contents of the HTML page. This is done by injecting into a <div> element whose id is "menu-popup" the HTML source for the names in the XML document:
parseMessages() 函數接收AutoComplete servlet返回的XML文檔對象做為參數。該函數自動轉化XML文檔并更新網頁內容,通過在HTML源文件中為XML文檔中的姓名插入一個 id 為 "menu-popup"的DIV元素:
<div style="position: absolute;
top:170px;left:140px" id="menu-popup">
As the user enters more characters, the list shortens. The user can then click on one of the names.
當用戶輸入更多字符,姓名列表變短。用戶可以點擊要查找的姓名。
Hopefully by now you realize that AJAX is simply exchanging information over HTTP in the background of a page, and updating that page dynamically based on the results. For more information about AJAX and Java technology, see the technical article Asynchronous JavaScript Technology and XML (AJAX) With Java 2 Platform, Enterprise Edition. (http://java.sun.com/developer/technicalArticles/J2EE/AJAX/index.html)Also see the AJAX BluePrints page, (http://java.sun.com/blueprints/ajax.html)and the AJAX FAQ for the Java Developer in Greg Murray's blog. (http://weblogs.java.net/blog/gmurray71/)
希望現在你已經了解到AJAX如何在后臺簡單地交換信息以及在此基礎上動態地更新頁面。欲了解更多關于AJAX和JAVA技術,可以看這篇技術文章《Asynchronous JavaScript Technology and XML (AJAX) With Java 2 Platform, Enterprise Edition》(http://java.sun.com/developer/technicalArticles/J2EE/AJAX/index.html)。或者看AJAX藍圖http://java.sun.com/blueprints/ajax.html,或Greg Murray的博客中為JAVA開發者寫的AJAX FAQ。http://weblogs.java.net/blog/gmurray71/
About the Author
關于作者
Greg Murray is the servlet specification lead. Greg is a former member of the Java BluePrints team, and was responsible for the web tier recommendations. He is leading the AJAX effort at Sun with the help of the BluePrints team. Greg has experience with internationalization, web services, J2SE standalone clients, and AJAX-based web clients.
格雷格-默里是SERVLET規范領導。他曾是JAVA藍圖工作組會員,非常負責地對WEB TIER提出許多建議(或者是對XX負責)。在藍圖工作組的協助下他在SUN領導AJAX工作。格雷格在國際化、WEB服務、J2SE獨立客戶端和基于AJAX的WEB客戶端方面有著豐富的經驗。
About the Translater
關于譯者
Ahdong is wide-interested boy in China.Ahdong is a member of Network Creative Lab of Huaqiao University,and is responsible for the newbees' recommendations about learning.He is leading the software department at the lab with Younghua.Ahdong is interested in and has some experience with Linux,web development with JAVA or PHP,web standard,and AJAX-based web clients.
阿冬是一個興趣廣泛的中國男孩。他是華僑大學網絡創新實驗室的一員,負責任地對許多初學者提了許多中肯的建議。他和永華一起領導實驗室軟件部。阿冬在LINUX、PHP或JAVA WEB開發、WEB標準、基于AJAX的WEB客戶端方面有著深厚的興趣并多少有一點兒經驗。