可以把XML作为请求体的一部分发送到服器,这与POST请求中将查询串作为请求体的一部分进行发送异曲
同工。服务器可以从请求体读到XML,并加以处理。
这个例子展示了对于一个Ajax请求如何向服务器发送XML。其中有一个选择框,用户可以选择宠物的
类型。通过这个例子可以了解如何向服务器发送XML。
下面是jsp代码:
<head>
<base href="<%=basePath%>">
<title>My JSP 'index.jsp' starting page</title>
<meta http-equiv="pragma" content="no-cache">
<meta http-equiv="cache-control" content="no-cache">
<meta http-equiv="expires" content="0">
<meta http-equiv="keywords" content="keyword1,keyword2,keyword3">
<meta http-equiv="description" content="This is my page">
<!--
<link rel="stylesheet" type="text/css" href="styles.css">
-->
<script language="javascript" type="text/javascript">
var XMLrequest = false;
try {
XMLrequest = new XMLHttpRequest();
} catch (trymicrosoft) {
try {
XMLrequest = new ActiveXObject("Msxml2.XMLHTTP");
} catch (othermicrosoft) {
try {
XMLrequest = new ActiveXObject("Microsoft.XMLHTTP");
} catch (failed) {
XMLrequest = false;
}
}
}
if (!XMLrequest) {
alert("Error initializing XMLHttpRequest!");
}
function parseResults() {
var responseDiv = document.getElementById("serverResponse");
if(responseDiv.hasChildNodes()){
responseDiv.removeChild(responseDiv.childNodes[0]);
}
var responseText = document.createTextNode(XMLrequest.responseText);
responseDiv.appendChild(responseText);
}
function updatePage() {
if (XMLrequest.readyState == 4) {
if (XMLrequest.status == 200) {
parseResults();
}
}
}
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(){
var xml = createXML();
var url = "PostingXMLExample?timeStamp="+new Date().getTime();
XMLrequest.open("POST",url,true);
XMLrequest.onreadystatechange = updatePage;
XMLrequest.setRequestHeader("Content-Type","application/x-www-form-urlencoded;");
XMLrequest.send(xml);
}
</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>
这个例子与POST例子基本上是一样的。区别在于,不是发送由名/值对组成的查询串,而是向服务器
发送XML串。
点击表单上的Submit Pets(提交宠物)按钮将调用sendPetTypes函数。这个函数调用名为createXML的
辅助函数,它根据所选的宠物类型建立XML串。
函数createXML使用document.getElementById方法获得select元素引用,然后迭代处理所 有option
子元素,对于选中的每个option元素依据所选宠物类型创建XML标记,并逐个追加到XML中。循环结束时,
要在返回调用函数(sendPetTypes)之前向XML串追加结束pets标记。
一旦得到了XML串,sendPetTypes函数继续为请求准备XMLHttpObject,然后把XML串指定为send()方法
的参数,从而将XML发送到服务器。
》在createXML方法中,为什么结束标记中斜线前面有一个反斜线?
使用反斜线可以避免把串解析为标记。即使没有反斜线,大多数浏览器也能安全地处理,但是根据严
格的XHTML标准,应该使用反斜线。
根据XMLHttpRequest 对象的文档,send()方法可以将串和XML文档对象实例作为参数。那么,这个例
子为什么使用串连接来创建XML,而不是直接创建文档和元素对象呢?遗憾的是,对于从头构建文档的对
象,目前还没有跨浏览器的技术。IE能过ActiveX对象提供这个功能,Mozilla浏览器则是通过本地
JavaScript对象来提供,其它浏览器可能根本不支持,也可能通过其他途径来支持这个功能。
一旦收到XMLHttpRequest对象的请求,就会调用这个servlet的doPost方法。doPost方法使用名为
readXMLFromRequestBody的辅助方法从请求体中抽取XML,然后使用JAXP接口将XML串转换为Document对象
。
注意Document对象是W3C指定的Document接口的一个实例。因此,它与浏览器的Document对象有着同
样的方法,如getElementsByTagName.可以使用这个方法来得到文档中所有type元素的列表。对于文档中
的每个type元素,会得以文本值,并逐个追加 到串中。处理完所有的type元素后,响应串写回到浏览器
。
下面是servlet代码:PostingXMLExample.java
public 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 (Exception e) {
System.out.println("ParserConfigruationException:"+e);
}
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);
}