概述
目录
- ajax
- 发送异步请求的四步
- 案例
- hello ajax
- 发送POST请求
- 用户名是否已被注册
- 响应内容为xml数据
- 省市联动
- XStream
- JSON
- json-lib的应用
ajax
asynchronous javascript and xml:异步的js和xml
异步交互和同步交互
同步:发送请求后需等待服务器响应结束,才能发送第二个请求
同步:发送一个请求后,无需等待服务器的响应就能发送第二个请求。可以使用js来接收服务器的响应,局部刷新
优缺点:
优点:
异步交互增强用户体验
服务器无需响应整个页面
缺点:
不能应用在所有场景
发送请求多,增加服务器压力
发送异步请求的四步
- 得到XMLHttpRequest
大多数浏览器:var xmlHttp=new XMLHttpRequest();
IE:var xmlHttp=new ActiveObject("Msml12.XMLHTTP");
- 打开与服务器的连接
xmlHttp.open("GET","/day23_1/AServlet",true);
(三个参数为:请求方式,请求的URL,请求是否为异步) - 发送请求
xmlHttp.send(null)
:必须给出null,如果不给会造成部分浏览器无法发送 - 在xmlHttp对象的一个事件上注册监听器onreadystatechange
xmlHttp对象一共有5个状态:
0状态:刚创建,还没有调用open()方法
1状态:请求开始,调用了open()方法,还没有调用send()方法
2状态:调用完了send()方法
3状态:服务器已经开始响应,响应还未结束
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.onreadstatechange=function(){/xmlHttp的五种状态都会调用本方法
if(xmlHttp.readyState==4&&xmlHttp.status==200){//双重判断
var text=xmlHttp.responseText;//获取服务器的响应内容
};
案例
hello ajax
ajax1.jsp:客户端
<script type="text/javascript">
function createXMLHttpRequest(){
try{
return new XMLHttpRequest();//大多数浏览器
}catch(e){
try{
return ActiveXObject("Msxm12.XMLHTTP");//IE6.0
}catch(e){
try{
return ActiveXObject("Microsoft.XMLHTTP");//IE5.5及更早
}catch(e){
throw e;
}
}
}
}
window.onload=function(){
var btn=document.getElementById("btn");
btn.onclick=function(){
//1.得到异步对象
var xmlHttp=createXMLHttpRequest();
//2.打开与服务器的连接
xmlHttp.open("GET","<c:url value='/AServlet'/>",true);
//3.发送请求
xmlHttp.send(null);
//4.给异步对象的onreadystatechange事件注册监听器
xmlHttp.onreadystatechange=function(){
if(xmlHttp.readyState==4&&xmlHttp.status==200){
var text=xmlHttp.responseText;
var h1=document.getElementById("h1");
h1.innerHTML=text;
}
}
}
}
</script>
</head>
<body>
<button id="btn">点击这里</button>
<h1 id="h1"></h1>
</body>
AServlet:服务端
public class AServlet extends HttpServlet {
public void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
response.setContentType("text/html");
System.out.println("Hello AJAX");
response.getWriter().print("Hello AJAX!!!");
}
}
在点击页面按钮后,页面部分刷新,打印Hello AJAX,地址栏不会刷新
发送POST请求
如果发送请求时带有参数,一般使用POST
改变:
xmlHttp.open("GET","<c:url value='/AServlet'/>",true);
- 添加一步:设置Content-Type请求头:
xmlHttp.setRequestHeader("Content-Type","application/x-www.form-urlencoded");
- send:xmlHttp.send(“username=zhangSan&password=123”);//发送请求时
btn.onclick=function(){
var xmlHttp=createXMLHttpRequest();
/**************修改请求方式为POST*************/
xmlHttp.open("POST","<c:url value='/AServlet'/>",true);
/**************设置请求头Content-Type***********/
xmlHttp.setRequestHeader("Content-type","application/x-www-form-urlencoded");
/*************发送指定时请求体**************/
xmlHttp.send("username=张三&password=123");
xmlHttp.onreadystatechange=function(){
if(xmlHttp.readyState==4&&xmlHttp.status==200){
var text=xmlHttp.responseText;
var h1=document.getElementById("h1");
h1.innerHTML=text;
}
}
}
AServlet
public void doPost(HttpServletRequest request, HttpServletResponse response)
throws 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);
}
用户名是否已被注册
ajax3.jsp
window.onload=function(){
var userEle=document.getElementById("usernameEle");
userEle.onblur=function(){
var xmlHttp=createXMLHttpRequest();
xmlHttp.open("POST","<c:url value='/ValidateUsernameServlet'/>",true);
xmlHttp.setRequestHeader("Content-Type","application/x-www-form-urlencoded");
xmlHttp.send("username="+userEle.value);
xmlHttp.onreadystatechange=function(){
if(xmlHttp.readyState==4&&xmlHttp.status==200){
var text=xmlHttp.responseText;
var span=document.getElementById("errorSpan");
if(text=="1")
span.innerHTML="用户名已被注册!";
else
span.innerHTML="";
}
}
}
}
响应内容为xml数据
服务器端:
设置响应头:ContentType,其值为:text/xml;charset=utf-8
客户端:
var doc=xmlHttp.responseXML;
//得到的是Document对象
BServlet
public class BServlet extends HttpServlet {
public void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
String xml = "<students>" +
"<student number='ITCAST_1001'>" +
"<name>zhangSan</name>" +
"<age>18</age>" +
"<sex>male</sex>" +
"</student>" +
"</students>";
response.setContentType("text/xml;charset=utf-8");
response.getWriter().print(xml);
}
}
ajax.4
window.onload = function() {
var btn = document.getElementById("btn");
btn.onclick = function() {
var xmlHttp = createXMLHttpRequest();
xmlHttp.open("GET", "<c:url value='/BServlet'/>", true);
xmlHttp.send(null);
xmlHttp.onreadystatechange = function() {
if(xmlHttp.readyState == 4 && xmlHttp.status == 200) {
var doc = xmlHttp.responseXML;
var ele = doc.getElementsByTagName("student")[0];
var number = ele.getAttribute("number");
var name;
var age;
var sex;
if(window.addEventListener) {
name = ele.getElementsByTagName("name")[0].textContent;//其他浏览器
} else {
name = ele.getElementsByTagName("name")[0].text;//IE支持
}
if(window.addEventListener) {
age = ele.getElementsByTagName("age")[0].textContent;//其他浏览器
} else {
age = ele.getElementsByTagName("age")[0].text;//IE支持
}
if(window.addEventListener) {
sex = ele.getElementsByTagName("sex")[0].textContent;//其他浏览器
} else {
sex = ele.getElementsByTagName("sex")[0].text;//IE支持
}
var text = number + ", " + name + ", " + age + ", " + sex;
document.getElementById("h1").innerHTML = text;
}
};
};
};
</script>
</head>
<body>
<button id="btn">点击这里</button>
<h1 id="h1"></h1>
</body>
省市联动
首先写表单:
ajax5.jsp
<body>
<h1>省市联动</h1>
<select name="province" id="p">
<option>===请选择省===</option>
</select>
<select name="city" id="c">
<option>===请选择市===</option>
</select>
</body>
选择省份:
页面在加载完成后,读取china.xml中的所有province的name属性,并用“,”连接成字符串返回给页面
public class ProvinceServlet extends HttpServlet {
public void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
request.setCharacterEncoding("utf-8");
response.setContentType("text/html;charset=utf-8");
/*
* 创建解析器对象
* 调用读方法得到Document
*/
SAXReader reader=new SAXReader();
InputStream input=this.getClass().getResourceAsStream("/china.xml");
try {
Document doc=reader.read(input);
/*
* 查询所有province的name属性
* 将所有属性值连接成一个字符串发送给客户端
*/
List<Attribute> a=doc.selectNodes("//province/@name");
StringBuilder sb=new StringBuilder();
for(int i=0;i<a.size();i++) {
sb.append(a.get(i).getValue());
if(i<a.size()-1)
sb.append(",");
}
response.getWriter().print(sb);
} catch (DocumentException e) {
throw new RuntimeException(e);
}
}
}
页面得到text信息,再将字符串分割成数组,为每个数组元素创建一个option,其实际值和显示值都为省份名称,再把每个option加到省份下拉框中
/*
* 请求ProvinceServlet得到所有省份名
* 遍历创建<option>
*/
window.onload=function(){//页面加载完成即执行
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(",");
for(var i=0;i<arr.length;i++){
var op=document.createElement("option");
op.value=arr[i];//设置实际值
var textNode=document.createTextNode(arr[i]);
op.appendChild(textNode);//设置显示值
document.getElementById("p").appendChild(op);
}
}
};
选择市:
在jsp页面添加改变监听器,在选项改变时,发送省份名称给CityServlet,它根据省份名称返回一个省的xml给页面
public class CityServlet extends HttpServlet {
public void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
request.setCharacterEncoding("utf-8");
response.setContentType("text/xml;charset=utf-8");//注意发送xml时这里要修改
/*
* 获取省份名称
* 使用省份名称查找到对应<province>元素
* 把province元素转换成字符串发送
*/
SAXReader reader=new SAXReader();
InputStream in=this.getClass().getResourceAsStream("/china.xml");
Document doc;
try {
doc = reader.read(in);
String pname=request.getParameter("pname");
Element proEle=(Element) doc.selectSingleNode("//province[@name='"+pname+"']");
String xmlStr=proEle.asXML();//把元素转换为字符串
response.getWriter().print(xmlStr);
} catch (DocumentException e) {
throw new RuntimeException(e);
}
}
}
页面同样根据xml创建option,添加到市的下拉框中:
/*
* 给province选择添加改变监听
* 使用选择的省份名请求CityServlet元素,得到<privince>元素
* 获取<province>元素中所有<city>元素,遍历获取文本内容发送字符串
* 创建<option>元素
*/
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){
//移除上次的结果
var citySelect=document.getElementById("c");
var optionEleList=citySelect.getElementsByTagName("option");
while(optionEleList.length>1)
citySelect.removeChild(optionEleList[1]);
var doc=xmlHttp.responseXML;
var cityEleList=doc.getElementsByTagName("city");
for(var i=0;i<cityEleList.length;i++){
var cityEle=cityEleList[i];
var cityName;
if(window.addEventListener)
cityName=cityEle.textContent;
else
cityName=cityEle.text;
var op=document.createElement("option");
op.value=cityName;
var textNode=document.createTextNode(cityName);
op.appendChild(textNode);
citySelect.appendChild(op);
}
}
};
};
};
XStream
从数据库中查询出来的都是JavaBean对象,需要先将其转换为xml才能供页面使用。
XStream就是可以把JavaBean转换(序列化)为xml的工具。
需要先导入两个包:
- 核心:xstream.jar
- 依赖:xpp_min
使用:
XStream xstream=new XStream();
String xmlStr=xstream.toXML(javabean);
但这样生成的xml的格式并不是很好,例如:
public class City {
private String name;//市名
private String description;//描述
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getDescription() {
return description;
}
public void setDescription(String description) {
this.description = description;
}
public String toString() {
return "City [name=" + name + ", description=" + description + "]";
}
public City(String name, String description) {
super();
this.name = name;
this.description = description;
}
}
public class Province {
private String name;// 省名
private List<City> cities = new ArrayList<City>();
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public List<City> getCities() {
return cities;
}
public void setCities(List<City> cities) {
this.cities = cities;
}
public void addCity(City city) {
cities.add(city);
}
}
public class Demo1 {
public List<Province> getProinvceList() {
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 = getProinvceList();
XStream xstream = new XStream();//使用XStream
String s = xstream.toXML(proList);
System.out.println(s);
}
}
得到的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>
让xml更好看的使用细节:
- 别名:
xstream.alias("china",List.class)
让List类型生成的元素名为china - 使用为属性:
xstream.useAttributeFor(Province.class,"name")
name是成员变量,默认生成name元素,这里改为生成province元素的name属性 - 去除某类型成员:
xstream.addImplicitCollection(Province.class,"cities")
让Province类型的cities成员不生成元素,只使用其内容 - 去除类的指定成员:
xstream.omitField(City.class,"description")
在生成的xml中不会出现City类的description的元素
public void fun5() {
List<Province> proList = getProinvceList();
XStream xstream = new XStream();
xstream.alias("china", List.class);//给List类型指定别名为china
xstream.alias("province", Province.class);//给Province指定别名为province
xstream.alias("city", City.class);//给City类型指定别名为city
xstream.useAttributeFor(Province.class, "name");//把Province类型的name属性,生成<province>元素的属性
xstream.addImplicitCollection(Province.class, "cities");//去除Provice类的名为cities的List类型的属性
xstream.omitField(City.class, "description");//让City类的,名为description属性不生成对应的xml元素
String s = xstream.toXML(proList);
System.out.println(s);
}
得到:
<china>
<province name="北京">
<city>
<name>东城区</name>
</city>
<city>
<name>昌平区</name>
</city>
</province>
<province name="辽宁">
<city>
<name>沈阳</name>
</city>
<city>
<name>葫芦岛</name>
</city>
</province>
</china>
JSON
JSON是js提供的一种数据交换格式
语法:
- { }:对象
- " ":属性(不能用单引号)
- 属性值:
null
数值
字符串
数组:用[ ]括起来
var str = "{"name": "zhangSan", "age": 18, "sex": "male"}";
var person = eval("(" + str + ")");//该函数执行字符串
JSON与xml的比较
- 可读性:xml更好
- 解读难度:JSON本身就是js对象,所以简单很多
- 流行度:xml已经流行很多年,但在ajax领域,JSON更受欢迎
json-lib的应用
导包:
commons-beanutils.jar
commons-collections.jar
commons-lang.jar
commons-logging.jar
ezmorph.jar
json-lib-jdk.jar
xom.jar
核心类:
- JSONObject(Map)
String s=map.toString()
JSONObject map=JSONObject.fromObject(person)
把对象转换成JSONObject对象
- JSONArray(Map)
Strings=list.toString()
JSONArray jsonArray=JSONObject.fromObject(list);
把list转换成JSONArray对象
//当做map使用
public void fun1() {
JSONObject map = new JSONObject();
map.put("name", "zhangSan");
map.put("age", 23);
map.put("sex", "male");
String s = map.toString();
System.out.println(s);
}
//已经有一个Person对象时,可以把Person对象转换成JSONObject对象
public void fun2() {
Person p = new Person("liSi", 32, "female");
// 把对象转换成JSONObject类型
JSONObject map = JSONObject.fromObject(p);
System.out.println(map.toString());
}
//当做list使用
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());
}
最后
以上就是文静日记本为你收集整理的【JavaWeb】21 AJAX/XStream/JSONajax案例XStreamJSON的全部内容,希望文章能够帮你解决【JavaWeb】21 AJAX/XStream/JSONajax案例XStreamJSON所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
发表评论 取消回复