省市联动
1、页面
<select name="province">
<option>选择省份</option>
</select>
<select name="city">
<option>选择城市</option>
</select>
2、Servlet
ProvinceServlet:当页面加载完毕后马上请求这个Servlet
需要加载china.xml文件,把所有的省的名称使用字符串发送给客户端
3、页面的工作
获取这个字符串,使用逗号分隔,得到数组
循环遍历每个字符串(省份的名称),使用每个字符串创建一个<option>添加到<select name="province">这个元素中
4、CityServlet
CityServlet:当页面选择某个省时,发送请求
得到省份的名称,加载china.xml文件,查询出该省份对应的元素对象。把这个元素转换成xml字符串,发送给客户端
5、页面的工作
把<select name="city">中所有子元素删除,但不要删除<option>选择城市</option>
得到服务器的响应结果:doc
获取所有的<city>子元素,循环遍历,得到<city>的内容
使用每个<city>的内容创建一个<option>元素,添加到<select name="city">
XStream
1、作用
把JavaBean转换为(序列化)xml
2、XStream的jar包
核心JAR包:xstream-1.4.x.jar
必须依赖包:xpp3_min-1.1.4c(XML Pull Parser速度很快的XML解析器)
3、使用步骤
XStream xstream = new XStream();
String xmlStr = xstream.toXML(javabean);
4、使用细节
别名:把类型对应的元素名修改
xstream.alias("china",List.class);让List类型生成的元素名为china
xstream.alias("province",Province.class):让Province类生成的元素名为province
使用为属性:默认类的成员,生成的是元素的子元素。希望让类的成员生成元素的属性
xstream.useAttributeFor(Province.class,"name"):把Province类的名为name成员,生成<province>元素的name属性
去除集合Collection类型的成员:只需要Collection的内容,而不希望Collection本身也生成一个元素
xstream.addImplicitCollection(Province.class,"cities"):让Province类的名为cities(是List类型的,内容还会生成元素)的成员不生成元素
去除类的指定成员,让其不生成xml元素
xstream.omitField(City.class,"description"):在生成的xml中不会出现City类的。名为description的对应的元素
JSON
json
是js提供的一种数据交换格式
json的语法
{}:是对象
属性名必须使用双引号括起来。单引不行
属性值:
null
数值
字符串
数组:使用[]括起来
boolean值:true和false
3、应用json
var person = {"name":"zs","age":11,"sex":"male"}
ajax.jsp
<script type="text/javascript">
function createXMLHttpRequest(){
try{
return new XMLHttpRequest();//大多数浏览器
}catch(e){
try{
return ActiveXObject("Msxml2.XMLHTTP");//IE6.0
}catch(e){
try{
return ActiveXObject("Microsoft.XMLHTTP");//IE5.5及更早
}catch(e){
alert("什么浏览器?");
throw e;
}
}
}
}
/*
1、在文档加载完毕时发送请求,得到所有省份名称,显示在<select name="province"/>中
2、在选择了新的省份时,发送请求(参数为省名称),得到xml文档,即<province>元素
解析xml文档,得到其中所有的<city>,再得到每个<city>元素的内容,即市名,使用市名生成<option>,插入到<select name="city">元素中
*/
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.getElementsByTagName("option");
//循环遍历每个option元素,然后在citySelect中移除
while(optionEleList.length>1){//子元素的个数如果大于就循环,等于1就不循环
citySelect.removeChild(optionEleList[1]);//总是删除1下标,因为1删除了,2就变成1了
}
var doc = xmlHttp.responseXML;
//得到所有名为city的元素
var cityEleList = doc.getElementsByTagName("city");
//循环遍历每个city元素
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
}
//使用市名称创建option元素.添加到<select name ="city">中
var op = document.createElement("option");
op.value = cityName;
//创建文本节点
var textNode = document.createTextNode(cityName);
op.appendChild(textNode);//把文本节点追加到op元素中
//把op添加到<select>元素中
citySelect.appendChild(op);
}
}
}
};
};
</script>
</head>
<body>
<h1>省市联动</h1>
<select name="province" id="p">
<option>选择省</option>
</select>
<select name="city" ID="c" >
<option>选择市</option>
</select>
</body>
ProvinceServlet
public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
request.setCharacterEncoding("utf-8");
response.setContentType("text/html;charset=utf-8");
/*
* 响应所有省份名称,使用逗号分隔
*/
/*
* 1、得到Document对象
* 创建解析器对象
* 调用解析器的读方法,传递一个流对象,得到Document
*/
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");//xpath查找 [//]没有深度查找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 (DocumentException e) {
throw new RuntimeException(e);
}
}
CityServlet
public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
request.setCharacterEncoding("utf-8");
response.setContentType("text/xml;charset=utf-8");//发送xml时这里要修改
/*
* 获取省份名称,加载该省对应的<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+"']");//province[@name='a']
String xmlStr = proEle.asXML();//把元素转换成字符串
response.getWriter().print(xmlStr);
} catch (DocumentException e) {
throw new RuntimeException(e);
}
}
xxx.xml
<china>
<province name="a">
<city>1</city>
<city>2</city>
</province>
<province name="b">
<city>11</city>
<city>22</city>
</province>
</china>
public class City {
private String name;//市名
private String description;//描述
set get 有参无参
public class Province {
private String name;
private List<City> cities = new ArrayList<City>();
set get 有参无参
public void addCity(City city){
cities.add(city);
}
public class Demo1 {
//返回javaBean集合
public List<Province> getProvinceList(){
Province p1 = new Province();
p1.setName("a");
p1.addCity(new City("1","11"));
p1.addCity(new City("2","22"));
Province p2 = new Province();
p2.setName("b");
p2.addCity(new City("3","33"));
p2.addCity(new City("4","44"));
List<Province> provinceList = new ArrayList<Province>();
provinceList.add(p1);
provinceList.add(p2);
return provinceList;
}
/*
<list>-->List类型显示list
<my.demo.Province> -->javabean类型为Province,元素的名称为类的完整名
<name>a</name>-->javabean的属性名
<cities>-->javabean的属性名
<my.demo.City>-->类名
<name>1</name>-->属性名
<description>11</description>-->属性名
</my.demo.City>
<my.demo.City>
<name>2</name>
<description>22</description>
</my.demo.City>
</cities>
</my.demo.Province>
<my.demo.Province>
<name>b</name>
<cities>
<my.demo.City>
<name>3</name>
<description>33</description>
</my.demo.City>
<my.demo.City>
<name>4</name>
<description>44</description>
</my.demo.City>
</cities>
</my.demo.Province>
</list>
*/
@Test
public void fun1(){
List<Province> proList = getProvinceList();
/*
* 创建XStream对象
* 调用toXML把集合转换成xml字符串
*/
XStream xstream = new XStream();
String s = xstream.toXML(proList);
System.out.println(s);
}
/*
* 别名(alias)
* 希望:
* 默认List类型对应<list>元素,希望让List类型对应<china>元素
* 默认Province类型对应<my.demo.Province>希望让它对应<province>
* 默认city类型对应<my.demo.City>希望它对应<city>元素
*/
/*
<china>
<province>
<name>a</name>
<cities>
<city>
<name>1</name>
<description>11</description>
</city>
<city>
<name>2</name>
<description>22</description>
</city>
</cities>
</province>
<province>
<name>b</name>
<cities>
<city>
<name>3</name>
<description>33</description>
</city>
<city>
<name>4</name>
<description>44</description>
</city>
</cities>
</province>
</china>
*/
@Test
public void fun2(){
List<Province> proList = getProvinceList();
XStream xstream = new XStream();
/*
* 给指定的类型指定别名
*/
xstream.alias("china",List.class);//给list类型指定别名china
xstream.alias("province", Province.class);//给Province指定别名
xstream.alias("city", City.class);//给City类型指定别名为city
String s = xstream.toXML(proList);
System.out.println(s);
}
/*
* 默认javabean的属性都会生成子元素,而现在希望生成元素的属性
*/
/*
<china>
<province name="a">
<cities>
<city>
<name>1</name>
<description>11</description>
</city>
<city>
<name>2</name>
<description>22</description>
</city>
</cities>
</province>
<province name="b">
<cities>
<city>
<name>3</name>
<description>33</description>
</city>
<city>
<name>4</name>
<description>44</description>
</city>
</cities>
</province>
</china>
*/
@Test
public void fun3(){
List<Province> proList = getProvinceList();
XStream xstream = new XStream();
xstream.alias("china",List.class);//给list类型指定别名china
xstream.alias("province", Province.class);//给Province指定别名
xstream.alias("city", City.class);//给City类型指定别名为city
/*
* 把Province类的name属性,生成<province>元素的属性
*/
xstream.useAttributeFor(Province.class,"name");
String s = xstream.toXML(proList);
System.out.println(s);
}
/*
* 去除List类型的属性,只把List中的元素生成xml元素
*/
/*
<china>
<province name="a">
<city>
<name>1</name>
<description>11</description>
</city>
<city>
<name>2</name>
<description>22</description>
</city>
</province>
<province name="b">
<city>
<name>3</name>
<description>33</description>
</city>
<city>
<name>4</name>
<description>44</description>
</city>
</province>
</china>
*/
@Test
public void fun4(){
List<Province> proList = getProvinceList();
XStream xstream = new XStream();
xstream.alias("china",List.class);//给list类型指定别名china
xstream.alias("province", Province.class);//给Province指定别名
xstream.alias("city", City.class);//给City类型指定别名为city
xstream.useAttributeFor(Province.class,"name");//把Province类的name属性,生成<province>元素的属性
/*
* 去除<cities>这样的Collection类型的属性
* 取出Province类的名为cities的List类型的属性
*/
xstream.addImplicitCollection(Province.class, "cities");
String s = xstream.toXML(proList);
System.out.println(s);
}
/*
*去除不想要的javabean属性
*就是让某些javabean属性,不生成对应的xml元素
*/
/*
<china>
<province name="a">
<city>
<name>1</name>
</city>
<city>
<name>2</name>
</city>
</province>
<province name="b">
<city>
<name>3</name>
</city>
<city>
<name>4</name>
</city>
</province>
</china>
*/
@Test
public void fun5(){
List<Province> proList = getProvinceList();
XStream xstream = new XStream();
xstream.alias("china",List.class);//给list类型指定别名china
xstream.alias("province", Province.class);//给Province指定别名
xstream.alias("city", City.class);//给City类型指定别名为city
xstream.useAttributeFor(Province.class,"name");//把Province类的name属性,生成<province>元素的属性
xstream.addImplicitCollection(Province.class, "cities");//去除Province类的名为cities的List类型的属性
/*
* 让City类的,名为description属性不生成对应的xml元素
*/
xstream.omitField(City.class, "description");
String s = xstream.toXML(proList);
System.out.println(s);
}
}