2.2 发送请求 2.2.4 发送XML请求

2.2 发送请求 2.2.4 发送XML请求

对于请求参数为大量key-value对的情形,使用简单的POST请求比较合适。但对于某些极端的情形,如请求参数特别多,而且请求参数的结构关系复杂的情况,则可以考虑发送XML请求。**XML请求的实质还是POST请求,只是在发送请求的客户端页面将请求参数封装成XML字符串的形式**,服务器端则负责解析该XML字符串。当然,服务器获取XML字符串后,可借助于dom4jJDOM等工具来解析。

发送的XML请求实际上依然是POST请求,只是请求参数不再以param=value的形式被发送,而是直接采用XML字符串作为参数。这意味着服务器端不能直接获取请求参数,而是必须以流的形式获取请求参数.

实例

下面对前述的级联菜单应用进行简单修改,修改后的级联菜单允许一次选取多个国家。如果一次选取了多个国家,则服务器返回多个国家对应的城市—请求参数采用XML文档发送。
first.html

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
<!DOCTYPE html>
<html>
<head>
<meta name="author" content="Yeeku.H.Lee(CrazyIt.org)" />
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>发送XML请求</title>
<style type="text/css">
select {
width: 120px;
font-size: 11pt;
}
</style>
</head>
<body>
<!-- 支持多选的列表框 -->
<select name="first" id="first" size="5" multiple="multiple">
<option value="1" selected="selected">中国</option>
<option value="2">美国</option>
<option value="3">日本</option>
</select>
<!-- 用于发送Ajax请求的按钮 -->
<input type="button" value="发送" onClick="send();" />
<!-- 被级联改变的列表框 -->
<select name="second" id="second" size="5">
</select>
<script type="text/javascript">
String.prototype.trim = function() {
//移除首尾的空格
return this.replace(/^\s+/, "").replace(/\s+$/, "");
}
// 定义创建XML文档的函数
function createXML() {
// 开始创建XML文档,countrys是根元素
var xml = "<countrys>";
// 获取first元素的,并获取起所有的子节点(选项)
var options = document.getElementById("first").childNodes;
var option = null;
// 遍历国家下拉列表的所有选项
for (var i = 0; i < options.length; i++) {
option = options[i];
// 如果某个选项被选中
if (option.selected) {
// 在countrys的根节点下增加一个country的子节点
xml = xml + "<country>" + option.value
+ "<\/country>";
}
}
// 结束XML文档的根节点
// 在生成XML字符串时,为了避免系统对正斜杠(/)进行特殊处理,
// 使用了转义,即在正斜杠前增加反斜杠(\)。
xml = xml + "<\/countrys>";
// 返回XML文档
return xml;
}
// 1.创建XMLHttpRequest对象
var xhr = new XMLHttpRequest();
// 定义发送XML请求的函数
function send() {
// 2.定义请求发送的URL
var uri = "second.jsp";
// 3.打开与服务器连接
xhr.open("POST", uri, true);
// 4.设置请求头
xhr.setRequestHeader("Content-Type",
"application/x-www-form-urlencoded");
// 5.指定当XMLHttpRequest对象状态发生改变时触发processResponse函数
xhr.onload = processResponse;
// 6.发送XML请求
xhr.send(createXML());
}
// 定义处理服务器响应的回调函数
function processResponse() {
if (xhr.status == 200) {
// 获取服务器响应字符串,并以$作为分隔符分割成多个字符串
var cityList = xhr.responseText.split("$");
var displaySelect = document
.getElementById("second");
// 清空second下拉列表的选项
displaySelect.innerHTML = "";
for (var i = 0; i < cityList.length; i++) {
if (cityList[i].trim().length > 0) {
// 依次创建多个option元素
option = document.createElement("option");
option.innerHTML = cityList[i];
// 将创建的option元素添加到下拉列表最后
displaySelect.appendChild(option);
}
}
}
}
</script>
</body>
</html>

second.jsp:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
<%@ page contentType="text/html; charset=utf-8" language="java"%>
<%@ page
import="java.io.*,org.dom4j.*,org.dom4j.io.XPPReader,java.util.*"%>
<%
// 定义一个StringBuffer对象,用于接收请求参数
StringBuffer xmlBuffer = new StringBuffer();
String line = null;
// 通过request对象获取输入流
BufferedReader reader = request.getReader();
// 依次读取请求输入流的数据
while ((line = reader.readLine()) != null)
{
xmlBuffer.append(line);
}
// 将从输入流中读取到的内容转换为字符串
String xml = xmlBuffer.toString();
// 以Dom4J开始解析XML字串串
Document xmlDoc = new XPPReader()
.read(new ByteArrayInputStream(xml.getBytes()));
// 获得countrys节点的所有子节点
List countryList = xmlDoc.getRootElement().elements();
// 定义服务器响应的结果
String result = "";
// 遍历countrys节点的所有子节点
for (Iterator it = countryList.iterator(); it.hasNext();)
{
Element country = (Element) it.next();
// 如果发送的该节点的值为1,表明选中了中国
if (country.getText().equals("1"))
{
result += "上海$广州$北京";
}
// 如果发送的该节点的值为1,表明选中了美国
else if (country.getText().equals("2"))
{
result += "$华盛顿$纽约$加洲";
}
// 如果发送的该节点的值为1,表明选中了日本
else if (country.getText().equals("3"))
{
result += "$东京$大板$福冈";
}
}
// 向客户端发送响应
out.println(result);
%>