使⽤JSON进⾏数据传输的总结
⼀、选择的意义
在异步应⽤程序中发送和接收信息时,可以选择以纯⽂本和 XML 作为数据格式。为了更好的使⽤ajax, 我们将学习⼀种有⽤的数据格式JavaScript Object Notation (JSON ),以及如何使⽤它更轻松地在应⽤程序中移动数据和对象。JSON 是⼀种简单的数据交换格式,在某些⽅⾯,它的作⽤与XML ⾮常类似,但⽐XML 更为简单,JSON 的语法简化了数据交换的难度,⽽且提供了⼀种伪对象的⽅式。
Java 的对象 < - >JavaScript 对象(json 数据格式)
⼆、JSON 基础
简单地说,JSON 可以将 JavaScript 对象中表⽰的⼀组数据转换为字符串(伪对象),然后就可以在函数之间轻松地传递这个字符串,或者在异步应⽤程序中将字符串从 Web 客户端传递给服务器端程序。这个字符串看起来有点⼉古怪(稍后会看到⼏个⽰例),但是 JavaScript 很容易解释它,⽽且 JSON 可以表⽰⽐名称/ 值对更复杂的结构。例如,可以表⽰数组和复杂的对象,⽽不仅仅是键和值的简单列表。
关于JSON 对象
1 、使⽤JavaScript 语法创建对象
// 定义⼀个函数,作为构造函数
fucntion person(name,sex)
{
this.name=name;
this.sex=sex;
}
// 创建⼀个实例
var p=new Person(‘ 张三’,’ 男’);
// 输出Person 实例
alert(p.name);
注意:通过该⽅式创建的对象是⼀般的脚本对象
2 、从JavaScript1.2 开始创建对象有了⼀种更快捷的语法(Json 的语法) ,如下:
var obj= { name: " 张三 " , "sex" : ' 男 ' } ;
alert(obj.sex);
关于数组
1 、早期的JavaScript 数组
var arr=new Array();
arr[0]=’a’;
arr[1]=’bbc’
我们也可以通过如下⽅式创建数组
var arr=new Array(‘a’,’bbc’);
2 、使⽤JSON 语法,则可以通过如下⽅式创建数组
var arr=[‘a’,’bbc’];
简单 JSON ⽰例
按照最简单的形式,可以⽤下⾯这样的 JSON 表⽰名称/ 值对:
{ "firstName":"Brett" }
这个⽰例⾮常基本,⽽且实际上⽐等效的纯⽂本名称/ 值对占⽤更多的空间:
firstName=Brett
但是,当将多个名称/ 值对串在⼀起时,JSON 就会体现出它的价值了。⾸先,可以创建包含多个名称/ 值对的记录,⽐如:
{"firstName": "Brett", "lastName":"McLaughlin", "email": "brett@newInstance"}
从语法⽅⾯来看,这与名称/ 值对相⽐并没有很⼤的优势,但是在这种情况下 JSON 更容易使⽤,⽽且可读性更好。例如,它明确地表⽰以上三个值都是同⼀记录的⼀部分;花括号使这些值有了某种联系。
值的数组
当需要表⽰⼀组值时,JSON 不但能够提⾼可读性,⽽且可以减少复杂性。例如,假设您希望表⽰⼀个⼈名列表。在 XML 中,需要许多开始标记和结束标记;如果使⽤典型的名称/值对(就像在本系列前⾯⽂章中看到的那种名称/ 值对),那么必须建⽴⼀种专有的数据格式,或者将键名称修改为person1-firstName 这样的形式。
如果使⽤ JSON ,就只需将多个带花括号的记录分组在⼀起:
{ "people": [
{ "firstName": "Brett", "lastName":"McLaughlin", "email": "brett@newInstance" },
{ "firstName": "Jason", "lastName":"Hunter", "email": "jason@servlets" },
{ "firstName": "Elliotte", "lastName":"Harold", "email": "elharo@macfaq" }
]}
这不难理解。在这个⽰例中,只有⼀个名为people 的变量,值是包含三个条⽬的数组,每个条⽬是⼀个⼈的记录,其中包含名、姓和电⼦邮件地址。上⾯的⽰例演⽰如何⽤括号将记录组合成⼀个值。当然,可以使⽤相同的语法表⽰多个值(每个值包含多个记录):
{ "programmers": [
{ "firstName": "Brett", "lastName":"McLaughlin", "email": "brett@newInstance" },
{ "firstName": "Jason", "lastName":"Hunter", "email": "jason@servlets" },
{ "firstName": "Elliotte", "lastName":"Harold", "email": "elharo@macfaq" }
],
"authors": [
{ "firstName": "Isaac", "lastName": "Asimov", "genre": "science fiction" },
{ "firstName": "Tad", "lastName": "Williams", "genre": "fantasy" },
{ "firstName": "Frank", "lastName": "Peretti", "genre": "christian fiction" }
],
"musicians": [
{ "firstName": "Eric", "lastName": "Clapton", "instrument": "guitar" },
{ "firstName": "Sergei", "lastName": "Rachmaninoff", "instrument": "piano" }
]
}
这⾥最值得注意的是,能够表⽰多个值,每个值进⽽包含多个值。但是还应该注意,在不同的主条⽬(programmers 、authors 和 musicians )之间,记录中实际的名称/ 值对可以不⼀样。JSON 是完全动态的,允许在 JSON 结构的中间改变表⽰数据的⽅式。甚⾄可以声明如下的Json 对象
var obj2= { people: { name: ' 张三 ' ,sex: " 男 " }}
alert(obj2.people.name);
在处理 JSON 格式的数据时,没有需要遵守的预定义的约束。所以,在同样的数据结构中,可以改变表⽰数据的⽅式,甚⾄可以以不同⽅式表⽰同⼀事物。
{deptid: ' 1 ' ,deptname: ' 开发部' ,deptnum: ' 2 ' ,deptdesc: ' 开发相关',
emps:[{empid:1,empname:' 张三 ',sex:’ 男 ’,age:’20’},{empid:2,empname:' 张三 ',sex:’ 男 ’,age:’20’} , {empid:3,empname:' 张三 ',sex:’ 男 ’,age:’20’}] }
三、在JavaScript 中使⽤JSON
掌握了 JSON 格式之后,在 JavaScript 中使⽤它就很简单了。JSON 是 JavaScript 原⽣格式,这意味着在 JavaScript 中处理 JSON 数据不需要任何特殊的 API 或⼯具包。
将JSON 数据赋值给变量
例如,可以创建⼀个新的 JavaScript 变量,然后将 JSON 格式的数据字符串直接赋值给它:
var people =
{ "programmers": [
{ "firstName": "Brett", "lastName":"McLaughlin", "email": "brett@newInstance" },
{ "firstName": "Jason", "lastName":"Hunter", "email": "jason@servlets" },
{ "firstName": "Elliotte", "lastName":"Harold", "email": "elharo@macfaq" }
],
"authors": [
{ "firstName": "Isaac", "lastName": "Asimov", "genre": "science fiction" },
{ "firstName": "Tad", "lastName": "Williams", "genre": "fantasy" },
{ "firstName": "Frank", "lastName": "Peretti", "genre": "christian fiction" }
],
"musicians": [
{ "firstName": "Eric", "lastName": "Clapton", "instrument": "guitar" },
{ "firstName": "Sergei", "lastName": "Rachmaninoff", "instrument": "piano" }
]
}
这⾮常简单;现在people 包含前⾯看到的 JSON 格式的数据。但是,这还不够,因为访问数据的⽅式似乎还不明显。
访问数据
尽管看起来不明显,但是上⾯的长字符串实际上只是⼀个数组;将这个数组放进 JavaScript 变量之后,就可以很轻松地访问它。实际上,只需⽤点号表⽰法来表⽰数组元素。所以,要想访问 programmers 列表的第⼀个条⽬的姓⽒,只需在 JavaScript 中使⽤下⾯这样的代码:
people.programmers[0].lastName;
注意,数组索引是从零开始的。所以,这⾏代码⾸先访问people 变量中的数据;然后移动到称为programmers 的条⽬,再移动到第⼀个记录([0] );最后,访问lastName 键的值。结果是字符串值 “McLaughlin” 。
下⾯是使⽤同⼀变量的⼏个⽰例。
people.authors[1].genre
// Value is "fantasy"
people.musicians[3].lastName
// Undefined. This refers to the fourth entry,and there isn't one
people.programmers[2].firstName
// Value is "Elliotte"
利⽤这样的语法,可以处理任何 JSON 格式的数据,⽽不需要使⽤任何额外的 JavaScript ⼯具包或 API 。
修改 JSON 数据
正如可以⽤点号和括号访问数据,也可以按照同样的⽅式轻松地修改数据:
people.musicians[1].lastName = "Rachmaninov";
在将字符串转换为 JavaScript json 格式对象之后,就可以像这样修改变量中的数据。
注意:json 格式的对象和json ⽂本是不同的
var obj={name:" 张三 ","sex":' 男 '}; //json 格式的对象
var str=" { name: " 张三 " , "sex" : ' 男 ' }" ; //json 格式的字符串( json 格式的⽂本)
转换回字符串
当然,如果不能轻松地将对象转换回本⽂提到的⽂本格式,那么所有数据修改都没有太⼤的价值。在 JavaScript 中这种转换也很简单:
var newJSONtext = JSONString();
这样就⾏了!现在就获得了⼀个可以在任何地⽅使⽤的⽂本字符串,例如,可以将它⽤作 Ajax 应⽤程序中的请求字符串。
更重要的是,可以将任何 JavaScript 对象转换为 JSON ⽂本。并⾮只能处理原来⽤ JSON 字符串赋值的变量。为了对名为myObject 的对象进⾏转换,只需执⾏相同形式的命令:
<script type="text/javascript">
function Car(make,model,year,color)
{
this.make=make;
}
function showCar()
{
var carr = new Car("Dodge","Coronet R/T",1968,"yellow");
JSONString());
}
</script>
这就是 JSON 与其他数据格式之间最⼤的差异。如果使⽤ JSON ,只需调⽤⼀个简单的函数,就可以获得经过格式化的数据,可以直接使⽤了。对于其他数据格式,需要在原始数据和格式化数据之间进⾏转换。即使使⽤ Document Object Model 这样的 API (提供了将⾃⼰的数据结构转换为⽂本的函数),也需要学习这个 API 并使⽤ API 的对象,⽽不是使⽤原⽣的 JavaScript 对象和语法。
最终结论是,如果要处理⼤量 JavaScript 对象,那么 JSON ⼏乎肯定是⼀个好选择,这样就可以轻松地将数据转换为可以在请求中发送给服务器端程序的格式(Ajax) 。
四、Struts 2 中使⽤Json ajax ⽀持
JSON 插件提供了⼀种名为json 的ResultType ,⼀旦为某个Action 指定了⼀个类型为json 的Result ,则该Result ⽆需映射到任何视图资源。因为JSON 插件会负责将Action ⾥的状态信息序列化成JSON 格式的数据,并将该数据返回给客户端页⾯的 JavaScript 。
简单地说,JSON 插件允许我们在JavaScript 中异步调⽤Action ,⽽且Action 不再需要使⽤视图资源来显⽰该Action ⾥的状态信息,⽽是由JSON 插件负责将Action ⾥的状态信息返回给调⽤页⾯——通过这种⽅式,就可以完成Ajax 交互。
Struts2 提供了⼀种可插拔⽅式来管理插件,安装Struts2 的JSON 插件与安装普通插件并没有太⼤的区别,⼀样只需要将Struts2 插件
的JAR ⽂件复制到Web 应⽤的WEB-INF/lib 路径下即可。
安装JSON 插件按如下步骤进⾏:
(1 )登陆le/p/jsonplugin/downloads/list 站点,下载Struts2 的JSON 插件的最新版本,当前最新版本是0.7 ,我们可以下载该版本的JSON 插件。
(2 )将下载到的jsonplugin-0.7.jar ⽂件复制到Web 应⽤的WEB-INF 路径下,即可完成JSON 插件的安装。
实现Action 逻辑
假设deptnew.html 输⼊页⾯中包含了四个表单域,这四个表单域对于四个请求参数,因此应该使⽤Action 来的dept 对象封装这四个请求参数。四个表单域的name 分别为dept.deptid 、dept.deptname 、dept.deptnum 和dept.deptdesc 。
处理该请求的Action 类代码如下:
package org.wllt.ajax.actions;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;
import org.wllt.ajax.beans.Dept;
lecode.jsonplugin.annotations.JSON;
import com.opensymphony.xwork2.Action;
public class JSONExample
{
// 封装请求参数的三个属性
private String field1;
private transient String field2;
private String field3;
/
/ 封装处理结果的属性
private int[] ints ={10, 20};
private Map map = new HashMap();
private String customName = "custom";
// ⽇期格式的属性
private Date date;
private Dept dept;
// 三个请求参数对应的 setter 和 getter ⽅法
@JSON(serialize=false)
public String getField1(){
return field1;
发送ajax请求的步骤
}
public void setField1(String field1)
{
this.field1 = field1;
}
// 封装处理结果的属性的 setter 和 getter ⽅法
public int[] getInts()
{
return ints;
}
public void setInts(int[] ints)
{
this.ints = ints;
}
@JSON(format="yyyy-MM-dd")
public Map getMap()
{
return map;
}
public void setMap(Map map)
{
this.map = map;
}
public String getField2() {
return field2;
}
public void setField2(String field2) {
this.field2 = field2;
}
public String getField3() {
return field3;
}
public void setField3(String field3) {
this.field3 = field3;
}
public Dept getDept() {
return dept;
}
public void setDept(Dept dept) {
this.dept = dept;
}
// 使⽤注释语法来改变该属性序列化后的属性名
@JSON(name="newName")
public String getCustomName()
{
return this.customName;
}
@JSON(format="yyyy-MM-dd")
public Date getDate() {
return date;
}
public void setDate(Date date) {
this.date = date;
}
public String execute()
{
map.put("name", "yeeku");
map.put("curdate",new Date());
return Action.SUCCESS;
}
}
在上⾯代码中,使⽤了JSON 注释,注释时指定了name 域,name 域指定Action 属性被序列化成JSON 对象的属性名。除此之
外,JSON 注释还⽀持如下⼏个域:
Name : Action 属性被序列化成JSON 对象的属性名
serialize :设置是否序列化该属性( 默认的action 的所有属性都会序列化成json ⽂本响应到原页⾯,也可以根据需要设定某些属性不序列化 ) 。也可以通过在配置json 类型的结果的时候定义需要不序列化的
属性:
<result name="success" type="json">
<param name="excludeProperties">service,joindate,dept</param>
</result>
deserialize :设置是否反序列化该属性。
format :设置⽤于格式化输出、解析⽇期表单域的格式。例如"yyyy-MM-dd'T'HH:mm:ss" 。
⼀般需要注释到需要转换⽇期格式属性的get ⽅法上⾯
配置该Action 与配置普通Action 存在⼩⼩的区别,为该Action 配置结果类型为json 的Result 。⽽这个Result ⽆需配置任何视图资源, 只需要把通过该结果把json ⽂本响应到原页⾯。
配置该Action 的l ⽂件代码如下:
<? xml version = "1.0" encoding = "UTF-8" ?>
<! DOCTYPE struts PUBLIC
"-//Apache Software Foundation//DTD Struts Configuration 2.0//EN"
"/dtds/struts-2.0.dtd" >
< struts >
< constant name = "struts.locale" value = "zh_CN" />
< constant name = "sion" value = "do,action" />
< package name = "json" extends = "json-default" >
< action name = "dept" class = "org.wllt.ajax.actions.DeptAction" >
< result type = "json" />
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。
发表评论