Ajax - 请求参数作为XML发送send(xml)

请求参数作为XML发送

 

与几年前相比,当前浏览器上JavaScript的兼容性有了长足的进步,已经不可同日而语,再加上越来越成熟的JavaScript开发工具和技术,你可以决定把Web浏览器作为开发平台。并不只是依赖于浏览器来看待模型—视图—控制器模式中的视图,还可以用JavaScript实现部分业务模型。可以使用Ajax技术把模型中的变化持久存储到后台服务器。如果模型放在浏览器上,模型的变化可以一齐传递到服务器,从而减少对服务器的远程调用次数,还可能提高性能。
如果只是使用一个包含名/值对的简单查询串,这可能不够健壮,不足以向服务器传递大量复杂的模型变化。更好的解决方案是将模型的变化作为XML发送到服务器。怎么向服务器发送XML呢?
可以把XML作为请求体的一部分发送到服务器,这与 POST请求中将查询串作为请求体的一部分进行发送异曲同工。服务器可以从请求体读到XML,并加以处理。
下面的例子展示了对于一个Ajax请求如何向服务器发送XML。图3-5显示了这个页面,其中有一个简单的选择框,用户可以选择宠物的类型。这是一个相当简化的例子,但是由此可以了解如何向服务器发送XML。
图3-5  选择框中选中的项将作为XML发送到服务器
代码清单3-9显示了 postingXML.html
代码清单 3-9   postingXML.html
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
  "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title>Sending an XML Request</title>
 
<script type="text/javascript">
 
var xmlHttp;
 
function createXMLHttpRequest() {
    if (window.ActiveXObject) {
        xmlHttp = new ActiveXObject("Microsoft.XMLHTTP");
    }
    else if (window.XMLHttpRequest) {
        xmlHttp = new XMLHttpRequest();
    }
}
 
function createXML() {
    var xml = "<pets>";
    var options = document.getElementById("petTypes").childNodes;
    var option = null;
    for(var i = 0; i < options.length; i++) {
        option = options[i];
        if(option.selected) {
            xml = xml + "<type>" + option.value + "<//type>";
        }
    }
 
    xml = xml + "<//pets>";
    return xml;
}
 
function sendPetTypes() {
    createXMLHttpRequest();
 
    var xml = createXML();
    var url = "PostingXMLExample?timeStamp=" + new Date().getTime();
 
    xmlHttp.open("POST", url, true);
    xmlHttp.onreadystatechange = handleStateChange;
    xmlHttp. setRequestHeader("Content-Type", "application/x-www-form-urlencoded;");
    xmlHttp.send(xml);
}
 
function handleStateChange() {
    if(xmlHttp.readyState == 4) {
        if(xmlHttp.status == 200) {
            parseResults();
        }
    }
}
 
function parseResults() {
    var responseDiv = document.getElementById("serverResponse");
    if(responseDiv.hasChildNodes()) {
        responseDiv.removeChild(responseDiv.childNodes[0]);
    }
 
    var responseText = document.createTextNode(xmlHttp.responseText);
    responseDiv.appendChild(responseText);
}
 
 
</script>
</head>
<body>
  <h1>Select the types of pets in your home:</h1>
 
  <form action="#">
    <select id="petTypes" size="6" multiple="true">
        <option value="cats">Cats</option>
        <option value="dogs">Dogs</option>
        <option value="fish">Fish</option>
        <option value="birds">Birds</option>
        <option value="hamsters">Hamsters</option>
        <option value="rabbits">Rabbits</option>
  </select>
 
  <br/><br/>
  <input type="button" value="Submit Pets" οnclick="sendPetTypes();"/>
</form>
 
<h2>Server Response:</h2>
 
<div id="serverResponse"></div>
 
</body>
</html>
这个例子与前面的 POST例子基本上是一样的。区别在于,不是发送由名/值对组成的查询串,而是向服务器发送XML串。
点击表单上的Submit Pets(提交宠物)按钮将调用 sendPetTypes函数。类似于前面的例子,这个函数首先创建XMLHttpRequest对象的一个实例,然后调用名为 createXML的辅助函数,它根据所选的宠物类型建立XML串。
函数 createXML使用 document.getElementbyId方法获得 select元素的引用,然后迭代处理所有 option子元素,对于选中的每个 option元素依据所选宠物类型创建XML标记,并逐个追加到XML中。循环结束时,要在返回到调用函数( sendPetTypes)之前向XML串追加结束 pets标记。
一旦得到了XML串, sendPetTypes函数继续为请求准备XMLHttpObject,然后把XML串指定为 send()方法的参数,从而将XML发送到服务器。
createXML方法中,为什么结束标记中斜线前面有一个反斜线?
SGML规约(HTML就是从SGML发展来的)中提供了一个技巧,利用这个技巧可以识别出 script元素中的结束标记,但是其他内容(如开始标记和注释)则不能识别。使用反斜线可以避免把串解析为标记。即使没有反斜线,大多数浏览器也能安全地处理,但是根据严格的XHTML标准,应该使用反斜线。
聪明的读者可能注意到,根据XMLHttpRequest对象的文档, send()方法可以将串和XML文档对象实例作为参数。那么,这个例子为什么使用串连接来创建XML,而不是直接创建文档和元素对象呢?遗憾的是,对于从头构建文档对象,目前还没有跨浏览器的技术。IE通过ActiveX对象提供这个功能,Mozilla浏览器则通过本地JavaScript对象来提供,其他浏览器可能根本不支持,也可能通过其他途径来支持这个功能。
读取XML的服务器端代码如代码清单3-10所示,这个代码稍有些复杂。在此使用了Java servlet来读取请求,并解析XML串,不过你也可以使用其他的服务器端技术。
一旦收到 XMLHttpRequest 对象的请求,就会调用这个 servlet doPost 方法。 doPost 法使用名为 readXMLFromRequestBody的辅助方法从请求体中抽取XML,然后使用JAXP接口将XML串转换为 Document对象。
注意, Document对象是W3C指定的 Document接口的一个实例。因此,它与浏览器的 Document对象有着同样的方法,如 getElementsByTagName。可以使用这个方法来得到文档中所有 type元素的列表。对于文档中的每个 type元素,会得到文本值(应该记得,文本值是 type元素的第一个子节点),并逐个追加到串中。处理完所有 type元素后,响应串写回到浏览器。
代码清单 3-10   PostingXMLExample.java
package ajaxbook.chap3;
 
import java.io.*;
import javax.servlet.*;
import javax.servlet.http.*;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import org.w3c.dom.Document;
import org.w3c.dom.NodeList;
import org.xml.sax.SAXException;
 
public class PostingXMLExample extends HttpServlet {
 
    protected void doPost(HttpServletRequest request, HttpServletResponse response)
    throws ServletException, IOException {
 
        String xml = readXMLFromRequestBody(request);
        Document xmlDoc = null;
        try {
            xmlDoc =
                    DocumentBuilderFactory.newInstance().newDocumentBuilder()
                    .parse(new ByteArrayInputStream(xml.getBytes()));
        }
        catch(ParserConfigurationException e) {
            System.out.println("ParserConfigurationException: " + e);
        }
        catch(SAXException e) {
            System.out.println("SAXException: " + e);
        }
 
        /* Note how the Java implementation of the W3C DOM has the same methods
         * as the JavaScript implementation, such as getElementsByTagName and
         * getNodeValue.
         */
        NodeList selectedPetTypes = xmlDoc.getElementsByTagName("type");
        String type = null;
        String responseText = "Selected Pets: ";
        for(int i = 0; i < selectedPetTypes.getLength(); i++) {
            type = selectedPetTypes.item(i).getFirstChild().getNodeValue();
            responseText = responseText + " " + type;
        }
 
        response.setContentType("text/xml");
        response.getWriter().print(responseText);
    }
 
    private String readXMLFromRequestBody(HttpServletRequest request){
        StringBuffer xml = new StringBuffer();
        String line = null;
        try {
            BufferedReader reader = request.getReader();
            while((line = reader.readLine()) != null) {
                xml.append(line);
            }
        }
        catch(Exception e) {
            System.out.println("Error reading XML: " + e.toString());
        }
        return xml.toString();
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值