闲着没事,在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客户端方面有着深厚的兴趣并多少有一点儿经验。