元素中。
4.2代码实现 服务器端:使用china.xml保存所有省份和城市名称: china.xml 东城区 西城区 …… 和平区 河东区 …… 石家庄 衡水 …… ……
*ProvinceServlet.java public class ProvinceServlet extends HttpServlet { public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { // 注意设置编码 response.setContentType("text/html;charset=utf-8"); // 使用DOM4J解析xml文档 InputStream input = this.getClass().getClassLoader().getResourceAsStream("china.xml"); SAXReader reader = new SAXReader(); try { Document doc = reader.read(input); // xpath查询所有province元素的name属性 List provinceNameAttributeList = doc.selectNodes("//province/@name"); // 用来装载所有name属性值 List provinceNames = new ArrayList(); // 遍历每个属性,获取属性名称,添加到list中 for(Attribute proAttr : provinceNameAttributeList) { provinceNames.add(proAttr.getValue()); } // System.out.println(provinceNames); // 把list转换成字符串 String str = provinceNames.toString(); // 把字符串前后中的[]去除发送给客户端 response.getWriter().print(str.substring(1, str.length()-1)); } catch (DocumentException e) { throw new RuntimeException(e); } } }
*CityServlet.java public class CityServlet extends HttpServlet { public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { request.setCharacterEncoding("utf-8"); // 注意,这里内容类型必须是text/xml,不然客户端得到的就不是xml文档对象,而是字符串了。 response.setContentType("text/xml;charset=utf-8"); // 获取省份参数 String provinceName = request.getParameter("provinceName"); InputStream input = this.getClass().getClassLoader().getResourceAsStream("china.xml"); SAXReader reader = new SAXReader(); try { Document doc = reader.read(input); // 查询指定省份名称的元素 Element provinceElement = (Element)doc.selectSingleNode("//province[@name='" + provinceName + "']"); // System.out.println(provinceElement.asXML()); // 把元素转换成字符串发送给客户端 response.getWriter().print(provinceElement.asXML()); } catch (Exception e) { throw new RuntimeException(e); } } }
客户端: *在打开select.jsp页面时就向服务器请求所有省份的名称,添加到元素中。 *给元素添加onchange事件监听,内容为向服务器发送请求,得到XML文档:元素,然后解析它,添加到中。 // 文档加载完成后 // 加载所有省份名称 window.onload = function() { /* 请求服务器,加载所有省名称到中 */ /* 1. ajax四步 */ var xmlHttp = createXMLHttpRequest(); xmlHttp.onreadystatechange = callback;//服务器响应完成后执行callback函数 xmlHttp.open("GET", "/ajaxdemo1/ProvinceServlet", true);//向服务器发送GET请求 xmlHttp.send(null);//发送请求 }; // 本方法获取服务器响应的所有省份的名称 function callback() { if(this.readyState == 4 && this.status == 200) { // 把服务器响应的省份名称,使用逗号分割成字符串数组 var provinceNameArray = this.responseText.split(", "); // 遍历每个省份名称,使用每个省份名称创建元素,添加到province的中 for(var i = 0; i < provinceNameArray.length; i++) { addProvinceOption(provinceNameArray[i]); } // 为province的元素添加onchange事件监听 document.getElementById("province").onchange = loadCities; } } // 本函数在province的元素发送变化时执行! // 本函数会使用当前选中的省份名称为参数,向服务器发送请求,获取当前省份下的所有城市! function loadCities() { var proName = this.value;//获取选择的省份名称 /* AJAX4步 */ var xmlHttp = createXMLHttpRequest();//创建异常对象 // 指定回调函数 xmlHttp.onreadystatechange = function() { if(xmlHttp.readyState == 4 && xmlHttp.status == 200) { // 得到服务器响应的xml文档对象 var doc = xmlHttp.responseXML;//注意,这里使用的是resopnseXML属性,不是resopnseText // 获取文档中所有city元素 var cityElementList = doc.getElementsByTagName("city"); // 获取html元素:city的 var citySelect = document.getElementById("city"); // 删除city的元素的所有子元素 removeChildNodes(citySelect); // 创建元素,指定文本内容为“请选择” var qxzOption = document.createElement("option"); var textNode = document.createTextNode("===请选择==="); qxzOption.appendChild(textNode); // 把"请选择"这个 添加到元素中 citySelect.appendChild(qxzOption); // 循环遍历每个服务器端响应的每个元素 for(var i = 0; i < cityElementList.length; i++) { var cityEle = cityElementList[i]; var cityName = null; // 获取元素的文本内容!处理浏览器差异! if(window.addEventListener) { cityName = cityEle.textContent; } else { cityName = cityEle.text; } // 使用城市名称创建,并添加到元素中 addCityOption(cityName); } } }; xmlHttp.open("POST", "/ajaxdemo1/CityServlet", true);//打开与服务器的连接 // 因为是POST请求,所以要设置Content-Type请求头 xmlHttp.setRequestHeader("Content-Type", "application/x-www-form-urlencoded"); // 参数为当前选中的省份名称 xmlHttp.send("provinceName=" + proName); } // 使用proName创建元素添加到元素中 function addProvinceOption(proName) { var option = document.createElement("option");//创建元素 var textNode = document.createTextNode(proName);//使用省份名称创建文本节点 option.appendChild(textNode);//把省份名称的文本节点添加到 元素中 option.setAttribute("value", proName);//使用省份名称来设置 元素的value属性 document.getElementById("province").appendChild(option);//把 元素添加到元素中 } // 本函数用来创建城市的,并添加到元素中 function addCityOption(cityName) { var citySelect = document.getElementById("city");//获取id为city的 var cityOption = document.createElement("option");//创建元素 var textNode = document.createTextNode(cityName);//使用城市名称创建文本节点 cityOption.appendChild(textNode);//把文本节点添加到 元素中 cityOption.setAttribute("value", cityName);//设置 元素的value属性为城市名称 citySelect.appendChild(cityOption);//把 元素添加到元素中 } //删除指定元素的所有子元素 function removeChildNodes(ele) { var nodes = ele.childNodes;//获取当前元素的所有子元素集合 while(nodes.length > 0) {//遍历所有子元素 ele.removeChild(nodes[0]);//删除子元素 } }
XStream 1.XStream的作用 XStream可以把JavaBean对象转换成xml。 通常服务器向客户端响应的数据都是来自数据库的一组对象,而我们不能直接把对象响应给响应端,所以我们需要把对象转换成xml再响应给客户端,这时就需要XStream组合了。
2.XStream入门 预先准备两个类Province和City City.java public class City{ private String name; private String desctipion; ... }
Province.java public class Province{ private String name; private List cities = new ArrayList();
public void addCity(City city){ cities.add(city); } }
接下来,我们需要写一个main(),创建一个List, List中存放两个Province对象,最终我们把List转化成XML Province p1 = new Province("辽宁省"); p1.addCity(new City("沈阳", "shenyang")); p1.addCity(new City("大连", "dalian")); Province p2 = new Province("吉林省"); p2.addCity(new City("长春", "changchen")); p2.addCity(new City("白城", "baicheng")); List list = new ArrayList();
list.add(p1); list.add(p2);
2.1XStream相关JAR包 我们可以到http://xstream.codehaus.org/地址去下载XStream安装包 XStream的必须要的jar包 *核心jar包:xstream-xxx.jar *必须依赖包:xpp3_min-xxxc(XML Pull Parser, 一款速度很快的XML解析器);
2.2使用XStream啊Java对象转换成XML 下面是使用XStream转换成list为xml的代码: XStream xstream = new XStream(); String s = xstream.toXML(list); System.out.println(s);
辽宁省 沈阳 shenyang 大连 dalian 吉林省 长春 changchen 白城 baicheng
也就是说,XStream是根据对象名、类名、属性名来生成XML文档的。 2.3alias用法 大家也看到了,生成的XML中,与类名对应的元素名称包含了包名部分,这就很不好看,若想自定义生成的元素名称,需要使用XStream为类名提供别名: stream.alias("province", Province.class); xstream.alias("china", List.class); xstream.alias("city", City.class);
辽宁省 沈阳 shenyang 大连 dalian 吉林省 长春 changchen 白城 baicheng
2.4把子元素变为元素属性 例如我们需要把子元素变成:样式,那么需要调用如下方法: xstream.useAttributeFor(Province.class, "name");
沈阳 shenyang 大连 dalian 长春 changchen 白城 baicheng
2.5去除集合属性对应元素 因为Province类有一个cities成员,所以生成了元素,但这个元素对XML文档而言没有什么意义,所以我们需要把它去除 xstream.addImplicitCollection(Province.class, "cities");
沈阳 shenyang 大连 dalian 长春 changchen 白城 baicheng
2.6让类的成员不生成对应的XML元素 到现在为止,我们都是每个类,每个成员都有对应的元素(或属性)存在,但是有时我们并不希望某些类的成员在对应的xml文档中出现,例如我们不希望City类的description成员出现在xml文档中,可以使用下面方法: xstream.omitField(City.class, "description");
沈阳 大连 长春 白城
JSON 1.什么是json json(JavaScript Object Notation)是一种轻量级的数据交换格式。 json是用字符串来表示JavaScript对象,例如可以在Servlet中发送一个json格式的字符串个客户端JavaScript,JavaScript可以执行这个字符串,得到一个JavaScript对象。 xml也可以用来为数据交换,前面学习的Servlet中发送xml给JavaScript,然后JavaScript在切解析xml
2.json对象语法 json语法: *数据在名称/值对中 *数据有逗号分隔 *花括号保存对象 *方括号保存数组
var person = {"name" : "zhangSan", "age" : "18", "sex" : "male"}; alert(person.name = "," + person.age + "," + person.sex);
注意,key也要在双引号中
JSON值: *数字(整数或浮点数) *字符串(在双引号中) *逻辑值(true或false) *数组(在方括号中) *对象(在花括号中) *null
var person = { "name" : "zhangSan", "age" : "19", "sex" : "male", "hobby" : ["cf", "sj", "ddm"] }; alert(person.name + ", " + person.age + ", " + person.sex + ", " + person.hobby);
带有方法的json对象 var person = {"name" : "zhangSan", "getName" : function(){ this.name; }}; alert(person.name); alert(person.getName());
3.json与xml比较 *可读性:xml胜出; *解码难度:json本身就是js对象(主场作战),所以简单很多; *流行度:xml已经流行很多年,但在ajax领域,json更受欢迎。
4.把java对象转换成json对象 apache提供的json-lib小工具,它可以方便的使用Java语言来创建json字符串。也可把JavaBean转换成json字符串。
4.1json-lib核心jar包 json-lib的核心jar包有: *json-lib.jar json-lib依赖jar包有: *commons-lang.jar *commons-beanutils.jar *commons-logging.jar *commons-collections.jar *ezmorph.jar
4.2json-lib中的核心类 在json-lib中只有两个核心类: *JSONObject; *JSONArray;
4.2.1JSONObject JSONObject类本身是一个Map,所以学习它很方便。 JSONObject jo = new JSONObject(); jo.put("name", "zhangSan"); jo.put("age", "18"); jo.put("sex", "male"); System.out.println(jo.toString());
Person person = new Person("liSi", 18, "female"); JSONObject jo = JSONObject.fromObject(person); System.out.println(jo.toString());
Map map = new HashMap(); map.put("name", "wangWu"); map.put("age", "81"); map.put("sex", "male"); JSONObject jo = JSONObject.fromObject(map); System.out.println(jo.toString());
String xml = "zhaoLiu 59 female "; XMLSerializer serial = new XMLSerializer(); JSONObject jo = (JSONObject)serial.read(xml); System.out.println(jo.toString());
4.2.2JSONArray JSONArray本身是一个List,所以使用起来很方便。 JSONArray ja = new JSONArray(); Person p1 = new Person("zhangSan", 18, "male"); Person p2 = new Person("liSi", 23, "female"); ja.add(p1); ja.add(p2); System.out.println(ja.toString());
Person p1 = new Person("zhangSan", 18, "male"); Person p2 = new Person("liSi", 23, "female"); List list = new ArrayList(); list.add(p1); list.add(p2); JSONArray ja = JSONArray.fromObject(list); System.out.println(ja.toString());
Person p1 = new Person("zhangSan", 18, "male"); Person p2 = new Person("liSi", 23, "female"); Person[] persons = {p1, p2}; JSONArray ja = JSONArray.fromObject(persons); System.out.println(ja.toString());
5.js解析服务器发送过来的json字符串 服务器发送过来的json字符串后,客户端需要对其进行解析。这时客户端需要使用eval()方法对json字符串进行执行。但要注意,eval()方法在执行json时,必须把json字符串使用一对圆括号括起来。 var json = "{\"name\" : \"zhangSan\", \"age\" : \"18\", \"sex\" : \"male\"}"; var person = eval("("+json+")"); alert(person.name+", "+ person.age+","+person.sex);
笔记:
1.ajax是什么 *asynchronous JavaScript and xml : 异步的js和xml *它能使用js访问服务器,而且是异步方法 *服务器给客户端的响应一般是整个页面,一个html完整页面,但在ajax中因为是局部刷新,那么服务器就不用在响应整个页面,而只是数据 >text:纯文本 >xml: >json:它是js提供的数据交互格式,它在ajax中最受欢迎
2.异步交互和同步交互 *同步: >发一个请求,就要等待服务器的响应结束,然后才能发第二个请求,中间这段时间就是一个字“卡” >刷新的是整个页面 *异步: >发一个请求后,无需等待服务器的响应,然后就可以发第二个请求 >可以使用js接收服务器的响应,然后使用js来局部刷新
3.ajax应用场景 *百度的搜索框 *用户注册时(校验用户名是否被注册)
4.ajax的优缺点 优点: *异步交互:增强了用户的体验 *性能:因为服务器无需响应整个页面,只需要响应部分内容,所有服务器的压力减轻了。 缺点: *ajax不能应用在所有场景 *ajax无端的增多了对服务器的访问次数,给服务器带来了压力
ajax发送异步请求(四步操作) 1.第一步(得到了XMLHttpRequest) *ajax其实只需要学习一个对象:XMLHttpRequest,如果掌握了它,就掌握了ajax *得到XMLHttpRequest >大多数浏览器都是支持:var xmlHttp = new XMLHttpRequest(); >IE6.0: var xmlHttp = new ActiveXObject("Msxml2.XMLHTTP"); >IE5.5即更早版本的IE:var xmlHttp = new AvtiveXObject("Microsoft.XMLHTTP"); *编写创建XMLHttpRequest对象的函数 function createXMLHttpRequest(){ try{ return new XMLHttpRequest(); }catch(e){ try{ return new ActiveXObject("Msxml2.XMLHTTP"); }catch(e){ try{ return new ActiveXObject("Microsoft.XMLHTTP"); }catch(e){ alert("未知浏览器"); throw e; } } } } 2.第二步(打开与服务器的连接) *xmlHttp.open():用来打开与服务器的连接,它需要三个参数: >请求方式:可以是GET或POST >请的URL:指定服务器端资源,例如:/day23-1/AServlet >请求是否为异步:如果为true表示发送异步请求,否则同步请求, *xmlHttp.open("GET", "/day23-3/AServlet", true); 3.第三步:(发送请求) *xmlHttp.send(null);如果不给可能会造成部分浏览器无法发送。 >参数:就是请求体内容,如果是GET请求,必须给出null。 4.第四步() *在xmlHttp对象的一个事件注册监听器:onreadystatechange *xmlHttp对象一共有5个状态: >0:刚创建,还没有调用open()方法; >1:请求开始:调用open()方法,单还没调用send()方法 >2:调用完了send()方法了; >3:服务器已经开始响应了,但是不表示响应结束了 >4:服务器响应结束(通常只关心这个状态) *得到xmlHttp对象的状态: >var state = xmlHttp.readyState;//可能是0、1、2、3、4 *得到服务器响应的状态码 >var staus = xmlHttp.status;//例如为200,404,500 *得到服务器响应的内容1 >var content = xmlHttp.responseText;//得到·服务器的响应的文本格式的内容 >var content = xmlHttp.responserXML;//得到服务器的响应的xml响应的内容,它是Document对象了 xmlHttp.onreadystatechange = function() {//xmlHttp的5种状态都会调用本方法 if(xmlHttp.readyState == 4 && xmlHttp.status == 200) {//双重判断:判断是否为4状态,而且还要判断是否为200 // 获取服务器的响应内容 var text = xmlHttp.responseText; } };
第二例: 发送POST请求(如果发送请求时需要带有参数,一般都是用POST请求) *open:xmlHttp.open("POST" ....); *添加异步:设置Content-Type请求头: >xmlHttp.setRequestHeader("Content-Type", "application/x-www-form-urlencoded"); *send:xmlHttp.send("username=zhangSan&password=123");//发送请求时指定请求体
第三例: 注册表单之校验用户是否注册 1.编写页面: *ajax3.jsp >给出注册表单页面 >给用户名文本框添加onblur事件的监听 >获取文本框的内容,通过ajax4步发送给服务器,得到响应结果 *如果为1:在文本框后显示:用户名已被注册 *如果为0:在文本框后显示: 2.编写Servlet *ValidataUsernameServlet >获取客户端传递的用户名参数 >判断是否为changeMax *是:返回1 *否:返回0
第四例:响应内容为xml数据 响应内容为xml数据 *服务器端: >设置响应头: ContentType,其值为:text/xml;charset=utf-8 *客户端: >var doc = xmlHttp.responseXML;//得到的是Document对象
第五例:省市联动 1.页面: ===请选择省份=== ===请选择城市===
2.ProvinceServlet *ProvinceServlet:当页面加载完毕后马上请求这个Servlet >它需要加载china.xml文本,把所有的省的名称使用字符串发送给客户端 3.页面的工作 *获取这个字符串,使用逗号分隔,得到数组 *循环遍历每个字符串(省份的名称),使用每个字符串创建一个元素添加到这个元素中 4.CityServlet *CityServlet:当页面选择某个省时,发送请求 *得到省份的名称,加载china.xml文件,查询出该省份对应的元素对象。把这个元素转换成xml字符串,发送给客户端 5.页面的工作 *把中的所有子元素删除,但不要删除<>===请选择城市=== *得到服务器的响应结果:doc *获取所有的子元素,循环遍历,得到的内容 *使用每个的内容创建一个元素,添加到
XStream 1.什么作用 *可以把javabean转换为(序列化为)xml 2.XStream的jar包 *核心jar包:xstream-1.4.7.jar; *必须依赖包:xpp3.min-xxx(XML Pull Parser,一款速度很快的XML解析器); 3.使用步骤 *XStream xstream = new XStream(); *String xmlStr = xstream.toXML(javabean); 4.使用细节 *别名:把类型对应的元素名修改了 >xstream.alias("china", List.class);让List类型生成的元素名为china >xstream.ailas("province", Province.class);让Province类型生成的元素名为province *使用为属性:默认类的成员,生成的是元素的子元素,我们希望让类的成员生成元素的属性 >xstream.useAttributeFor(Province.class, "name");把Province类的名为name的成员,生成元素的name属性 *去除Collection类型的成名:我们只需要Collection的内容,而不希望Collection本身也生成一个元素 >xstream.addImplicitCollection(Province.class, "citieList");让Province类的名为citieList(它是List类型的,它的内容还会生成元素)的成名不生成元素 *去除类的指定成名,让其不生成xml元素 >xstream.omitField(City.calss, "description");在生成的xml中不会出现City类的名为description的对应的元素。
JSON 1.json是什么 *它是js提供的一种数据交换格式 2.json的语法 *{}:是对象。 >属性名必须使用双引号括起来,单引号不行 >属性值: *null *数值 *字符串 *数值:使用[]括起来 *boolean值:true和false 3.应用json *var person = {"name":"wangji", "age":"11", "sex":"male"}; 4.json与xml比较 *可读性:xml胜出 *解析难度:json本身就是js对象(主场作战),所以简单很多 *流行度:xml已经流行了好多年,但在ajax领域,json还是更受欢迎
json-lib 1.这是什么: *它可以把javabean转换成json串 2.jar包 *略 3.核心类 *JSONObejct --> Map >toString(); >JSONObject map = JSONObject.fromObejct(person);把对象转换成JSONObject对象 *JSONArray -->List >toString() >JSONArray jsonArray = JSONObject.fromObject(list);把list转换成JSONArray对象