ajax案例,servlet服务器端返回xml给客户端浏览器,客户端浏览器xmlHttpRequest.responseXML却等于null
我们要做的效果就是从服务器端取出城市集合,城市实体对象有城市id,城市名称,城市描述,城市图片这几个属性!
效果如图:点击ajax返回xml格式的数据,然后解析xml按钮,得到服务器数据!
在开发xml和ajax结合使用的时候,遇到一个问题,浏览器客户端中xmlHttpRequest.responseXML总是等于null
后来发现了问题所在?
原来是servlet中的代码有问题!看下图
就是response.setContentType("text/html;charset=utf-8");这行代码
导致了前端jsp页面获取xmlHttpRequest.responseXML总是等于null
所以我们可以在前端jsp页面中可以做些特殊处理
使用var cityList = parser.parseFromString(xmlHttpRequest.responseText,"text/xml");将文本格式转换成xml格式,
这样我们在客户端浏览器中就可以像操作xml一样操作cityList变量了,如下图:
以上方式是一种方式!
另外还有一种解决方式!
那就是修改servlet中的代码,把response.setContentType("text/html;charset=utf-8");这行代码修改成
response.setContentType("text/xml;charset=utf-8");修改完这行代码之后,我们在前端jsp页面就不需要做什么特殊的处理了,直接就xmlHttpRequest.responseXML就可以得到从服务器端返回的数据,得到的就是xml格式的数据,然后就可以在jsp页面中直接操作xml了!
对了,顺便补充一下,xml和字符串之间的转换!我在网上查了下资料,顺便贴一下吧,类似于java中的工具类,单独写了一个js文件!
xml.js文件如下:
/**
* xml工具
* xml对象和String字符串之间的转换
*
*/
//convert string to xml object (将字符串转换成xml对象)
function string2XML(xmlString) {
// for IE(IE浏览器)
if (window.ActiveXObject) {
var xmlObject = new ActiveXObject("Microsoft.XMLDOM");
xmlObject.async = "false";
xmlObject.loadXML(xmlString);
return xmlObject;
}
// for other browsers(火狐,谷歌浏览器等等)
else {
var parser = new DOMParser();
var xmlObject = parser.parseFromString(xmlString, "text/xml");
return xmlObject;
}
}
//convert xml object to string (将xml对象转换成字符串)
function xml2String(xmlObject) {
// for IE(IE浏览器)
if (window.ActiveXObject) {
return xmlObject.xml;
}
// for other browsers(火狐,谷歌浏览器等等)
else {
return (new XMLSerializer()).serializeToString(xmlObject);
}
}
以下是servlet的代码和jsp页面的代码
servlet名叫JsonCity
servlet代码如下:
package com.jiongmeng.servlet;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import com.jiongmeng.entity.City;
import net.sf.json.JSONArray;
/**
* json版省市联动
*/
@WebServlet(urlPatterns="/JsonCity", loadOnStartup=1)
public class JsonCity extends HttpServlet {
private static final long serialVersionUID = 1L;
public static Map<String, List<City>> provinces = new HashMap<String, List<City>>();
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
response.setContentType("text/html;charset=utf-8");
//设置返回文本的类型,设置输出信息的格式及字符集
// response.setContentType("text/xml;charset=utf-8");
PrintWriter pw = response.getWriter();
String provinceId = request.getParameter("provinceId");
String returnDataType = request.getParameter("returnDataType");
//得到省下面的所有市,是一个市数组或市集合
List<City> cityList = provinces.get(provinceId);
try {
Thread.sleep(3000);
} catch (InterruptedException e) {
e.printStackTrace();
}
if (returnDataType == null) {
//向浏览器客户端返回json数据格式
/*
* 将市数组或市集合,生成符合json规范的字符串返回给客户端,客户端通过javascript中的eval()函
* 数解析json,在客户端用javascript解析json就像java中操作对象一样方便,在客
* 户端用javascript通过.点操作符操作json
*/
// JSONObject JSONCitysStr = JSONObject.fromObject(cityList);
JSONArray JSONCitysStr = JSONArray.fromObject(cityList);
System.out.println(JSONCitysStr.isEmpty() + JSONCitysStr.toString());
pw.print(JSONCitysStr.toString());
pw.flush();
pw.close();
}
else {
System.out.println("******************xml字符串如下(返回给浏览器客户端)******************");
System.out.println("******************共有" + cityList.size() + "个元素******************");
pw.print("<?xml version=\"1.0\" encoding=\"UTF-8\"?>");
pw.print("<citys>");
System.out.println("<?xml version=\"1.0\" encoding=\"UTF-8\"?>");
System.out.println("<citys>");
//向浏览器客户端返回xml数据格式
for (City city : cityList) {
pw.print("<city>");
pw.print("<cityID>" + city.getCityId() + "</cityID>");
pw.print("<cityName>" + city.getCityName() + "</cityName>");
pw.print("<context>" + city.getContext() + "</context>");
pw.print("<imgPath>" + city.getImgPath() + "</imgPath>");
pw.print("</city>");
System.out.println("<city>");
System.out.println("<cityID>" + city.getCityId() + "</cityID>");
System.out.println("<cityName>" + city.getCityName() + "</cityName>");
System.out.println("<context>" + city.getContext() + "</context>");
System.out.println("<imgPath>" + city.getImgPath() + "</imgPath>");
System.out.println("</city>");
}
pw.print("</citys>");
System.out.println("</citys>");
}
}
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
doGet(request, response);
}
@Override
public void init() throws ServletException {
//模拟数据库中的数据(为了测试)
List<City> jiangxiCitys = new ArrayList<City>();
jiangxiCitys.add(new City("88", "赣州市", "黄金机场", "/img/jiangxi.jpg"));
List<City> ganzhouCitys = new ArrayList<City>();
ganzhouCitys.add(new City("8801", "于都县", "长征广场,长征大桥,长征第一渡", "/img/11.jpg"));
List<City> yuduCitys = new ArrayList<City>();
yuduCitys.add(new City("880101", "贡江镇", "古老的镇子", "/img/jiangxi.jpg"));
yuduCitys.add(new City("880102", "禾丰镇", "特产是珠子粉", "/img/jiangxi.jpg"));
yuduCitys.add(new City("880103", "祁禄山镇", "环境宜人", "/img/jiangxi.jpg"));
yuduCitys.add(new City("880104", "岭背镇", "风景优美", "/img/jiangxi.jpg"));
ganzhouCitys.add(new City("8802", "兴国县", "又名将军县,走出了100多位将军", "/img/10.jpg"));
ganzhouCitys.add(new City("8803", "信丰县", "赣南脐橙", "/img/13.jpg"));
ganzhouCitys.add(new City("8804", "上犹县", "玉龙湾", "/img/4.jpg"));
ganzhouCitys.add(new City("8805", "赣县", "赣县中学", "/img/18.jpg"));
ganzhouCitys.add(new City("8806", "大余县", "大余中学", "/img/15.jpg"));
ganzhouCitys.add(new City("8807", "会昌县", "会昌中学", "/img/19.jpg"));
jiangxiCitys.add(new City("66", "南昌市", "八一广场", "/img/jiangxi.jpg"));
jiangxiCitys.add(new City("57", "九江市", "胜利塔", "/img/jiangxi.jpg"));
jiangxiCitys.add(new City("92", "景德镇市", "景德镇瓷器名扬天下", "/img/jiangxi.jpg"));
jiangxiCitys.add(new City("26", "抚州市", "铜锣湾广场,凤凰世纪花城", "/img/jiangxi.jpg"));
jiangxiCitys.add(new City("32", "上饶市", "婺源文化与生态旅游区", "/img/jiangxi.jpg"));
jiangxiCitys.add(new City("33", "萍乡市", "秋收起义广场,武功山", "/img/jiangxi.jpg"));
List<City> guangdongCitys = new ArrayList<City>();
guangdongCitys.add(new City("106", "广州市", "广州塔小蛮腰", "/img/guangdong.jpg"));
List<City> guangzhouCitys = new ArrayList<City>();
guangzhouCitys.add(new City("10601", "越秀区", "面积33.80平方公里", "/img/guangdong.jpg"));
guangzhouCitys.add(new City("10602", "海珠区", "面积90.40平方公里", "/img/guangdong.jpg"));
guangzhouCitys.add(new City("10603", "荔湾区", "面积59.10平方公里", "/img/guangdong.jpg"));
guangzhouCitys.add(new City("10604", "天河区", "面积96.33平方公里", "/img/guangdong.jpg"));
guangdongCitys.add(new City("107", "深圳市", "南山区科技园", "/img/guangdong.jpg"));
guangdongCitys.add(new City("108", "中山市", "利和广场", "/img/guangdong.jpg"));
guangdongCitys.add(new City("109", "惠州市", "泗洲塔", "/img/guangdong.jpg"));
guangdongCitys.add(new City("110", "江门市", "汇悦城", "/img/guangdong.jpg"));
guangdongCitys.add(new City("111", "梅州市", "长乐学宫", "/img/guangdong.jpg"));
guangdongCitys.add(new City("112", "汕尾市", "凤山妈祖文化广场", "/img/guangdong.jpg"));
guangdongCitys.add(new City("113", "河源市", "桃花水母大剧院", "/img/guangdong.jpg"));
guangdongCitys.add(new City("114", "阳江市", "阳江国际金融中心", "/img/guangdong.jpg"));
guangdongCitys.add(new City("115", "清远市", "马踏飞燕", "/img/guangdong.jpg"));
guangdongCitys.add(new City("116", "茂名市", "希望之泉", "/img/guangdong.jpg"));
guangdongCitys.add(new City("117", "湛江市", "湛江海湾大桥", "/img/guangdong.jpg"));
List<City> zhejiangCitys = new ArrayList<City>();
zhejiangCitys.add(new City("192", "杭州市", "杭州西湖,杭州大剧院", "/img/zhejiang.jpg"));
zhejiangCitys.add(new City("193", "宁波市", "天一广场,天一阁", "/img/zhejiang.jpg"));
zhejiangCitys.add(new City("194", "温州市", "温州鹿城广场,温州大桥", "/img/zhejiang.jpg"));
zhejiangCitys.add(new City("195", "绍兴市", "八字桥,世茂天际中心", "/img/zhejiang.jpg"));
zhejiangCitys.add(new City("196", "嘉兴市", "嘉兴古运河,嘉兴范蠡湖", "/img/zhejiang.jpg"));
zhejiangCitys.add(new City("197", "衢州市", "金佰汇广场", "/img/zhejiang.jpg"));
zhejiangCitys.add(new City("198", "金华市", "梦幻谷,明清宫苑,秦王宫,横店,清明上河图", "/img/zhejiang.jpg"));
zhejiangCitys.add(new City("199", "台州市", "江南长城、长屿洞天、神仙居", "/img/zhejiang.jpg"));
List<City> nanchangCitys = new ArrayList<City>();
nanchangCitys.add(new City("200", "进贤县", "南昌市下面县", ""));
nanchangCitys.add(new City("201", "安义县", "南昌市下面县", ""));
provinces.put("1", jiangxiCitys);
provinces.put("2", guangdongCitys);
provinces.put("3", zhejiangCitys);
provinces.put("88", ganzhouCitys);
provinces.put("66", nanchangCitys);
provinces.put("8801", yuduCitys);
provinces.put("106", guangzhouCitys);
}
public List<City> getCitys(String provinceId) {
//得到省下面的所有市,是一个市数组或市集合
List<City> cityList = provinces.get(provinceId);
try {
Thread.sleep(3000);
} catch (InterruptedException e) {
e.printStackTrace();
}
return cityList;
}
}
jsp叫xmlAndAjax.jsp
jsp代码如下
<%@ page language="java" contentType="text/html; charset=utf-8"
pageEncoding="utf-8"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<title>xml在ajax中的应用</title>
<link rel="stylesheet" type="text/css" href="${pageContext.request.contextPath}/css/body.css">
<link rel="stylesheet" type="text/css" href="${pageContext.request.contextPath}/css/mark.css">
<link rel="stylesheet" type="text/css" href="${pageContext.request.contextPath}/css/console.css">
<script type="text/javascript" src="${pageContext.request.contextPath}/js/console.js"></script>
<script type="text/javascript" src="${pageContext.request.contextPath}/js/loading.js"></script>
<script type="text/javascript" src="${pageContext.request.contextPath}/js/weChatQRCode.js"></script>
<script type="text/javascript" src="${pageContext.request.contextPath}/My97DatePicker/WdatePicker.js"></script>
<script type="text/javascript" src="${pageContext.request.contextPath}/js/test.js"></script>
<script type="text/javascript" src="${pageContext.request.contextPath}/js/testVar.js"></script>
<script type="text/javascript" src="${pageContext.request.contextPath}/js/xml.js"></script>
<style type="text/css">
.myImg {
border-radius: 8px; /* 圆角 */
border: 5px solid #0000AA;
}
</style>
</head>
<body>
<center id="center">
eval()函数不太安全,比如:eval()函数解析文本框(input)中输入的非法的值(用户在文本框中输入了某些恶意的非法的javascript代码)
<a href="${pageContext.request.contextPath}/json.jsp?debug=okokok" target="_blank">
eval()函数解析文本框(input)中输入的非法的值(案例demo)
</a>
<h1>xml在ajax中的应用</h1>
<h2>(ajax从服务器端返回xml格式的数据,前端拿到xml格式的数据后进行解析)</h2>
<input id="ajaxXmlButton" onclick="getServerCityByProvinceId()" type="button" value="ajax返回xml格式的数据,然后解析xml"><br>
<hr id="myHr" style="border:2px solid black;">
<input type="button" value="打印外部js文件中的变量" onclick="printOutJsFileVar()">
<hr style="border:2px solid black;">
<form action="Test" method="get">
<h3>(测试使用post方式,地址栏后面不会显示参数,而使用get方式,地址栏后面会显示参数)</h3>
<h2>员工信息表,带一个隐藏域(form表单使用get方式提交)</h2>
用户名:<input type="text" name="userName" value="令狐冲"><br><br>
<input type="hidden" name="testHidden" value="tom">
薪水:<input type="text" name="money" value="29869.75"><br><br>
入职时间:<input class="Wdate" type="text" name="workDate" onfocus="WdatePicker({readOnly:true, lang:'zh-cn', dateFmt:'yyyy-MM-dd'})">
顺便测试下My97DatePicker日期控件<br><br>
<input type="submit" value="提交到名字叫Test的servlet中处理"><br><br>
</form>
<a href="${pageContext.request.contextPath}/my97DatePicker.jsp?debug=abc666" target="_blank">
My97DatePicker日期控件案例demo
</a>
<input type="button" value="查看浏览器是否禁用Cookie" onclick="testCookie()">
<br><br>
<a href="https://blog.csdn.net/judyge/article/details/51934292" target="_blank">
html中隐藏域hidden的作用介绍及使用示例
</a>
</center>
<br><br><br><br><br>
</body>
<script type="text/javascript">
var parser = new DOMParser();
//使用ajax,服务器端返回xml格式的数据
//回调函数
function ajaxAndXml() {
if (getConsole() || isInitConsole()) {
console.log("==========控制台已经初始化了" + getConsole() + "==========");
// 先清空一下控制台中的内容
myCleanConsole();
}
else{
console.log("==========控制台还没有初始化" + getConsole() + "==========");
document.getElementById("center").insertBefore(initConsole(), document.getElementById("myHr"));
}
if (xmlHttpRequest.readyState == 4 && xmlHttpRequest.status == 200) {
// var cityList = "" + xmlHttpRequest.responseText + "";
// var cityList = "" + xmlHttpRequest.responseText + "";
debug("xmlHttpRequest.responseXML=" + xmlHttpRequest.responseXML);
console.log("xmlHttpRequest.responseText=" + xmlHttpRequest.responseText);
// var cityList = xmlHttpRequest.responseXML;
var cityList = parser.parseFromString(xmlHttpRequest.responseText,"text/xml");
var rootNode = cityList.documentElement;
console.log("xml对象cityList=" + cityList);
// var xmlStr = (new XMLSerializer()).serializeToString(cityList);
var xmlStr = xml2String(cityList);
console.log("xml字符串cityList=" + xmlStr);
var cityArray = rootNode.getElementsByTagName("city");
var hrTag = "<hr style='height:5px;border:5px solid black;'>";
debug("<center><h1>从服务器端取数据,共有" + cityArray.length + "个元素</h1></center>");
var result = hrTag;
for (var index = 0; index < cityArray.length; index++) {
var cityId = cityArray[index].firstChild.firstChild.nodeValue;
var cityName = cityArray[index].firstChild.nextSibling.firstChild.nodeValue;
var cityContext = cityArray[index].getElementsByTagName("context")[0].firstChild.nodeValue;
var cityImgPath = cityArray[index].getElementsByTagName("imgPath")[0].firstChild.nodeValue;
result += "<span style='color:#CD0000;'>城市id:</span>" + cityId + "<br>";
result += "<span style='color:#CD0000;'>城市名称:</span>" + cityName + "<br>";
result += "<span style='color:#CD0000;'>城市描述:</span>" + cityContext + "<br>";
// var imgPath = "<img title='" + cityContext + "' src='" + "/ajax" + cityImgPath + "' style='width: 98%; height: 700px;'>";
var imgPath = "<img class='myImg' title='" + cityContext + "' src='" + "/ajax" + cityImgPath + "' style='width: 50%; height: 400px;'>";
result += "<span style='color:#CD0000;'>城市图片:</span><br>" + imgPath + hrTag;
}
debug("<center>" + result + "</center>");
//给控制台div层设置height高度
getConsole().style = "height: auto;";
//隐藏加载图片
hideLoading();
}
}
window.onload = function() {
createFollowWeChatQRCodeElement();
var centerNode = document.getElementById("center");
// var ajaxXmlButtonNode = document.getElementById("ajaxXmlButton");
var hrNode = document.getElementById("myHr");
//还未初始化控制台div层
if (!isInitConsole()) {
console.log("**********还未初始化控制台div层" + getConsole() + "**********");
// debug("<hr>");
console.log(centerNode + " / " + getConsole());
// centerNode.insertBefore(initConsole(), ajaxXmlButtonNode);
centerNode.insertBefore(initConsole(), hrNode);
// document.body.insertBefore(initConsole(), document.body.firstChild);
}
else{
console.log("**********控制台div层已经初始化了" + getConsole() + "**********");
//控制台div层已经初始化了
centerNode.insertBefore(getConsole(), hrNode);
}
// getServerCityByProvinceId();
}
//打印外部js文件中的变量
function printOutJsFileVar() {
var hrTag = "<hr style='height:5px;border:5px solid #CD0000;'>";
var spanStartTag = "<span style='color: #0000AA;font-size: 32px;'>";
var spanEndTag = "</span>";
debug(hrTag + spanStartTag + "hometown=" + hometown + "<br>onLineName=" + onLineName
+ "<br>age=" + age + "<br>hobby=" + hobby + spanEndTag + hrTag);
}
function testCookie() {
if (navigator.cookieEnabled) {
console.log("浏览器启用了Cookie");
debug("浏览器启用了Cookie");
console.log("Cookie信息=" + document.cookie);
debug("Cookie信息=" + document.cookie);
} else {
//浏览器禁用了Cookie,所以js读取不到Cookie信息
console.log("浏览器禁用了Cookie");
debug("浏览器禁用了Cookie");
console.log("Cookie信息=" + document.cookie);
debug("Cookie信息=" + document.cookie);
}
}
/*
eval()函数不太安全,比如:eval()函数解析文本框(input)中输入的非法的值(用户在文本框中输入了某些恶意的非法的javascript代码)
*/
// var test = '[{ "count":alert("hello javaScript!"),"pageCount":7,"nowPage":23 }]';//单独的这行代码,什么都不会打印
// var test = '{ "count":alert("hello javaScript!"),"pageCount":7,"nowPage":23 }';//单独的这行代码,什么都不会打印
// eval(test);//报错SyntaxError: missing ; before statement
// eval("(" + test + ")");
// var test = [{ "count":alert("hello javaScript!"),"pageCount":7,"nowPage":23 }];//单独的这行代码,会打印出hello javaScript!
// var test = { "count":alert("hello javaScript!"),"pageCount":7,"nowPage":23 };//单独的这行代码,会打印出hello javaScript!
// eval("(" + test + ")");//报错SyntaxError: missing ] after element list
// var result2 = eval(test);
// alert(result2);
// alert(test.count);//undefined
// alert(test.nowPage);
// test();
function test() {
var jsonData = '{ "count":alert("hello javaScript!"),"pageCount":7,"nowPage":23 }';
var jsonObj = eval('(' + jsonData + ')'); // eval();方法
alert(jsonObj.count);
jsonObj.count;
alert(jsonObj.pageCount);
alert(jsonObj.nowPage);
var testJson = {
name : "令狐冲",
age : 17,
sayHi : function() {
alert("hello,我是" + this.name + ",我今年" + this.age + "岁了!");
}
};
testJson.sayHi();
alert(testJson.name);
alert(testJson.age);
alert(testJson.sayHi);
}
var xmlHttpRequest;
function createXmlHttpRequest() {
//判断不同浏览器,采用不同方式创建XMLHttpRequest对象
if (window.ActiveXObject) {
//IE浏览器
try {
xmlHttpRequest = new ActiveXObject("Microsoft.XMLHTTP");
} catch (e) {
xmlHttpRequest = new ActiveXObject("Msxml2.XMLHTTP");
}
return xmlHttpRequest;
} else if (window.XMLHttpRequest) {
//其他浏览器如Firefox、Chrome等等
return new XMLHttpRequest();
}
}
//根据省id获取服务器上的市
function getServerCityByProvinceId(provinceId) {
if (provinceId == '0') {
cleanCity();
return;
}
//1.创建XMLHttpRequest对象
xmlHttpRequest = createXmlHttpRequest();
//2.设置回调函数
xmlHttpRequest.onreadystatechange = ajaxAndXml;
//请求的目标地址
var url = "/ajax/JsonCity?returnDataType=xml&provinceId=" + 88;
//3.初始化XMLHttpRequest组件
//addTimestampParameter(url)函数不太好的就是,URL本身可能带有一些参数,那就要判断是加"?"还是加"&"了
//xmlHttpRequest.open("GET", addTimestampParameter(url), true);
xmlHttpRequest.open("GET", url, true);
//xmlHttpRequest.open("POST", url, true);
//推荐使用下面这种方式,简洁灵活,不影响URL参数
xmlHttpRequest.setRequestHeader('If-Modified-Since', '0');
//4.发送请求
xmlHttpRequest.send(null);
//显示加载图片
showLoading(document.getElementById("ajaxXmlButton"),
"${pageContext.request.contextPath}/img/loading1.gif");
}
//测试多个js文件中出现了同名的变量,比如test.js文件和testVar.js文件中都有名字叫testHometown的变量
console.log("testHometown=" + testHometown);
</script>
<script type="text/javascript" src="${pageContext.request.contextPath}/js/test.js"></script>
<script type="text/javascript">
//测试多个js文件中出现了同名的变量,比如test.js文件和testVar.js文件中都有名字叫testHometown的变量
console.log("testHometown=" + testHometown);
</script>
</html>