一、JSON定义
在百度百科中的解释:JSON(JavaScript Object Notation) 是一种轻量级的数据交换格式。它基于JavaScript的一个子集。 JSON采用完全独立于语言的文本格式,JSON简单说就是javascript中的对象和数组,所以这两种结构就是对象和数组两种结构,通过这两种结构可以表示各种复杂的结构。
1、对象:
对象在js中表示为“{}”括起来的内容,数据结构为 {key:value,key:value,...}的键值对的结构,在面向对象的语言中,key为对象的属性,value为对应的属性值,所以很容易理解,取值方法为 对象.key 获取属性值,这个属性值的类型可以是 数字、字符串、数组、对象几种。
2、数组:
数组在js中是中括号“[]”括起来的内容,数据结构为 ["java","javascript","vb",...],取值方式和所有语言中一样,使用索引获取,字段值的类型可以是 数字、字符串、数组、对象几种。简单地说,JSON 可以将 JavaScript 对象中表示的一组数据转换为字符串,然后就可以在函数之间轻松地传递这个字符串,或者在异步应用程序中将字符串从 Web 客户机传递给服务器端程序。这个字符串看起来有点儿古怪,但是JavaScript很容易解释它。
以前学过的jquery 遍历 Dictionary 风格的数组(其实就是一个javascript对象)
var stu={ "firstName": "Brett", "lastName":"McLaughlin", "email": "aaaa" }
$.each(stu,function(key,value){
alert(key+"---"+value);
}) var people =
{
"演员":
[
{ "firstName": "Brett", "lastName":"要被取值的", "email": "aaaa" },
{ "firstName": "Jason", "lastName":"Hunter", "email": "bbbb" },
{ "firstName": "Elliotte", "lastName":"Harold", "email": "cccc" }
], "作者": [
{ "firstName": "Isaac", "lastName": "Asimov", "genre": "science fiction" },
{ "firstName": "Tad", "lastName": "Williams", "genre": "fantasy" },
{ "firstName": "Frank", "lastName": "Peretti", "genre": "christian fiction" }
], "配乐": [
{ "firstName": "Eric", "lastName": "Clapton", "instrument": "guitar" },
{ "firstName": "Sergei", "lastName": "Rachmaninoff", "instrument": "piano" }
] } //这里有3 个key,每个key对应的value 又是一个数组,数组中的每个元素,又是一个对象(对象由键值对组成)
//alert(people.演员[0].lastName) ; 可以取出 "要被取值的" 这个数组
//例子 用JSON 传输数据 //客户端
$(function(){
$("button").click(function(){
$.ajax({
url:"JSONTestServlet",
type:"post",
data:{userName:$("#userName").val()},
dataType:"JSON", //千万不要忘了指定返回数据的格式
success:function(user){
$("#divresult").append("用户id:"+user.id +"<br />");
$("#divresult").append("用户名:"+user.userName +"<br />");
$("#divresult").append("用户密码:"+user.password +"<br />");
$("#divresult").append("用户备注:"+user.note +"<br />");
}
});
});
}); //服务端
public void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException { //这里,要把 user转JSON格式的字符串返回
String str=" {\"id\":\"1\",\"userName\":\"张三\",\"password\":\"admin\" ,\"note\":\"这是备注\"} ";
response.setContentType("text/html;charset=utf-8");
response.getWriter().print(str);
}
二、JSONlib 的使用(两步)
1) 导入 JSON lib的包
commons-beanutils-1.8.2.jar
commons-collections-3.2.1.jar
commons-lang-2.5.jar
commons-logging-1.1.1.jar
ezmorph-1.0.6.jar
JSON-lib-2.4-jdk15.jar
2) 使用
public void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
String userName=request.getParameter("userName");
UserInfo user= UserDao.getUserByName(userName);
//使用JSONlib提供的功能,将一个类对象转成JSON格式的字符串
JSONObject JSONObj=JSONObject.fromObject(user);
System.out.println(JSONObj); response.setContentType("text/html;charset=utf-8");
response.getWriter().print(JSONObj.toString());
}
}
//例子,如何使用 JSONlib 返回一组数组
//服务端
public void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
List<UserInfo> userList=UserDao.getAllUser(); //如果要转一个对象, 用JSONObject,转多个对象(List),用 JSONArray
JSONArray JSONObj= JSONArray.fromObject(userList); response.setContentType("text/html;charset=utf-8" );
response.getWriter().print(JSONObj);
} //客户端
$(function(){
$("button").click(function(){
$.ajax({
url:"JSONArrayTestServlet",
type:"post",
dataType:"JSON",
success:function(userList){ //取出数据的第一种方式
/* for(var i=0;i<userList.length;i++){
alert(userList[i].id);
var trStr="<tr><td>"+userList[i].id+"</td><td>"+userList[i].userName+
"</td><td>"+userList[i].password+"</td><td>"+userList[i].note+"</td></tr>";
$("#table1").append(trStr);
} */ //使用 $.each() 的方式
$.each(userList,function(key,user){
var trStr="<tr><td>"+user.id+"</td><td>"+user.userName+
"</td><td>"+user.password+"</td><td>"+user.note+"</td></tr>";
$("#table1").append(trStr);
});
}
});
});
});
//例子 将JSON字符串反序列化为 java对象
String JSONStr= "{\"id\":99,\"userName\":\"张三\",\"password\":\"admin\",\"note\":\"备注\",\"aihao\":\"球类\"}" ;
JSONObject JSONObj=JSONObject.fromObject(JSONStr); //注意,UserInfo 类,一定要有一个无参的构造函数
UserInfo user=(UserInfo)JSONObject.toBean(JSONObj,UserInfo.class);
三、Ajax联动菜单
//请求发起页面
$(function(){
$("#bigCate").change(function(){
//取出自己的被选中的option 的 value (它应该是小分类对应的parentId)
var parentId=this.value ; //根据这个parentId去数据库查询,
$.ajax({
url:"CateAjaxServlet",
cache:false,
data:{parentId:parentId},
dataType:"JSON",
success:function(cateList){
//把取务端返回的小分类的列表,拼到小分类对应的下拉框中,但要先清空一下
$("#smallCate").empty();
$.each(cateList,function(key,cateInfo){
var optionStr="<option value='"+cateInfo.id+"'>"+cateInfo.cateName+"</option>";
$("#smallCate").append(optionStr);
}); }
});
});
}); <body>
<%
List<CateInfo> bigCateList=new CateDao().getCateList(0);
request.setAttribute("bigCateList", bigCateList);
%>
<form action="xxx" method="post">
大分类:
<select id="bigCate" name="bigCate" >
<c:forEach var="cateInfo" items="${ bigCateList}" >
<option value="${cateInfo.id }">${cateInfo.cateName }</option>
</c:forEach>
</select> 小分类:
<select id="smallCate" name="smallCate" >
</select> 打酱油的:
<input type="text" />
</form>
</body> //服务端
public void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
//根据传上来的parentID 查询子分类
int parentId = Integer.parseInt(request.getParameter("parentId"));
List<CateInfo> cateList=new CateDao().getCateList(parentId);
JSONArray JSONObj=JSONArray.fromObject(cateList); response.setContentType("text/html;charset=utf-8" );
response.getWriter().print(JSONObj);
}
四、关于返回数据类型 为 JSONp 的情况
因为同源策略,Ajax 的请求是不许跨域访问的,如果试图访问其他服务器上的url 会出现如下错误
1.已阻止交叉源请求:同源策略不允许读取 http://10.10.10.15:8080/JSONPDemo/TestServlet 上的远程资源。
解决方法:可以将资源移动到相同的域名上或者启用 CORS 来解决这个问题。
2.已阻止跨源请求:同源策略禁止读取位于 http://169.254.246.250:8080/web1/WebAServlet 的远程资源。(原因:CORS 头缺少 'Access-Control-Allow-Origin')。
同源策略是指阻止代码获得或者更改从另一个域名下获得的文件或者信息。也就是说我们的请求地址必须和当前网站的地址相同。同源策略通过隔离来实现对资源的保护。这个策略的历史非常悠久从Netscape Navigator 2.0时代就开始了。
解决方法:解决这个限制的一个相对简单的办法就是在服务器端发送请求,服务器充当一个到达第三方资源的代理中继。虽然是用广泛但是这个方法却不够灵活。
另一个办法就是使用框架(frames),将第三方站点的资源包含进来,但是包含进来的资源同样要受到同源策略的限制。有一个很巧妙的办法就是在页面中使用动态代码元素,代码的源指向服务地址并在自己的代码中加载数据。当这些代码加载执行的时候,同源策略就不会起到限制。但是如果代码试图下载文件的时候执行还是会失败,幸运的是,我们可以使用JSON(JavaScript Object Notation)来改进这个应用。
//JSONp的使用
<script type="text/javascript">
$(function(){
$("button").click(function(){
$.ajax({
url:"http://169.254.246.250:8080/web1/WebAServlet",
dataType:"JSONp", //这里使用 JSONp这个格式
JSONp:"JSONpcallback", //这个名字是给别人用的
success:function(data){
$("#div1").append(data.id+"<br />");
$("#div1").append(data.userName+"<br />");
$("#div1").append(data.password+"<br />");
$("#div1").append(data.note+"<br />");
}
});
});
});
</script> //被访问者的服务端
public void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException { String JSONp=request.getParameter("JSONpcallback");
String JSONStr= "{\"id\":99,\"userName\":\"张三\",\"password\":\"admin\",\"note\":\"备注\",\"aihao\":\"球类\"}" ;
response.setContentType("text/html;charset=utf-8");
response.getWriter().print( JSONp+"("+ JSONStr +")" );
}