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()开始。如果交互是异步的,浏览器前继续执行页面事件(而不是中断用户当前动作去执行交互动作——译者注)。

解决方案 »

  1.   

    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>
      

  2.   

    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/
      

  3.   

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

  4.   

    THX
    xicheng_my_love(永华),许多句子不太明白的地方皆是经其指点才得以理解。
      

  5.   

    谢谢鼓励,现在正在翻译AJAX FAQ for the Java Developer,翻完发上来。
      

  6.   

    COOL,不过据说AJAX不支持中文,有这一说吗?
      

  7.   

    不支持中文?没听说,支持不支持要看客户端(JS)和服务器端(JAVA)支持不支持吧。没有不支持中文的道理吧。不知道“不支持中文”一说是怎么个不支持法,也好有针对性测试一下。
      

  8.   

    不错 正要准备学习一下呢 网上一直找不到好的中文资料。
    谢谢楼主了 呵呵收藏ing
      

  9.   

    楼主,建议你顺便发到csdn blog,bea中国社区,sun中国社区,javaresearch, javaeye等出名技术社区。
      

  10.   

    感觉有大有收获,正考虑web2.0的技术,包括ajax。
      

  11.   

    楼主要是能把文章整理一下,放到blog之类的就好了
    这个帖子里,内容被分割得四分五裂,不方便阅读
      

  12.   

    good!
    我昨天面试提到了这个,但是我不知道是什么东西,今天一找就有人翻译了, 厉害!但是我英文没你厉害, 能者多劳!
    整理下, 帖出来 大家一起品尝!
      

  13.   

    http://www.google.com/webhp?complete=1&hl=en