学习链接
目录
1、Ajax简介、异步与同步
- asynchronous javascript and xml :异步的js和xml,能使用js访问服务器,并且是异步访问;
- 服务器给客户端的响应一般是整个页面:一个html完整页面,但在ajax中因为是局部刷新,那么服务器就不再响应整个页面,而只是数据
返回的数据可以是text纯文本和xml和json
- 异步交互和同步交互
同步:发一个请求,就要等待服务器的响应结束,然后才能发第二个请求,刷新的是整个页面;
异步:发一个请求后,无须等待服务器的响应,就可以发第二个请求,可以使用js接收服务器的响应,然后使用js来局部刷新;
- 局部刷新
<head>
<script type="text/javascript">
window.onload = function(){//在文档加载完成后马上执行,实际为监听器
//得到btn元素
var btn = docunment.getElementById("btn");
//给btn的click事件注册监听
btn.onclock = function(){//在按钮被点击时执行
//获取h1元素对应的DOM对象
var h1 = document,getElementById("h1");
// 给h1添加内容
h1.innerHTML = "Hello JS!!!";
}
};
</script>
</head>
<body>
<button id="btn">点击这里</button>
<h1 id='h1'></h1>
</body>
2、Ajax的应用场景和优缺点
- 搜索框的联想下拉列表
- 注册页面检测
- Ajax优缺点:
优点:
1、异步交互,增强了用户体验;
2、性能:因为服务器无需再响应整个页面,只需响应部分内容,服务器压力减轻了;
缺点:
1、不能应用在所有场景;
2、增加了服务器响应次数。
3、Ajax发送异步请求(四步操作)
第一步,得到XMLHttpRequest
- ajax只需要学习一个对象:XMLHttpRequest
- 得到XMLHttpRequest
//大多数浏览器都支持:
var xmlHttp = new XMLHttpRequest();
//IE6.0
var xmlHttp = new ActiveXObject("Msxml12.XMLHTTP");
//IE5.5及更早版本的IE
var xmlHttp = new ActiveXObject("Microsoft.XMLHTTP");
- 编写创建XMLHttpRequest对象的函数
function createXMLHttpRequest() {
try{
return new XMLHttpRequest();
} catch(e) {
try {
return new ActiveXObject("Msxml12.XMLHTTP");
} catch(e) {
try {
return new ActiveXObject("Microsoft.XMLHTTP");
} catch(e) {
alert("创建XMLHttpRequest对象失败");
throw e;
}
}
}
}
第二步、打开与服务器的连接
- xmlHttp.open()用来打开与服务器的连接,需要三个参数:
请求的方式:可以是GET或POST
请求的URL:指定服务器端资源
请求是否为异步,如果为true表示发送异步请求,否则同步请求。
eg. xmlHttp.open(“GET”,“资源URL”,true);
第三步、发送请求
- xmlHttp.send(null); 如果不给参数可能造成部分浏览器无法发送。
参数:就是请求体内容
如果是GET请求,必须给出null
PSOT请求,xmlHttp.send(“username=zhangsan&password=123”);
第四步、响应请求
- 在xmlHttp对象的一个事件上注册监听器:onreadystatechange
xmlHttp对象一共有五个状态:
0状态:初始化,没有调用open()方法;
1状态:请求开始,调用了open()方法,但还没有调用send()方法;
2状态:调用完了send()方法;
3状态:服务器已经开始响应,但不表示响应结束了;
4状态:服务器响应结束。
通常只关注4状态。
- 得到xmlHttp对象的状态:
var state = xmlHttp.readyState;//可能是0、1、2、3、4
- 得到服务器响应的状态码
var status = xmlHttp.status; //例如200、404、500
- 得到服务器响应的内容
var content = xmlHttp.responseText;//得到服务器的响应的文本格式的内容
var content = xmlHttp.responseXML;//得到服务器的响应的xml格式的内容,它是Document对象了
- 示例
xmlHttp.onreadystatechange = function() {//xmlHttp的5种状态都会调用本方法
if(xmlHttp.readyState == 4 && xmlHttp.status == 200) {//双重判断:判断是否为4状态,而且还要判断是否为200
//获取服务器的响应内容
var text = xmlHttp.responseText;
}
}
Ajax第一例:helloworld
- Servlet
import java.io.IOException;
public class AServlet extends HttpServlet {
public void doGet(HttpServletRequest request, HttpServletResponse response)
throw ServletException, IOException{
System.out.println("Hello Ajax!");
response.getWriter().print("Hello Ajax!!!");
}
}
- ajax.jsp
<head>
<script type="text/javascript">
//创建异步对象
function createXMLHttpRequest() {
try{
return new XMLHttpRequest();//大多数浏览器
} catch(e) {
try {
return new ActiveXObject("Msxml12.XMLHTTP");//IE6.0
} catch(e) {
try {
return new ActiveXObject("Microsoft.XMLHTTP");//IE5.5及更早版本
} catch(e) {
alert("创建XMLHttpRequest对象失败");
throw e;
}
}
}
}
window.onload = function(){//在文档加载完成后马上执行,实际为监听器
//得到btn元素
var btn = docunment.getElementById("btn");
//给btn的click事件注册监听
btn.onclock = function(){//给按钮的点击事件注册监听,在按钮被点击时执行
/*
ajax四步操作,得到服务器响应,把响应结果显示到h1元素中
*/
// 1、得到异步对象
var xmlHttp = createXMLHttpRequest();
/* 2、打开与服务器的连接
* 指定请求方式
* 指定请求的url
* 指定是否为异步请求
*/
xmlHttp.open("GET","<c:url value='/AServlet/'>",true);
// 3、发送请求
xmlHttp.send(null);//GET请求没有请求体,但也要给出null
// 4、给异步对象的onreadystatechange事件注册监听器
xmlHttp.onreadtstatechange = function() {//当xmlHttp的状态发生变化时执行
//双重判断:xmlHttp的状态为4,以及服务器响应的状态码为200
if(xmlHttp.readyState == 4 && xmlHttp.status == 200) {
//获取服务器的响应内容
var text = xmlHttp.responseText;
//获取h1元素对应的DOM对象
var h1 = document,getElementById("h1");
// 给h1添加内容
h1.innerHTML = text;
}
}
}
};
</script>
</head>
<body>
<button id="btn">点击这里</button>
<h1 id='h1'></h1>
</body>
Ajax第二例:发送POST请求
- 如果发送请求时需要带有参数,一般都用POST请求
- POST请求的请求头
Content-Type: application/x-www-form-urlencoded
- 注意:
open:xmlHttp.open(“POST”…);
添加一步:设置Content-Type请求头
xmlHttp.setRequestHeader(“Content-Type”,“application/x-www-form-urlencoded”);
send:xmlHttp.send(“username=zhangsan&password=123”);//发送请求时指定请求体
- Servlet
import java.io.IOException;
public class AServlet extends HttpServlet {
public void doGet(HttpServletRequest request, HttpServletResponse response)
throw ServletException, IOException{
System.out.println("Hello Ajax!");
response.getWriter().print("Hello Ajax!!!");
}
//在Servlet中新增函数
public void doPost(HttpServletRequest request, HttpServletResponse response)
throw ServletException, IOException{
response.setContentType("text/html;charset=utf-8");//响应的编码
request.setCharacterEncoding("UTF-8");//请求的编码
String username = request.getParameter("username");//获取请求参数
System.out.println("POST:Hello Ajax!" + username);
response.getWriter().print("POST:Hello Ajax!!!" + username);
}
}
- ajax2.jsp
<head>
<script type="text/javascript">
//创建异步对象
function createXMLHttpRequest() {
try{
return new XMLHttpRequest();//大多数浏览器
} catch(e) {
try {
return new ActiveXObject("Msxml12.XMLHTTP");//IE6.0
} catch(e) {
try {
return new ActiveXObject("Microsoft.XMLHTTP");//IE5.5及更早版本
} catch(e) {
alert("创建XMLHttpRequest对象失败");
throw e;
}
}
}
}
window.onload = function(){//在文档加载完成后马上执行,实际为监听器
//得到btn元素
var btn = docunment.getElementById("btn");
//给btn的click事件注册监听
btn.onclock = function(){//给按钮的点击事件注册监听,在按钮被点击时执行
/*
ajax四步操作,得到服务器响应,把响应结果显示到h1元素中
*/
// 1、得到异步对象
var xmlHttp = createXMLHttpRequest();
/* 2、打开与服务器的连接
* 指定请求方式
* 指定请求的url
* 指定是否为异步请求
* 修改open方法,指定请求方式为POST
*/
xmlHttp.open("POST","<c:url value='/AServlet/'>",true);
// 设置请求头:Content-Type
xmlHttp.setRequestHeader("Content-Type","application/x-www-form-urlencoded");
// 3、发送请求
xmlHttp.send("username=张三&password=123");//
// 4、给异步对象的onreadystatechange事件注册监听器
xmlHttp.onreadtstatechange = function() {//当xmlHttp的状态发生变化时执行
//双重判断:xmlHttp的状态为4,以及服务器响应的状态码为200
if(xmlHttp.readyState == 4 && xmlHttp.status == 200) {
//获取服务器的响应内容
var text = xmlHttp.responseText;
//获取h1元素对应的DOM对象
var h1 = document,getElementById("h1");
// 给h1添加内容
h1.innerHTML = text;
}
}
}
};
</script>
</head>
<body>
<button id="btn">点击这里</button>
<h1 id='h1'></h1>
</body>
Ajax第三例:用户名是否已被注册
1、编写页面
- ajax3.jsp 给出注册表单页面、给用户名文本框添加onblur事件的监听、获取文本框的内容,通过ajax4步发送给服务器,得到响应结果
如果为1:在文本框后显示“用户名已被注册”
如果为0:不做操作
2、编写Servlet
-
ValidateUsernameServlet
获取客户端传递的用户名参数,判断是否为itcast
是,返回1/否,返回0 -
ajax3.jsp
<head>
<script type="text/javascript">
//创建异步对象
function createXMLHttpRequest() {
try{
return new XMLHttpRequest();//大多数浏览器
} catch(e) {
try {
return new ActiveXObject("Msxml12.XMLHTTP");//IE6.0
} catch(e) {
try {
return new ActiveXObject("Microsoft.XMLHTTP");//IE5.5及更早版本
} catch(e) {
alert("创建XMLHttpRequest对象失败");
throw e;
}
}
}
}
window.onload = function(){//在文档加载完成后马上执行,实际为监听器
//得到文本框
var userEle = docunment.getElementById("usernameEle");
//给文本框的失去焦点事件注册监听
userEle.onblur = function(){
/*
ajax四步操作,得到服务器响应,把响应结果显示到h1元素中
*/
// 1、得到异步对象
var xmlHttp = createXMLHttpRequest();
/* 2、打开与服务器的连接
* 指定请求方式
* 指定请求的url
* 指定是否为异步请求
* 修改open方法,指定请求方式为POST
*/
xmlHttp.open("POST","<c:url value='/ValidateUsernameServlet/'>",true);
// 设置请求头:Content-Type
xmlHttp.setRequestHeader("Content-Type","application/x-www-form-urlencoded");
// 3、发送请求
xmlHttp.send("username="+userEle.value);//
// 4、给异步对象的onreadystatechange事件注册监听器
xmlHttp.onreadtstatechange = function() {//当xmlHttp的状态发生变化时执行
//双重判断:xmlHttp的状态为4,以及服务器响应的状态码为200
if(xmlHttp.readyState == 4 && xmlHttp.status == 200) {
//获取服务器的响应内容
var text = xmlHttp.responseText;
//获取span,添加内容
var span = document.getElementById("errorSpan");
if(text == "1"){
span.innerHTML = "用户名已被注册";
} else {
span.innerHTML = "";
}
}
}
}
};
</script>
</head>
<body>
<h1 >演示用户名是否被注册</h1>
<form action="" method="post">
用户名:<input type="text" name="username" id="usernameEle"/><span id="errorSpan"></span><br/>
密码:<input type="password" name="password"/><br/>
<input type="submit" value="注册">
</form>
</body>
- Servlet
import java.io.IOException;
public class AServlet extends HttpServlet {
public void doPost(HttpServletRequest request, HttpServletResponse response)
throw ServletException, IOException{
response.setContentType("text/html;charset=utf-8");//响应的编码
request.setCharacterEncoding("UTF-8");//请求的编码
/*
* 1、获取参数username
* 2、判断是否为itcast
* 3、如果是:响应1
* 4、如果不是:响应0
*/
String username = request.getParameter("username");
if(username.euqalsIgnoreCase("itcast")){
response.getWriter().point("1");
} else {
response.getWriter.print("0");
}
}
}
Ajax第四例:响应内容为xml
- 服务器端:
设置响应头: Content-Type,其值为:text/xml;character=utf-8 - 客户端:
var doc = xmlHttp.responseXML;//得到的是Document对象 - Servlet
import java.io.IOException;
public class AServlet extends HttpServlet {
public void doGet(HttpServletRequest request, HttpServletResponse response)
throw ServletException, IOException{
String xml = "<students>"+
"<student number='ITCAST_1001'>"+
"<name>zhangsan</name>"+
"<age>23</age>"+
"<sex>male</sex>"+
"</student>"+
"</students>";
response.setContentType("text/xml;character=utf-8");
response.getWriter().print(xml);
}
}
- ajax4.jsp
<head>
<script type="text/javascript">
//创建异步对象
function createXMLHttpRequest() {
try{
return new XMLHttpRequest();//大多数浏览器
} catch(e) {
try {
return new ActiveXObject("Msxml12.XMLHTTP");//IE6.0
} catch(e) {
try {
return new ActiveXObject("Microsoft.XMLHTTP");//IE5.5及更早版本
} catch(e) {
alert("创建XMLHttpRequest对象失败");
throw e;
}
}
}
}
window.onload = function(){//在文档加载完成后马上执行,实际为监听器
//得到btn元素
var btn = docunment.getElementById("btn");
//给btn的click事件注册监听
btn.onclock = function(){//给按钮的点击事件注册监听,在按钮被点击时执行
/*
ajax四步操作,得到服务器响应,把响应结果显示到h1元素中
*/
// 1、得到异步对象
var xmlHttp = createXMLHttpRequest();
/* 2、打开与服务器的连接
* 指定请求方式
* 指定请求的url
* 指定是否为异步请求
*/
xmlHttp.open("GET","<c:url value='/BServlet/'>",true);
// 3、发送请求
xmlHttp.send(null);//GET请求没有请求体,但也要给出null
// 4、给异步对象的onreadystatechange事件注册监听器
xmlHttp.onreadtstatechange = function() {//当xmlHttp的状态发生变化时执行
//双重判断:xmlHttp的状态为4,以及服务器响应的状态码为200
if(xmlHttp.readyState == 4 && xmlHttp.status == 200) {
//获取服务器的响应结果(xml)
var doc = xmlHttp.responseXML;
//查询文档下名为student的所有元素,得到数组,再取下标0元素
var ele = doc.getElementsByTagName("student")[0];
var number = ele.getAttribute("number");//获取元素名为number的属性值
var name,age,sex;
if(window.addEventListener){
//其他浏览器支持
name = ele.getElementsByTagName("name")[0].textContent;
age = ele.getElementsByTagName("age")[0].textContent;
sex = ele.getElementsByTagName("sex")[0].textContent;
} else {
//IE支持
name = ele.getElementsByTagName("name")[0].text;
age = ele.getElementsByTagName("age")[0].text;
sex = ele.getElementsByTagName("sex")[0].text;
}
var text = number + "," + name + "," + age + "," + sex;
document.getElementById("h1").innerHTML = text;
}
}
}
};
</script>
</head>
<body>
<button id="btn">点击这里</button>
<h1 id='h1'></h1>
</body>
Ajax第五例:省市联动
Servlet用到了doc4j
- 1、页面
<select name="province">
<option>===请选择省份===</option>
</select>
<select name="city">
<option>==请选择城市==</option>
</select>
- 2、ProvinceServlet
ProvinceServlet:当页面加载完毕后马上请求这个Servlet。
它需要加载china.xml文件,把所有的省的名称使用字符串发送给客户端。
- 3、页面的工作
获取这个字符串,使用逗号分隔,得到数组
循环遍历每个字符串(省份的名称),使用每个字符串创建一个 < option >元素添加到< select name=“province”>这个元素中
- 4、CityServlet
当页面选择某个省份时,发送请求。
得到省份的名称,加载china.xml,查询出该省份对应的元素对象,把这个元素转换成xml字符串,发送给客户端
- 5、页面的工作
把< select name=“city” >中的所有子元素删除,但不要删除< option >=== 请选择城市 ===< option >
得到服务器的响应结果doc
获取所有的< city > 子元素,循环遍历,得到内容
使用每个< city >的内容创建一个< option >元素,添加到< select name=“city” >
- ajax5.jsp
<script>
/*
* 1、在文档加载完毕时发送请求,得到所用省份名称,显示在<select name="province">中
* 2、在选择了新的省份时,发送请求(参数为省名称),得到xml文档,即<province>元素
* 3、解析xml文档,得到其中所有的<city>,再得到每个<city>元素的内容,即市名,使用市名生成<option>,插入到<select name="city">元素中
*/
//创建异步对象
function createXMLHttpRequest() {
try{
return new XMLHttpRequest();//大多数浏览器
} catch(e) {
try {
return new ActiveXObject("Msxml12.XMLHTTP");//IE6.0
} catch(e) {
try {
return new ActiveXObject("Microsoft.XMLHTTP");//IE5.5及更早版本
} catch(e) {
alert("创建XMLHttpRequest对象失败");
throw e;
}
}
}
}
window.onload = function() {
/*
* ajax四步:请求ProvinceServlet,得到所有省份名称
* 使用每个省份名称创建一个<option>元素,添加到<select name="province">中
*/
var xmlHttp = createXMLHttpRequest();
xmlHttp.open("GET","<c:url value='/ProvinceServlet'/>",true);
xmlHttp.send(null);
xmlHttp.onreadystatechange = function() {
if(xmlHttp.readyState == 4 && xmlHttp.status == 200) {
//获取服务器的响应
var text = xmlHttp.responseText;
//使用逗号分隔,得到数组
var arr = text.split(",");
// 循环遍历每个省份名称,生成一个option对象,添加到<select>中
for(var i = 0; i < arr.length; i++){
//创建一个指定名称元素
var op = document.createElement("option");
op.value = arr[i];//设置op的实际值为当前的省份名称
var textNode = document.createTextNode(arr[i]);//创建文本节点
op.appendChild(textNode);//把文本子节点添加到op元素中,指定其显示值
document.getElementById("p").appendChild(op);
}
}
};
/*
* 给<select name="province">添加改变监听,使用选择的省份名称请求CityServlet,得到<province>元素(xml元素)
* 获取<province>元素中所有的<city>元素遍历
* 获取每个<city>的文本内容,即市名称
* 使用每个市名称创建<option>元素添加到<select name="city">
*/
var proSelect = document.getElementById("p");
proSelect.onchange = function() {
var xmlHttp = createXMLHttpRequest();
xmlHttp.open("POST","<c:url value='/CityServlet'/>",true);
xmlHttp.setRequestHeader("Content-Type","application/x-www-form-urlencoded");
xmlHttp.send("pname="+proSelect.value);//把下拉列表中选择的值发送给服务器
xmlHttp.onreadystatechange = function() {
if(xmlHttp.readyState == 4 && xmlHttp.status == 200) {
/*
* 把<select>中的所有option移除,除了请选择
*/
var citySelect = document.getElementById("c");
// 获取其所有子元素
var optionEleList = citySelect.getElementByTagName("option");
// 循环遍历每个option元素,然后在citySelect中移除
while(optionElementList.length > 1){
//子元素的个数如果大于1就循环,等于1就不循环
citySelect.removeChild(optionEleList[1]);
//总是删除1下标,因为1删除后2变成1
}
//获取服务器的响应
var doc = xmlHttp.responseXML;
//得到所有名为city的元素
var cityEleList = doc.getElementByTagName("city");
// 循环遍历每个城市名称,生成一个option对象,添加到<select>中
for(var i = 0; i < cityEleList .length; i++){
var cityEle = cityEleList[i];//得到每个city元素
var cityName;
// 获取市名称
if(window.addEventListener){//处理浏览器差异
cityName = cityEle.textContent;//支持FireFox等浏览器
} else {
cityName = cityEle.text;//支持IE
}
var op =document.createElement("option");
op.value = cityName;
// 创建文本节点
var textNode = document.createTextNode(cityName);
//把文本节点追加到op元素中
op.appendChild(textNode);
//把op添加到<select>元素中
citySelect.appendChild(op);
}
}
};
};
}
</script>
<body>
<h1>省市联动</h1>
<select name="province" id="p">
<option>===请选择省份===</option>
</select>
<select name="city" id="c">
<option>==请选择城市==</option>
</select>
</body>
- ProvinceServlet
import java.io.IOException;
public class ProvinceServlet extends HttpServlet {
public void doGet(HttpServletRequest request, HttpServletResponse response) throw ServletException, IOException {
request.setCharacterEncoding("utf-8");
request.setContentType("text/html;charset=utf-8");
// 响应所有省份名称,使用逗号分隔
/*
* 1、Document对象
* 创建解析器对象
* 调用解析器的读方法,传递一个流对象,得到Docunment
*/
try {
SAXReader reader = new SAXReader();
InputStream input = this.getClass().getResourceAsStream("/china.xml");
Document doc = reader.read(input);
/*
* 查询所有province的name属性
* 循环遍历,把所有的属性值连接成一个字符串,发送给客户端
*/
List<Attribute> arrList = doc.selectNodes("//province/@name");
StringBuilder sb = new StringBuilder();
for(int i=0; i < arrList.size(); i++) {
sb.append(arrList.get(i).getValue());//把每个属性的值放到sb中
if(i<arrList.size() -1){
sb.append(",");
}
}
response.getWriter().print(sb);
} catch(Exception e) {
throw new RuntimeExcption(e);
}
}
}
- CityServlet
import java.io.IOException;
public class ProvinceServlet extends HttpServlet {
public void doPost(HttpServletRequest request, HttpServletResponse response) throw ServletException, IOException {
request.setCharacterEncoding("utf-8");
request.setContentType("text/xml;charset=utf-8");
/*
* 获取省份名称,加载该省对应的<province>元素;
* 把元素转换成字符串发送给客户端
*/
/*
* 1、获取省份的名称
* 2、使用省份名称查找对应的<province>元素
* 3、把<province>元素转换成字符串发送
*/
try {
//得到Document
SAXReader reader = new SAXReader();
InputStream input = this.getClass().getResourceAsStream("/china.xml");
Document doc = reader.read(input);
/*
* 获取参数
*/
String pname = request.getParameter("pname");//获取省份名称
Element proEle = (Element)doc.selectSingleNode("//province[@name='" + pname + "']");
String xmlStr = proEle.asXML();//把元素转换成字符串
response.getWriter().print(xmlStr);
} catch(Exception e) {
throw new RuntimeExcption(e);
}
}
}
4、XStream工具
- 1、作用:可以把JavaBean转换为(序列化为)xml
- 2、XStream的JAR包
核心JAR包:xstream-1.4.7.jar
必须依赖包:xpp3_min_1.1.4c(XML Pull Parser,一款速度很快的XML解析器) - 3、使用步骤以及多次优化
City.java
public class City{
private String name;//市名
private String description;//描述
//get、set函数
//toString函数
//两个构造函数
}
Province.java
public class Prvince{
private String name;//省名
private List<City> cities = new ArrayList<City>();
//get、set函数
//toString函数
//两个构造函数
public void add(City city){
cities.add(city);
}
}
Demo1.java
public class Demo1{
//返回javabean集合
public List<Province> getProvinceList() {
Province p1 = new Province();
p1.setName("北京");
p1.addCity(new City("东城区","DongChengQu"));
p1.addCity(new City("昌平区","ChangPingQu"));
Province p2 = new Province();
p2.setName("辽宁");
p2.addCity(new City("沈阳","ShenYang"));
p2.addCity(new City("葫芦岛","HuLuDao"));
List<Province> provinceList = new ArrayList<Province>();
provinceList.add(p1);
provinceList.add(p2);
return provinceList;
}
public void fun1() {
List<Province> proList = getProvinceList();
/*
* 创建XStream对象
* 调用toXML把集合转换成xml字符串
*/
XStream xstream = new XStream();
String s = xstream.toXML(proList);
System.out.print(s);//打印出xml文件如下
}
}
- xml文件
<list> --> List类型显示List
<cn.itcast.demo1.Province> --> javabean的类型为Province,它元素的名称为完整类名
<name>北京</name> --> javabean的属性名
<cities> --> javabean的属性名
<cn.itcast.demo1.City> -->类名
<name>东城区</name> -->属性名
<description>DongChengQu</description> -->属性名
</cn.itcast.demo1.City>
<cn.itcast.demo1.City> -->类名
<name>昌平区</name> -->属性名
<description>ChangPingQu</description> -->属性名
</cn.itcast.demo1.City>
</cities>
</cn.itcast.demo1.Province>
<cn.itcast.demo1.Province>
<name>辽宁</name>
<cities>
<cn.itcast.demo1.City>
<name>沈阳</name>
<description>ShenYang</description>
</cn.itcast.demo1.City>
<cn.itcast.demo1.City>
<name>葫芦岛</name>
<description>HuLuDao</description>
</cn.itcast.demo1.City>
</cities>
</cn.itcast.demo1.Province>
</list>
- 第一次优化XStream生成xml文件
/*
* 别名(alias)
* 默认List类型对应<List>元素,让List元素对应<china>元素
* 默认Province类型对应完整包名,让Province元素对应<Province>
* 默认City类型对应完整包名,让City元素对应<City>
*/
public void fun2(){
List<Province> proList = getProvinceList();
XStream xstream = new XStream();
/*
* 给指定的类型指定别名
*/
xstream.alias("china",List.class);//给List类型指定别名
xstream.alias("province",Province.class);//给Province类型指定别名
xstream.alias("city",City.class);//给City类型指定别名
String s = xstream.toXML(proList);
System.out.print(s);//打印出xml文件如下
}
- 优化后的xml文件
<china>
<Province>
<name>北京</name>
<cities>
<City>
<name>东城区</name>
<description>DongChengQu</description>
</City>
<City>
<name>昌平区</name>
<description>ChangPingQu</description>
</City>
</cities>
</Province>
<Province>
<name>辽宁</name>
<cities>
<City>
<name>沈阳</name>
<description>ShenYang</description>
</City>
<City>
<name>葫芦岛</name>
<description>HuLuDao</description>
</City>
</cities>
</Province>
</china>
- 第二次优化XStream生成xml文件
public void fun3(){
List<Province> proList = getProvinceList();
XStream xstream = new XStream();
xstream.alias("china",List.class);//给List类型指定别名
xstream.alias("province",Province.class);//给Province类型指定别名
xstream.alias("city",City.class);//给City类型指定别名
// 把Province类型的name属性,生成<province>元素的属性
xstream.useAttributeFor(Province.class,"name");
// 去除<cities>这样的Collection属性
xstream.addImplicitCollection(Province.class,"cities");
String s = xstream.toXML(proList);
System.out.print(s);//打印出xml文件如下
}
- 优化后的xml文件
<china>
<Province name="北京">
<City>
<name>东城区</name>
<description>DongChengQu</description>
</City>
<City>
<name>昌平区</name>
<description>ChangPingQu</description>
</City>
</Province>
<Province name="辽宁">
<City>
<name>沈阳</name>
<description>ShenYang</description>
</City>
<City>
<name>葫芦岛</name>
<description>HuLuDao</description>
</City>
</Province>
</china>
- 第三次优化XStream生成xml文件
public void fun3(){
List<Province> proList = getProvinceList();
XStream xstream = new XStream();
xstream.alias("china",List.class);//给List类型指定别名
xstream.alias("province",Province.class);//给Province类型指定别名
xstream.alias("city",City.class);//给City类型指定别名
// 把Province类型的name属性,生成<province>元素的属性
xstream.useAttributeFor(Province.class,"name");
// 去除<cities>这样的Collection属性
xstream.addImplicitCollection(Province.class,"cities");
// 去除不想要的javabean属性,就是让这些javabean属性不生成对应xml元素
// 让City类名为Description属性不生成对应xml元素
xstream.omitField(City.class,"description");
String s = xstream.toXML(proList);
System.out.print(s);//打印出xml文件如下
}
<china>
<Province name="北京">
<City>
<name>东城区</name>
</City>
<City>
<name>昌平区</name>
</City>
</Province>
<Province name="辽宁">
<City>
<name>沈阳</name>
</City>
<City>
<name>葫芦岛</name>
</City>
</Province>
</china>
- 优化的总结
1、别名:修改类型对应的元素名
//让List类型生成的元素名为china
xstream.alias(“china”,List.class);
//让Province类型生成的元素名为province
xstream.alias(“province”,Province.class);
//让City类型生成的元素名为city
xstream.alias(“city”,City.class);
2、使用为属性:默认类的成员,生成的是元素的子元素,让类的成员生成元素的属性
//把Province类的名为name的成员,生成 < province > 元素的name属性
xstream.useAttributeFor(Province.class,“name”);
3、去除Collection类型的成员:只需要Collection的内容,不希望Collection也成为一个元素
//让Province类的名为cities的成员不生成元素,它是List类型的,它的内容还会生成元素
xstream.addImplicitCollection(Province.class,“cities”);
4、去除类的指定成员,让其不生成xml元素
//在生成的xml中不会出现City类的,名为description的对应元素
xstream.omitField(City.class,“description”);
5、JSON的概述
- JSON:它是js提供的一种数据交换格式。
- JSON的语法:
1、{}是对象
2、属性名必须使用双引号括起来。
3、JSON值:数字(整数或浮点数)、字符串(双引号括起来)、逻辑值。数组(方括号中)、对象(花括号中)、null。 - 应用JSON
//eg1
window.onload = function() {
var person = {"name":"zhangsan","age":18,"sex":"male"};
alert(person.name + "," + person.age + "," + person.sex );
}
//eg2
window.onload = function() {
//注意用 \ 来转义双引号
var str = "{\"name\":\"zhangsan\",\"age\":18,\"sex\":\"male\"}";
var person = eval("("+ str + ")");
alert(person.name + "," + person.age + "," + person.sex );
}
//eval函数
window.onload = function() {
var str = "1 + 2";
var sum = eval("(" + str + ")");
}
- ajax案例:向客户端发送JSON串
AServlet.java
import java.io.IOException;
public class ProvinceServlet extends HttpServlet {
public void doGet(HttpServletRequest request, HttpServletResponse response) throw ServletException, IOException {
/*
* 向客户端发送JSON串
*/
String str = "{\"name\":\"zhangsan\",\"age\":18,\"sex\":\"male\"}";
response.getWriter().print(str);
}
}
<head>
```
<script type="text/javascript">
//创建异步对象
function createXMLHttpRequest() {
try{
return new XMLHttpRequest();//大多数浏览器
} catch(e) {
try {
return new ActiveXObject("Msxml12.XMLHTTP");//IE6.0
} catch(e) {
try {
return new ActiveXObject("Microsoft.XMLHTTP");//IE5.5及更早版本
} catch(e) {
alert("创建XMLHttpRequest对象失败");
throw e;
}
}
}
}
window.onload = function() {
var btn = docunment.getElementById("btn");
btn.onclick = function() {
//使用Ajax得到服务器端响应,把结果显示到h3中
//得到request
var xmlHttp = createXMLHttpRequest();
//连接
xmlHttp.open("GET","<c:url value='/AServlet'/>",true);
//发送
xmlHttp.send(null);
//给xmlHttp的状态改变事件上添加监听
xmlHttp.onreadystatechange = function() {
//双重判断
if(xmlHttp.readyState == 4 && xmlHttp.status == 200) {
var text = xmlHttp.responseText;
//执行json串
var person = eval("(" + text + ")");
var s = person.name + "," + person.age + "," + person.sex;
document.getElementById("h3").innerHTML = s;
}
};
};
};
</script>
</head>
<body>
<%-- 点击按钮后,把服务器响应的数据显示到h3元素中--%>
<button id="btn">点击这里</button>
<h1>JSON</h1>
<h3 id="h3"></h3>
</body>
- JSON与XML比较
可读性:xml更好
解析难度:JSON本身就是JS对象,所以比较简单
流行度:XML已经流行多年,但AJAX中,JSON更受欢迎
6、json-lib的应用
- 可以把javabean转换成json串
- JAR包
核心jar包:json-lib.jar
依赖jar包:commons-lang.jar、commons-beanutiils.jar、commons-logging.jar、commons-collections.jar、ezmorph.jar - 核心类
JSONObject --> Map
–>toSting();
–>JSONObject map = JSONObject.fromObject(person);//把对象转换成JSONObject对象
JSONArray --> List
–>toSting();
–>JSONArray jsonArray = JSONObject.fromObject(list);//把list转换成JSONArray对象
public class Demo1 {
//当map用
public void fun1() {
JSONObject map = new JSONObject();
map.put("name","zhangsan");
map.put("age",2);
map.put("sex","male");
String s = map.toString();
System.out.println(s);
}
//当已经有一个Person对象时,可以把Person对象转换成JSONObject对象
//省略Person类
public void fun2() {
Person p = new Person("liSi",32,"female");
JSONObject map = JSONObject.fromObject(p);
System.out.println(map.toString());
}
//JSONArray
public void fun3() {
Person p1 = new Person("zhangsan",23,"male");
Person p2 = new Person("liSi",32,"female");
JSONArray list = new JSONArray();
list.add(p1);
list.add(p2);
System.out.println(list.toString());
}
//原本就有一个List,需要把List转换成JSONArray
public void fun4() {
Person p1 = new Person("zhangsan",23,"male");
Person p2 = new Person("liSi",32,"female");
List<Person> list = new ArrayList<Person>();
list.add(p1);
list.add(p2);
System.out.println(JSONArray.fromObject(list).toString());
}
}
7、打包ajax生成小工具
ajax-lib
–>ajaxutils.js
- ajaxutils.js
//创建异步对象
function createXMLHttpRequest() {
try{
return new XMLHttpRequest();//大多数浏览器
} catch(e) {
try {
return new ActiveXObject("Msxml12.XMLHTTP");//IE6.0
} catch(e) {
try {
return new ActiveXObject("Microsoft.XMLHTTP");//IE5.5及更早版本
} catch(e) {
alert("创建XMLHttpRequest对象失败");
throw e;
}
}
}
}
function ajax(/*请求方式*/method,
/*请求的url*/url,
/*是否异步*/asyn,
/*请求体*/params,
/*回调方法*/callback
/*服务器响应数据转化成什么类型*/type) {
/*
* 1、得到xmlHttp
* 2、打开连接
* 3、判断是否为POST
* 4、发送请求
* 5、注册监听
*/
var xmlHttp = createXMLHttpRequest();
xmlHttp.open(method,url,asyn);
if("POST"== method) {
xmlHttp.setRequestHeader("Content-Type","application/x-www-form-urlencoded");
}
xmlHttp.send(params);
xmlHttp.onreadystatechange = function() {
if(xmlHttp.readyState == 4 && xmlHttp.status == 200) {
//获取服务器响应数据,进行转换
var data;
if(type == "xml") {
data = xmlHttp.responseXML;
} else if(type == "text") {
data = xmlHttp.responseText;
} else if(type = "json") {
var text xmlHttp.responseText;
date = eval("(" + text + ")");
}
//调用回调方法
callback(data);
}
};
}
/* option对象有如下属性
*请求方式 method,//默认为GET
*请求的url url,
*是否异步 asyn,//默认为异步
*请求体 params,
*回调方法 callback,
*服务器响应数据转化成什么类型 type//默认为text
*/
//将参数转换为对象传递
function ajax(option) {
/*
* 1、得到xmlHttp
* 2、打开连接
* 3、判断是否为POST
* 4、发送请求
* 5、注册监听
*/
var xmlHttp = createXMLHttpRequest();
if(!option.method) {//默认为GET
option.method = "GET";
}
if(option.asyn == undefined) {//默认为异步
option.asyn == true;
}
xmlHttp.open(option.method,option.url,option.asyn);
if("POST"== option.method) {
xmlHttp.setRequestHeader("Content-Type","application/x-www-form-urlencoded");
}
xmlHttp.send(option.params);
xmlHttp.onreadystatechange = function() {
if(xmlHttp.readyState == 4 && xmlHttp.status == 200) {
//获取服务器响应数据,进行转换
var data;
if(!option.type) {//如果type没有赋值,默认为文本
data = xmlHttp.responseText;
}else if(option.type == "xml") {
data = xmlHttp.responseXML;
} else if(option.type == "text") {
data = xmlHttp.responseText;
} else if(option.type = "json") {
var text xmlHttp.responseText;
date = eval("(" + text + ")");
}
//调用回调方法
option.callback(data);
}
};
}
- Demo演示ajax工具
<head>
```
<script type="text/javascript" src="<c: url value='/ajax-lib/ajaxutils.js'/'>"></script>
<script type="text/javascript">
window.onload = function() {
var btn = docunment.getElementById("btn");
btn.onclick = function() {
/*
* ajax
*/
ajax(
{
url:"<c:url value='/AServlet'/'>",
type:"json",
callback:function(data) {
document.getElementById("h3").innerHTML =
data.name + "," + data.age + "," + data.sex;
}
}
)
};
};
</script>
</head>
<body>
<%-- 点击按钮后,把服务器响应的数据显示到h3元素中--%>
<button id="btn">点击这里</button>
<h1>JSON</h1>
<h3 id="h3"></h3>
</body>