SUN的《AJAX与J2EE》全文

来源:互联网 发布:ubuntu服务器图形界面 编辑:程序博客网 时间:2024/04/30 12:35

 客户端所嵌入的页面特定的控制逻辑以JavaScript代码的形式存在。页面与JavaScript的交互建立在事件的基础上(比如文档加载事件、鼠标点击事件、焦点变化事件、甚至一个时钟事件)。AJAX清楚的将表示逻辑和数据分离开来、一个HTML网页能够在需要的时候获取以比特为单位的数据片段!这不同于以前的有一点变化就必须刷新整个页面的做法。同时AJAX也需要一种完全不同的服务端架构来支持这种交互模式。以前的传统服务端WEB应用专注于为每一个客户端的每一次请求生成HTML页面、每一次客户端接到响应都要刷新和重新渲染整个页面。而我们所谈的WEB应用专注于客户端把HTML文档当作模版或容器、客户端向其中插入内容、其原理就是每当客户端发生事件、客户端都可以向服务端发出请求并使用服务端返回的XML数据。

名为ValidateServlet的Servlet验证表单数据、但是要求不能对整个页面刷新。步骤如下:

1. A client event occurs.——客户端事件发生:
点击链接或表单元素的键盘事件引发JavaScript函数validate():
<input type="text"
            size="20"  
              id="userid"
            name="id"
         onkeyup="validate();">

2. A XMLHttpRequest object is created and configured.——一个XMLHttpRequest对象被创建并配置:
var req;
function validate() {
    var idField = document.getElementById("idField");
    var url = "validate?id=" + escape(idField.value);
    if (window.XMLHttpRequest) {
        req = new XMLHttpRequest();
    } else if (window.ActiveXObject) {
        req = new ActiveXObject("Microsoft.XMLHTTP");——创建XMLHttpRequest对象
    }
    req.open("GET", url, true);——调用XMLHttpRequest对象的open方法、url为所请求的服务端组件路径、true表示这个调用是异步的、

如果设置为异步就必须还要有一个callback函数如下:
    req.onreadystatechange = callback;
    req.send(null);
}

3. The XMLHttpRequest object makes a call.——XMLHttpRequest对象发出请求:

如果是GET请求那么内容可以为空、在url附加参数。
如果是POST请求那么就需要一个Content-Type头的设置如下:
req.setRequestHeader("Content-Type", "application/x-www-form-urlencoded");
req.send("id=" + escape(idTextField.value));

如果用JavaScript产生表单元素值、必须确保值编码的正确、JavaScript有一个escape()函数用于保障正确的编码、并把特定字符正确的忽略掉。

4. The request is processed by the ValidateServlet.——请求被ValidateServlet所处理:
servlet处理XMLHttpRequest就和处理其他HTTP请求一样:

public class ValidateServlet extends HttpServlet {   
    private ServletContext context;
    private HashMap users = new HashMap();
    public void init(ServletConfig config) throws ServletException {
        this.context = config.getServletContext();
        users.put("greg","account data");
        users.put("duke","account data");
    }
    public void doGet(HttpServletRequest request, HttpServletResponse  response)
        throws IOException, ServletException {

        String targetId = request.getParameter("id");

        if ((targetId != null) && !users.containsKey(targetId.trim())) {
            response.setContentType("text/xml");
            response.setHeader("Cache-Control", "no-cache");
            response.getWriter().write("valid"); 
        } else {
            response.setContentType("text/xml");
            response.setHeader("Cache-Control", "no-cache");
            response.getWriter().write("invalid"); 
        }
    }
}

5. The ValidateServlet returns an XML document containing the results.——ValidateServlet返回一个包含结果的XML文档。
ValidateServlet生成一个XML文档作为响应、更复杂的情况可能用到DOM、XSLT等。

    response.setContentType("text/xml");
    response.setHeader("Cache-Control", "no-cache");
    response.getWriter().write("invalid"); 
开发者必须了解两件事:第一:Content-Type必须设置为text/xml;第二:Cache-Control必须设置为no-cache。

6. The XMLHttpRequest object calls the callback() function and processes the result. 
——XMLHttpRequest对象调用callback()函数并处理结果。
XMLHttpRequest对象的准备状态有所变化的时候则调用callback()方法、我们假定已经请求完毕ValidateServlet、准备状态为4、表示XMLHttpRequest调用已经完成、HTTP状态码为200、表示HTTP交互已经成功。

function callback() {
    if (req.readyState == 4) {
        if (req.status == 200) {
            // update the HTML DOM based on whether or not message is valid
        }
    }
}
浏览器维护着一个文档的对象表示模型、既:DOM。网页中的JavaScript方法可以访问这个模型、并且可以在页面已经全部加载完成后再次改变这个模型。

使用JavaScript代码:req.responseXML可以得到服务端返回的XML文档、req为XMLHttpRequest对象、DOM为JavaScript提供了一种搜索文档内容以及根据搜索结果改变网页DOM的手段。可以使用req.responseText来访问返回的XML文档的字符串表示、如下所示:

 <message>
  valid
 </message>

上面的例子是一个简单的XML片段、实际应用可能包含更多:

function parseMessage() {
    var message = req.responseXML.getElementsByTagName("message")[0];
    setMessage(message.childNodes[0].nodeValue);
}

parseMessages()方法处理从服务端返回的XML文档、该方法使用message元素的值去调用setMessage()方法来改变HTML DOM。

7. The HTML DOM is updated.——HTML文档对象被更新。

JavaScript可以获得HTML DOM中任何元素(对象)的引用、推荐使用document.getElementById("userIdMessage")方法来获取。userIdMessage就是网页上任意元素的ID属性、有了元素(对象)的引用、JavaScript就可以改变这个元素的属性以及这个元素的样式属性、还可以增加删除或改变这个元素的子元素。通用的方法是设置innerHTML属性、如下所示:

<script type="text/javascript">
 function setMessage(message) {
     var userMessageElement = document.getElementById("userIdMessage");
     userMessageElement.innerHTML = "<font color=/"red/">" + message + " </font>";
 }
</script>
<body>
<div id="userIdMessage"></div>
</body>

innerHTML属性被改变以后网页可以立即体现出变化、如果innerHTML属性内部包含象<image>、<iframe>这样的元素、那么其所指定的资源内容一样被浏览器解析显示。

这种方法最大的缺点是在JavaScript代码里面难于以字符串形式书写HTML、内嵌于JavaScript中的HTML也难以看懂、维护和更改。另外的改变HTML DOM的方法是动态创建新元素然后将其作为子元素插入目标元素下、如下所示:

<script type="text/javascript">
 function setMessage(message) {
     var userMessageElement = document.getElementById("userIdMessage");
     var userIdMessageFont = document.getElementById("userIdMessageFont");
     var messageElement = document.createTextNode(message);
     if (userMessageElement.childNodes[0]) {
         // update the elements
         userIdMessageFont.replaceChild(messageElement, userIdMessageFont.childNodes[0]);
     } else {
         // create the new elements
         var fontElement = document.createTextNode("font");
         fontElement.setAtribute("id", "userIdMessageFont");
         fontElement.setAtribute("color", "red");
         userMessageElement.appendChild(fontElement);
         fontElement.appendChild(messageElement);
     }
 }
</script>
<body>
 <div id="userIdMessage"></div>
</body>

原创粉丝点击