服务器返回给异步对象的数据载体:
1.HTML
2.XML
3.JSON
一)什么是JSON
(1)JSON(Java Script Object Notation(记号,标记))是一种轻量级的数据交换语言,以文本字符串为基础,且易于让人阅读。
注意:XML就是一个重量级的数据交换语言
(2)JSON采用完全独立于任何程序语言的文本格式,使JSON成为理想的数据交换语言
二)JSON的作用
(1)简化JS中创建自定义对象的方式
注意:JSON就是用JS语法来书写,所以必须放在<script>标签中
在用JS语法书写JSON时,最外面不要用""双引号
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"> <html> <head> <title>简化创建自定义对象的方式</title> <meta http-equiv="content-type" content="text/html; charset=UTF-8"> </head> <body> <!-- js方式定义Person对象 <script type="text/javascript"> function Person(id,name,sal){ this.id = id; this.name = name; this.sal = sal; } var p = new Person(1,"波波",7000); document.write("编号:" + p.id + "<br/>"); document.write("姓名:" + p.name + "<br/>"); document.write("薪水:" + p.sal + "<br/>"); </script> --> <hr/> <!-- json方式定义Person对象 --> <script type="text/javascript"> //采用js语言来书写 var p = {id:1,name:"包包",sal:8000};//id可写为"id",name亦可以加引号 //属性可以''或""符号 //字符串必加''或""符号,其它类型不用加符号 document.write("编号:" + p.id + "<br/>"); document.write("姓名:" + p.name + "<br/>"); document.write("薪水:" + p.sal + "<br/>"); </script> </body> </html>
var p = { id:1, name:"哈哈", tel:[ { no:"135", type:"中移动" }, { no:"133", type:"中联通" } ], show:function(username){ alert("你的姓名是:" + p.name+":"+username); }, isSingle:false }; var p = {'city':['北京','上海','广州','深圳']}; for(var i=0;i<p.city.length;i++){ document.write(p.city[i]+"<br/>"); }
<html> <head> <title>创建一个数组,数组中有三个对象</title> <meta http-equiv="content-type" content="text/html; charset=UTF-8"> </head> <body> <script type="text/javascript"> var ps = [ { id:1, name:'哈哈' }, { id:2, name:'呵呵' }, { id:3, name:'嘻嘻' } ]; </script> <script type="text/javascript"> document.write("共有" + ps.length + "个学生<br/>"); for(var i=0;i<ps.length;i++){ document.write("编号:" + ps[i].id + "<br/>"); document.write("姓名:" + ps[i].name + "<br/>"); } </script> </body> </html>
<html> <head> <title>创建一个对象,使用function做为属性值</title> <meta http-equiv="content-type" content="text/html; charset=UTF-8"> </head> <body> <script type="text/javascript"> var p = { id:1, name:'哈哈', isLove:true, home:['广州','深圳'], show : function(str){ alert("你是" + str); } }; //document.write(p.isLove?"已婚":"单身"+"<br/>"); p.show("赵君"); </script> </body> </html>
(2)在AJAX中,作为数据载体之一
注意:JS可以直接解析JSON格式的文本,前提是:该JSON必须采用JS格式书写的才行,如果该JSON是采用Java格式写的,必须使用eval()函数转换后,方可被JS解析,该eval("")函数接收一个字符串格式的内容。
(3)省份-城市-区域三级联动【Struts2 + JSON版】
切记:将来JSON是不能完完全全替代XML的,只能在定义对象和数据交换语言方面替代
JSP页面:
<%@ page language="java" pageEncoding="UTF-8"%> <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"> <html> <head> <title>省份-城市-区域三级联动【Struts2 + JSON版】</title> <script type="text/javascript" src="js/ajax.js"></script> </head> <body> <select id="provinceID" style="width:111px"> <option>选择省份</option> <option>湖北</option> <option>湖南</option> <option>广东</option> </select> <select id="cityID" style="width:111px"> <option>选择城市</option> </select> <select id="areaID" style="width:111px"> <option>选择区域</option> </select> <!-- 省份->城市 --> <script type="text/javascript"> document.getElementById("provinceID").onchange = function(){ //清空城市下拉框 var cityElement = document.getElementById("cityID"); cityElement.options.length = 1; //清空区域下拉框 var areaElement = document.getElementById("areaID"); areaElement.options.length = 1; var province = this[this.selectedIndex].innerHTML; if("选择省份" != province){ //NO1) var ajax = createAJAX(); //NO2) var method = "POST"; var url = "${pageContext.request.contextPath}/findCityByProvinceRequest?time="+new Date().getTime(); ajax.open(method,url); //NO3) ajax.setRequestHeader("content-type","application/x-www-form-urlencoded") //NO4) var content = "bean.province=" + province; ajax.send(content); //-------------------------------------------等待 //NO5 ajax.onreadystatechange = function(){ if(ajax.readyState == 4){ if(ajax.status == 200){ //NO6)返回JAVA格式的JSON文本 var jsonJAVA = ajax.responseText; //jsonJAVA所代表的是java格式的json文本,是不能直接被js执行的 //解决方案:将java格式的json文本,转成js格式的json文本 //如何做:用js提供的一个函数搞定 var jsonJS = eval("("+jsonJAVA+")"); 注意。在java中这里是固定写法,不能写为eval(jsonJAVA) var array = jsonJS.cityList; var size = array.length; for(var i=0;i<size;i++){ var city = array[i]; var option = document.createElement("option"); option.innerHTML = city; cityElement.appendChild(option); } } } } } } </script> <!-- 城市->区域 --> <script type="text/javascript"> document.getElementById("cityID").onchange = function(){ var areaElement = document.getElementById("areaID"); areaElement.options.length = 1; var city = this[this.selectedIndex].innerHTML; if("选择城市" != city){ //NO1) var ajax = createAJAX(); //NO2) var method = "POST"; var url = "${pageContext.request.contextPath}/findAreaByCityRequest?time="+new Date().getTime(); ajax.open(method,url); //NO3) ajax.setRequestHeader("content-type","application/x-www-form-urlencoded") //NO4) var content = "bean.city=" + city; ajax.send(content); //------------------------------------------等待 //NO5) ajax.onreadystatechange = function(){ if(ajax.readyState == 4){ if(ajax.status == 200){ //NO6) var jsonJAVA = ajax.responseText; var jsonJS = eval("("+jsonJAVA+")"); var array = jsonJS.areaList; var size = array.length; for(var i=0;i<size;i++){ var area = array[i]; var option = document.createElement("option"); option.innerHTML = area; areaElement.appendChild(option); } } } } } } </script> </body> </html>
/** * 封装省份和城市 * @author AdminTC */ public class Bean { private String province;//省份 private String city;//城市 public Bean(){} public String getProvince() { return province; } public void setProvince(String province) { this.province = province; } public String getCity() { return city; } public void setCity(String city) { this.city = city; } }
ProvinceCityAreaAction.java
package cn.itcast.javaee.js.provincecityarea; import java.util.ArrayList; import java.util.List; import com.opensymphony.xwork2.ActionSupport; /** * 省份-城市-区域三级联动【Struts2 + JSON版】 * @author AdminTC */ public class ProvinceCityAreaAction extends ActionSupport{ private Bean bean; public Bean getBean() { return bean; } public void setBean(Bean bean) { this.bean = bean; } /** * 根据省份获取城市 */ public String findCityByProvince() throws Exception { cityList = new ArrayList<String>();//注意:这里返回的json必须提供get,set方法,即必须为实例变量 if("湖北".equals(bean.getProvince())){ cityList.add("武汉"); cityList.add("赤壁"); }else if("湖南".equals(bean.getProvince())){ cityList.add("郴州"); cityList.add("张家界"); cityList.add("浏阳"); }else if("广东".equals(bean.getProvince())){ cityList.add("阳江"); cityList.add("清远"); cityList.add("佛山"); cityList.add("湛江"); } //让struts2框架帮你将List/Set/Map<String>转成JSON文本 使用struts2-json-plugin-2.3.1.1.jar 在项目中引入该jar包即可 return SUCCESS; } /** * 根据城市获取区域 */ public String findAreaByCity() throws Exception { areaList = new ArrayList<String>(); if("阳江".equals(bean.getCity())){ areaList.add("AA"); areaList.add("BB"); }else if("清远".equals(bean.getCity())){ areaList.add("CC"); areaList.add("DD");; }else if("佛山".equals(bean.getCity())){ areaList.add("EE"); areaList.add("FF"); }else if("湛江".equals(bean.getCity())){ areaList.add("GG"); areaList.add("HH"); } return SUCCESS; } private List<String> areaList;//区域的集合 必须写此实例变量,并提供get方法,struts2转成json的时候会调用get方法,所以要返回的json值必须这么写。 private List<String> cityList;//城市的集合 public List<String> getCityList() { return cityList; } public List<String> getAreaList() { return areaList; } }
struts.xml
<?xml version="1.0" encoding="UTF-8" ?> <!DOCTYPE struts PUBLIC "-//Apache Software Foundation//DTD Struts Configuration 2.0//EN" "http://struts.apache.org/dtds/struts-2.0.dtd"> <struts> <package name="myPackage" extends="json-default" namespace="/"> json-default继承Struts-default <!-- 全局结果类型 --> <global-results> <result name="success" type="json"/> </global-results>
<action name="checkRequest" class="cn.itcast.javaee.js.checkcode.CheckcodeAction" method="check"> </action> <!-- 省份->城市 --> <action name="findCityByProvinceRequest" class="cn.itcast.javaee.js.provincecityarea.ProvinceCityAreaAction" method="findCityByProvince">
<result name="success" type="json">
</action> <!-- 城市->区域 --> <action name="findAreaByCityRequest" class="cn.itcast.javaee.js.provincecityarea.ProvinceCityAreaAction" method="findAreaByCity"></action> </package> </struts>
三)使用第三方工具,将JavaBean对象/List或Set或Map对象转成JSON
上面在struts2中,使用了Struts2框架的功能,struts2-json-plugin-3.2.1.1.jar把list等对象转成json对象,但是如果在开发中使用的不是Struts2,而是其他技术呢,那如何把list等java对象转成JSON呢?
准备导入第三方jar包:
》commons-beanutils-1.7.0.jar
》commons-collections-3.1.jar
》commons-lang-2.5.jar
》commons-logging-1.1.1.jar
》ezmorph-1.0.3.jar
》json-lib-2.1-jdk15.jar
(1)JavaBean----->JSON
》JSONArray jsonArray = JSONArray.fromObject(city);
》String jsonJAVA = jsonArray.toString();
(2)List<JavaBean>----->JSON
》JSONArray jsonArray = JSONArray.fromObject(cityList);
》String jsonJAVA = jsonArray.toString();
(3)List<String>----->JSON
》JSONArray jsonArray = JSONArray.fromObject(stringList);
》String jsonJAVA = jsonArray.toString();
(4)Set<JavaBean>----->JSON
》JSONArray jsonArray = JSONArray.fromObject(citySet);
》String jsonJAVA = jsonArray.toString();
(5)Map<String,Object>----->JSON
》JSONArray jsonArray = JSONArray.fromObject(map);
》String jsonJAVA = jsonArray.toString();
最后一个例子切记,将来jQuery-EasyUI-DataGrid组件时我们还要用到
将来,在企业中,就算脱离struts2的环境,也能用第三方工具,将Java类型转成JSON文本
/** * 城市 * @author AdminTC */ public class City { private Integer id; private String name; public City(){} public City(Integer id, String name) { this.id = id; this.name = name; } public Integer getId() { return id; } public void setId(Integer id) { this.id = id; } public String getName() { return name; } public void setName(String name) { this.name = name; } }
/** * 省份 * @author AdminTC */ public class Province { private Integer id;//编号 private String name;//名字 private List<City> cityList = new ArrayList<City>(); public Province(){} public Province(Integer id, String name, List<City> cityList) { this.id = id; this.name = name; this.cityList = cityList; } public Integer getId() { return id; } public void setId(Integer id) { this.id = id; } public String getName() { return name; } public void setName(String name) { this.name = name; } public List<City> getCityList() { return cityList; } public void setCityList(List<City> cityList) { this.cityList = cityList; } }
package cn.itcast.javaee.js.bean2json; import java.util.ArrayList; import java.util.LinkedHashMap; import java.util.LinkedHashSet; import java.util.List; import java.util.Map; import java.util.Set; import net.sf.json.JSONArray; /** * 使用第三方工具,将JavaBean对象/List或Set或Map对象转成JSON * @author AdminTC */ public class TestBean2Json {
private static void javabean2json() { City city = new City(1,"广州"); JSONArray jSONArray = JSONArray.fromObject(city); String jsonJAVA = jSONArray.toString(); System.out.println(jsonJAVA); //[{"id":1,"name":"广州"}] } private static void list2json() { List<City> cityList = new ArrayList<City>(); cityList.add(new City(1,"广州")); cityList.add(new City(2,"珠海")); JSONArray jSONArray = JSONArray.fromObject(cityList); String jsonJAVA = jSONArray.toString(); System.out.println(jsonJAVA); //[{"id":1,"name":"广州"},{"id":2,"name":"珠海"}] } private static void set2json() { Set<City> citySet = new LinkedHashSet<City>(); citySet.add(new City(1,"广州")); citySet.add(new City(2,"珠海")); JSONArray jSONArray = JSONArray.fromObject(citySet); String jsonJAVA = jSONArray.toString(); System.out.println(jsonJAVA); //[{"id":1,"name":"广州"},{"id":2,"name":"珠海"}] } private static void javabeanlist2json() { List<City> cityList = new ArrayList<City>(); cityList.add(new City(1,"中山")); cityList.add(new City(2,"佛山")); Province province = new Province(1,"广东",cityList); JSONArray jSONArray = JSONArray.fromObject(province); String jsonJAVA = jSONArray.toString(); System.out.println(jsonJAVA); /* [ { "id":1, "name":"广东" "cityList":[{"id":1,"name":"中山"},{"id":2,"name":"佛山"}], } ] */ } private static void map2json() { List<City> cityList = new ArrayList<City>(); cityList.add(new City(1,"中山")); cityList.add(new City(2,"佛山")); Map<String,Object> map = new LinkedHashMap<String,Object>(); map.put("total",cityList.size());//表示集合的长度 map.put("rows",cityList);//rows表示集合 JSONArray jSONArray = JSONArray.fromObject(map); String jsonJAVA = jSONArray.toString(); System.out.println(jsonJAVA); //[{"total":2,"rows":[{"id":1,"name":"中山"},{"id":2,"name":"佛山"}]}] jsonJAVA = jsonJAVA.substring(1,jsonJAVA.length()-1); System.out.println(jsonJAVA); } public static void main(String[] args) { //javabean2json(); //list2json(); //set2json(); //javabeanlist2json(); map2json(); } }
四)总结JSON的特点
(1)在客户端(特指PC浏览器),直接使用JavaScript语言解析JSON,无需第三方jar包
(2)本质上,就是一个文本,只是该文本有特定的书写格式
(3)可以使用第三方工具,将JavaBean对象或者List/Set/Map<JavaBean>对象转成JSON
(4)优点:JSON与XML很相似,但是它更加轻巧,服务器只需发送一个html普通字符串,不用发送复杂的xml格式文档了
(5)缺点:语法过于严谨,初学者可能觉得代码不易读,写错一点都不行
(6)JSON本质上,就是用JS语法写的特殊文本记号,用JS可以直接解析