您的位置:首页 > 编程语言 > Java开发

struts2(十)之JSON基础

2016-05-09 15:31 495 查看
JSON简介

JSON(JavaScript Object Notation),JavaScript对象符号,是一种轻量级的数据交换格式。它是基于ECMAScript的一个子集。 JSON采用完全独立于语言的文本格式,但是也使用了类似于C语言家族的习惯(包括C、C++、C#、Java、JavaScript、Perl、Python等)。这些特性使JSON成为理想的数据交换语言。 易于人阅读和编写,同时也易于机器解析和生成(一般用于提升网络传输速率)。

JSON主要基于以下两种数据结构:

>由key-value对组成的数据结构。 在各种语言中有不同的实现,如:在JavaScript中是一个对象,在Java中是一种Map结构,在C语言中是一个struct。在其他语言中,可能是record、dictionary、hash table。

>有序集合。 在不同语言中,可能是list、vector、数组或者序列等实现。

这些是通用的数据结构。 几乎所有的现代编程语言都有相应的实现。所以JSON可以作为程序设计语言中通用的数据交换格式。在JavaScript中主要有两种JSON的语法,一种用于创建对象,一种用于创建数组。

基础结构

json可以简单地理解为javascript中的对象和数组,通过这两种结构可以表示各种复杂的结构。

1、对象:对象在js中表示为“{}”括起来的内容,数据结构为 {key:value,key:value,…}的键值对的结构,在面向对象的语言中,key为对象的属性,value为对应的属性值,所以很容易理解,取值方法为 对象.key获取属性值,这个属性值的类型可以是数字、字符串、数组、对象几种。

2、数组:数组在js中是中括号“[]”括起来的内容,数据结构为 [“java”,”javascript”,”vb”,…],取值方式和所有语言中一样,使用索引获取,字段值的类型可以是 数字、字符串、数组、对象几种。

经过对象、数组2种结构就可以组合成复杂的数据结构了。

简单地说 ,JSON 可以将 JavaScript 对象中表示的一组数据转换为字符串,然后就可以在函数之间轻松地传递这个字符串,或者在异步应用程序中将字符串从 Web 客户机传递给服务器端程序。JavaScript可以很容易解释这个字符串,而且 JSON 可以表示比”名称 / 值对”更复杂的结构。例如,可以表示数组和复杂的对象,而不仅仅是键和值的简单列表。

使用JSON语法创建对象

使用JSON语法创建对象不用写函数,不用new关键字,可以直接获取一个JavaScript对象。下面是这种语法的示意图。



创建对象object时,总以{开始,以}结束,对象每个属性名和属性值之间以英文冒号(:)隔开,多个属性定义之间以英文逗号(,)隔开,语法格式如下:

object =
{
propertyName1 : propertyValue1,
propertyName2 : propertyValue2,
...
}


要注意的是,并不是每个属性定义后面都有一个英文逗号(,),必须后面还有属性定义时才需要逗号(,),最后一个属性后面是不加逗号(,)的。

用JSON语法创建JavaScript对象时,属性值不仅可以是普通字符串,也可以是任何基本数据类型,或者是函数、数组,甚至是另外一个JSON语法创建对象。

person =
{
name : 'Jujiu',
sex : 'male',
//使用JSON语法为期指定一个属性
son : {
name : 'yoyo',
grade : 1
},
//使用JSON语法为person值分配一个方法
info : function{
document.writeln("姓名:" + this.name + "性别:" + this.sex);
}
}


使用JSON语法创建数组

使用JSON语法创建数组的语法示意图。



如图所示,JSON创建数组总是以英文括号([)开始,然后依次放入数组元素,元素与元素之间以逗号(,)隔开,最后一个数组元素后面不加英文逗号,但以英文反方括号(])结束。使用JSON创建数组的语法格式如下:

arr = [value1, value2 ...]


与JSON创建对象相似的是,数组的最后一个元素后面不能有逗号(,)。

由于JSON语法的简单易用,且作为数据传输载体时,数据传输量更小,所以在Ajax交互中,往往不使用XML作为数据交换格式,而是采用JSON作为数据交换格式。假设需要交换一个对象personn,其name属性为Jujiu,gender属性为29,使用JSON语法可以简单地写成:

person =
{
name : 'Jujiu',
gender : 'male',
age : 29
}


用XML数据交换格式,则要写成:

<person>
<name>Jujiu</name>
<gender>male</gender>
<age>29</age>
</person>


可见,使用JSON语法要简单一些。

当服务器返回一个满足JSON格式的字符串后,接下来可以利用json扩展的方法将该字符串转换成一个JavaScript对象。登录http:www.json.org/json2.js站点,下载jsonn2.js文件,该文件提供了一个全局的JSON对象,该对象包含两个方法:stringify和parse,其中前者负责把一个JSON对象转换成JSON格式的字符串,后者负责把JSON格式字符串转换成JSON对象。

实现Action逻辑

先来看一段代码。

package com.afy.app.action;

import java.util.HashMap;
import java.util.Map;

import com.opensymphony.xwork2.Action;
import org.apache.struts2.json.annotations.JSON;

public class JSONExample{
// 模拟处理结果的成员变量
private int[] ints = {10, 20};
private Map<String , String> map
= new HashMap<String , String>();
private String customName = "顾客";
// 封装请求参数的三个成员变量
private String field1;
// 'transient'修饰的成员变量不会被序列化
private transient String field2;
// 没有setter和getter方法的成员变量不会被序列化
private String field3;

public String execute(){
map.put("name", "疯狂Java讲义");
return Action.SUCCESS;
}

// 使用注解来改变该成员变量序列化后的名字
@JSON(name="newName")
public Map getMap(){
return this.map;
}

// customName的setter和getter方法
public void setCustomName(String customName){
this.customName = customName;
}
public String getCustomName(){
return this.customName;
}

// field1的setter和getter方法
public void setField1(String field1){
this.field1 = field1;
}
public String getField1(){
return this.field1;
}

// field2的setter和getter方法
public void setField2(String field2){
this.field2 = field2;
}
public String getField2(){
return this.field2;
}

// field3的setter和getter方法
public void setField3(String field3){
this.field3 = field3;
}
public String getField3(){
return this.field3;
}
}


这里是处理一个页面请求的Action类代码,该页面中包含三个表单域,这三个表单域对应于三个请求参数,因此应该使用Action来封装三个请求参数。三个表单域的name分别是field1、field2、field3。

上面代码中,使用了@JSON注解,使用该注解时指定了name属性,name属性用于改变JSON对象的属性名字。另外,@JSON还支持如下几个属性。

>serialize : 设置是否序列号该属性。

> deserialize: 设置是否反序列化该属性。

>format: 设置用于格式化输出、解析日期表单域的格式。如“yyyy-MM-dd’T’HH:mm:ss”。

JSON插件与json类型的Result

JSON插件提供了一种json类型的Result,一旦为某个Action指定一个类型为json的Result,则该该Result不用映射到任何视图资源。因为JSON插件会负责将Action里的状态信息序列化成JSON格式的字符串,并将该字符串返回给客户端浏览器。

JSON插件允许在客户端页面的JavaScript中异步调用Action,而且Action不再需要使用视图资源来显示该Action里的状态,而是由JSON插件将Action里的状态信息返回给调用页面,通过这种方式,就可以完成Ajax交互。

将struts2解压缩目录的lib子目录下的struts2-json-plugin-2.3.16.3.jar文件复制到Web应用的WEB-INF\lib目录下,就可以为该struts2应用增加JSON插件了。

接下来配置提供返回JSON字符串的Action,要为Action配置类型为json的Result,而这个Result无需配置任何视图资源。配置Action的struts.xml文件如下。

<?xml version="1.0" encoding="GBK"?>
<!DOCTYPE struts PUBLIC
"-//Apache Software Foundation//DTD Struts Configuration 2.3//EN"
"http://struts.apache.org/dtds/struts-2.3.dtd">
<struts>
<constant name="struts.i18n.encoding" value="UTF-8"/>
<package name="example" extends="json-default">
<action name="JSONExample" class="org.crazyit.app.action.JSONExample">
<!-- 配置类型的json的Result -->
<result type="json">
<!-- 为该Result指定参数 -->
<param name="noCache">true</param>
<param name="contentType">text/html</param>
<!-- 设置只序列Action的map属性 -->
<!--  param name="root">map</param -->
</result>
</action>
<action name="*">
<result>/WEB-INF/content/{1}.jsp</result>
</action>
</package>
</struts>


要注意的两个地方是:

①. 配置struts.i18n.encoding常量时,不使用GBK编码,而用UTF-8,因为Ajax的POST请求都是以UTF-8的方式进行编码的。

②. 自己的包要继承json-default包,而不再继承默认的default包,因为只有这个包下才有json类型的Result。

将视图名配置为json类型的Result时无需指定任何视图资源,JSON插件会将该Action序列化后发送给客户端。

实现JSP页面

为了方便地实现Ajax交互,本页面将使用jQuery,通过使用该框架,可以简单地访问页面中的DOM节点,包括更好地实现Ajax交互,这样避免了创建XMLHttpRequest对象、发送异步请求这些繁琐步骤。下面看JSP页面代码。

<%@ page contentType="text/html; charset=GBK" language="java" errorPage="" %>
<%@ taglib prefix="s" uri="/struts-tags" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title>使用JSON插件</title>
<script src="${pageContext.request.contextPath}/jquery-1.11.1.js"
type="text/javascript">
</script>
<script type="text/javascript">
function gotClick(){
$("#show").hide();
// 指定向JSONExample发送请求,将id为form1的表单所包含的表单控件转换为请求参数
$.post("JSONExample" , $("#form1").serializeArray() ,
// 指定回调函数
function(data , statusText){
$("#show").height(80)
.width(240)
.css("border" , "1px solid black")
.css("border-radius" , "15px")
.css("background-color" , "#efef99")
.css("color" , "#ff0000")
.css("padding" , "20px")
.empty();
// 遍历JavaScript对象的各属性
for(var propName in data){
$("#show").append(propName + "-->"
+ data[propName] + "<br />");
}
$("#show").show(600);
},
// 指定服务器响应为JSON数据
"json");
}
</script>
</head>
<body>
<s:form id="form1">
<s:textfield name="field1" label="Field 1"/>
<s:textfield name="field2" label="Field 2"/>
<s:textfield name="field3" label="Field 3"/>
<tr><td colspan="2">
<input type="button" value="提交" onclick="gotClick();"/>
</td></tr>
</s:form>
<div id="show">
</div>
</body>
</html>


为了使用jQuery库,要导入jQuery的代码库到该页面。页面可以取得整个Action实例的状态信息,包括Action实例里每个属性名,以及对应的属性值,这样就能完全获得struts2对该请求的处理结果,剩下的就是,通过DOM操作把这些处理结果显示出来。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: