JSON
作为JSON处理(JSON-P)的Java API,JSR-353已经到达了最终的批准投票阶段。JSON-P(类似于JAXP)由一个流API(类似于StAX)和一个对象模型API(类似于DOM)组成。它的参考实现是jsonp,目前正处在测试阶段,它基于CDDL v1.1 和 GPL v2 协议开放源码。JSON-P将作为即将发布的Java EE 7的一部分,同时JAX-RS会使用它作为默认的JSON实现。请注意,该API并没有包含JSON数据绑定(类似于JAXB),同时它和更流行的JSONP(JSON with padding)并没有关系。
JSON(JavaScript对象标记)是一个轻量级数据交换格式,被广泛用于Web应用程序、REST服务和NoSQL数据库。随着JSON的流行以及Java平台上诸多JSON类库(org.json、Jackson及google-gson等)的出现,现在已经到了需要对开发者创建并使用JSON的方式进行标准化的阶段。JSON-P就是即将到来的标准,它能够被独立地使用,或者作为Java EE 7容器的一部分。
JSON-P分为两个API,流API(javax.json.stream)和对象模型API(javax.json)。流API是一种底层且高效的解析和生成JSON的方式。它由两个主要的抽象构成——JsonParser和JsonGenerator。JsonParser是一个拉模式解析器,允许以向前、只读的方式访问JSON输入源。JsonGenerator则提供了向流中写入JSON的方法,并且允许使用方法链。Generator输出JSON对象中的名/值对以及JSON数组中的值。
下面是JsonParser和JsonGenerator的代码示例。首先是我们将会读取或者创建的JSON数据。
[
{ "type" : "home", "number" : "(800)111-1111" },
{ "type" : "cell","number" : "(800) 222-2222" }
]
下面是JsonParser示例,示例的底部是它的输出。
JsonParserFactory factory =Json.createParserFactory(null);
JsonParser parser = factory.createParser(newStringReader(json));
while (parser.hasNext()) {
Eventevent = parser.next();
switch (event) {
case KEY_NAME: {
System.out.print(parser.getString() + "="); break;
}
case VALUE_STRING: {
System.out.println(parser.getString()); break;
}
}
}
type=home
number=(800) 111-1111
type=cell
number=(800) 222-2222
下面是JsonGenerator的示例,它向System.out中打印JSON。
JsonGeneratorFactory factory =Json.createGeneratorFactory(null);
JsonGenerator generator =factory.createGenerator(System.out);
generator.writeStartArray().
writeStartObject().
write("type", "home").
write("number", "(800) 111-1111").writeEnd().
writeStartObject().
write("type","cell").
write("number", "(800) 222-2222").writeEnd().
writeEnd().close();
第二部分是对象模型API,一个简单易用的高层API,它基于流API实现。它创建了一个类似于树的结构代表内存中的JSON数据,能够非常容易地进行操纵和查询。对象模型API中最主要的抽象是JsonObject和JsonArray,这两部分都是不可变的。JsonObject提供了一个Map视图,用于访问模型中未被排序的名/值对集合。JsonArray提供了一个列表视图访问排序的值序列。为了创建这些对象模型,你可以使用构建者模式(JsonObjectBuilder和JsonArrayBuilder)或者使用JsonReader从一个输入源(InputStream或者Reader)中读取它们。然后你可以使用JsonWriter将这些对象模型写入一个输出源(OutputStream或者Writer)。
下面是使用JsonArrayBuilder创建JsonArray的示例。需要再次提醒的是,我们使用的依然是上面的JSON数据。
JsonBuilderFactory factory =Json.createBuilderFactory(null);
JsonArray jsonArray =factory.createArrayBuilder()
.add(factory.createObjectBuilder().
add("type", "home").
add("number", "(800) 111-1111"))
.add(factory.createObjectBuilder().
add("type", "cell").
add("number", "(800) 222-2222")).build();
下面是JSONReader示例。
try (JsonReader jsonReader =Json.createReader(new StringReader(json))) {
JsonArray array = jsonReader.readArray();
System.out.println(array);
}
下面是JsonWriter示例。
try (JsonWriter jsonWriter =Json.createWriter(System.out)) {
jsonWriter.writeArray(jsonArray);
}
如果你想尝试这个测试版本,那么可以下载jsonp,或者使用javax.json:javax.json-api:1.0-b06 和org.glassfish:javax.json:1.0-b06Maven 产品。你需要使用Java SE 6或者更高版本。如果想要获取更多信息,可以访问官方网站提供的JSON处理的Java API ,或者阅读JSON处理的Javadocs。你还可以通过YouTube观看JavaOne提供的JSON处理的Java API呈现。
使用JSON的方法
JSON 即 JavaScript Object Natation,它是一种轻量级的数据交换格式,非常适合于服务器与 JavaScript 的交互。本文将快速讲解 JSON 格式,并通过代码示例演示如何分别在客户端和服务器端进行 JSON 格式数据的处理。
Json必需的包
commons-httpclient-3.1.jar
commons-lang-2.4.jar
commons-logging-1.1.1.jar
json-lib-2.2.3-jdk13.jar
ezmorph-1.0.6.jar
commons-collections-3.2.1.jar
出现java.lang.NoClassDefFoundError: net/sf/ezmorph/Morpher错误是因为没有导入ezmorph.jar文件或版本不对。
出现java.lang.NoClassDefFoundError:org/apache/commons/collections/map/ListOrderedMap错误是因为没有导入commons-collections.jar文件或版本不对。
Java代码转换成json代码
1. List集合转换成json代码
List list = new ArrayList(); list.add( "first" ); list.add( "second" ); JSONArray jsonArray2 = JSONArray.fromObject( list ); |
2. Map集合转换成json代码
Map map = new HashMap(); map.put("name", "json"); map.put("bool", Boolean.TRUE); map.put("int", new Integer(1)); map.put("arr", new String[] { "a", "b" }); map.put("func", "function(i){ return this.arr[i]; }"); JSONObject json = JSONObject.fromObject(map); |
3. Bean转换成json代码
JSONObject jsonObject = JSONObject.fromObject(new JsonBean()); |
4. 数组转换成json代码
boolean[] boolArray = new boolean[] { true, false, true }; JSONArray jsonArray1 = JSONArray.fromObject(boolArray); |
5. 一般数据转换成json代码
JSONArray jsonArray3 = JSONArray.fromObject("['json','is','easy']" ); |
6. beans转换成json代码
List list = new ArrayList(); JsonBean2 jb1 = new JsonBean2(); jb1.setCol(1); jb1.setRow(1); jb1.setValue("xx"); JsonBean2 jb2 = new JsonBean2(); jb2.setCol(2); jb2.setRow(2); jb2.setValue(""); list.add(jb1); list.add(jb2); JSONArray ja = JSONArray.fromObject(list); |
看了JSON的处理,对应存在特殊字符比如""的,怎么处理的?
用 \ 转义
关于 JSON 的Java库, Nutz 的 Json 解析器就非常好:
Java转换成Json:
1. Map<String,Object> map = new HashMap<String, Object>();
2. map.put("name", "Peter");
3. map.put("age", 21);
4. map.put("friends", null);
5. String result = Json.toJson(map);
Map<String,Object> map = new HashMap<String, Object>();
map.put("name", "Peter");
map.put("age", 21);
map.put("friends", null);
String result = Json.toJson(map);
这个时候会输出成:
1. {
2. age :21,
3. name :"Peter"
4. }
{
age :21,
name :"Peter"
}
会自动忽略掉值为空的字段.
Json转换成Java:
1. String json = "{age :21,name :\"Peter\"}";
2. map = Json.fromJson(HashMap.class, Lang.inr(json));
String json = "{age :21,name :\"Peter\"}";
map = Json.fromJson(HashMap.class, Lang.inr(json));
可以支持行注释,块注释, Json.fromJson(Class<T> type, Reader) 可以直接生成一个 Java 对象
我也是在用JSON,但不是像这样的动态生成js脚本,而是为了处理大批表格数据的读取问题,用struts(1.2)的action来生成json字符串,再用response.getWriter().write()输出到页面,ExtJS自然就是用Ext.data.JsonStore来读取了。这种方式的效率比较高,也达到了代码分离的目的,逻辑层和数据访问层根本无需暴露在web上,页面虽然是jsp,也无需使用<%%>或者struts标签。欢迎交流~
我先贴部分代码上来和大家交流一下,目前处于开发初期阶段,稍后我才做一个sample放上来。
1. /**
2. * 向浏览器输出JSON字符串
3. * @param response HttpServletResponse对象
4. * @param obj 任意对象,可以是List,也可以是单个对象
5. */
6. public void writeJsonString(HttpServletResponse response, Object obj) throws IOException {
7. if( obj == null ) {
8. this.exception = "obj参数为空";
9. logger.error(this.exception);
10. throw new NullPointerException(this.exception);
11. }
12.
13. JSONArray array = JSONArray.fromObject(obj);
14.
15. try {
16. String json = array.toString();
17. if( json.startsWith("[") ) {
18. json = json.substring(1);
19. }
20. if( json.endsWith("]") ) {
21. json = json.substring(0, json.length()-1);
22. }
23. response.setCharacterEncoding("utf-8");
24. response.getWriter().write(json);
25. } catch (IOException e) {
26. this.exception = "向浏览器输出JSON字符串时发生错误";
27. logger.error(this.exception);
28. logger.error(e);
29. throw new IOException(this.exception);
30. }
31. }
/**
* 向浏览器输出JSON字符串
* @param responseHttpServletResponse对象
* @param obj 任意对象,可以是List,也可以是单个对象
*/
public void writeJsonString(HttpServletResponse response, Object obj)throws IOException {
if( obj == null ) {
this.exception= "obj参数为空";
logger.error(this.exception);
thrownew NullPointerException(this.exception);
}
JSONArray array = JSONArray.fromObject(obj);
try {
Stringjson = array.toString();
if(json.startsWith("[") ) {
json = json.substring(1);
}
if(json.endsWith("]") ) {
json = json.substring(0, json.length()-1);
}
response.setCharacterEncoding("utf-8");
response.getWriter().write(json);
} catch (IOException e) {
this.exception= "向浏览器输出JSON字符串时发生错误";
logger.error(this.exception);
logger.error(e);
thrownew IOException(this.exception);
}
}
这里是js部分
1. var store = new Ext.data.JsonStore({
2. url: '../demo.do', //请大家根据实际情况修改action路径
3. root: 'data', //传回来的JSON字符串是HashMap生成的,data对应具体的数据集,一般是List对象
4. totalProperty: 'totalCount', //总记录数,整型
5. id: 'id',
6. fields: ['title', 'state', {name:'createDate', type: 'date'}, 'author', {name:'id', type:'int'}]
7. });
8. store.setDefaultSort('id', 'asc');
9. store.load({params:{start:0, limit:25}}); //传两个URL参数做分页处理
var store = new Ext.data.JsonStore({
url: '../demo.do', //请大家根据实际情况修改action路径
root: 'data', //传回来的JSON字符串是HashMap生成的,data对应具体的数据集,一般是List对象
totalProperty: 'totalCount', //总记录数,整型
id: 'id',
fields: ['title', 'state',{name:'createDate', type: 'date'}, 'author', {name:'id', type:'int'}]
});
store.setDefaultSort('id', 'asc');
store.load({params:{start:0, limit:25}}); //传两个URL参数做分页处理
还需要说明的是:需要json-lib-2.1-jdk15.jar, ezmorph-1.0.3.jar,到附件中取。
在学习JSON之前,当我在写大量JSP页面的时候,产生动态数据一般采用两种途径:
1.直接在页面中写java代码
2 采用各种标签代替
这两种用法的支持者都很多,但是我发现就算是采用标签也好,对于页面的重用还是无能为力,比如有几个页面都需要用到一个item数据,一个是管理用户页面,一个是订单页面。我们既要在管理用户的servlet写上setAttribute('item',item),也要在管理订单的servlet写上setAttribute('item',item);然后在页面上通过getAttribute()获得数据:
1. <%for(int i=0;i<item.length;++i){%>
2. html tag ...
3. <%}%>
<%for(inti=0;i<item.length;++i){%>
html tag ...
<%}%>
或者采用标签的形式:
1. <ww:iterator value="item">
2. html tag...
3. <ww:iterator>
<ww:iterator value="item">
html tag...
<ww:iterator>
很多时候我们会采用 <jsp:inclue page="common.jsp"/>来重用这样的页面,但这里有个问题,如果多个的页面样式不一样呢?如果数据不是很多呢,这样会产生很多页面碎片,实践已经证明,重用页面并不是一个好办法.
有时候我想,如果我能单独用一个action来提供输出数据,每个需要这些数据的页面页面都去获取这些数据,关于这些数据在页面如何渲染是页面的问题,这个action只提供数据,这样我们重用数据不是比重用页面好很多么?
但是之前的技术并不能支撑这样的实现,一个页面如何自己主动去访问它需要的数据呢?
答案是当然是通过AJAX技术.但今天我介绍的是另外一种技术JSON.
先简单的介绍一下JSON(虽然很多人已经知道),JSON JavaScirp Object Notion 可以看成一段javascript对象树,比如 user.id 表示的是user对象的id,如果对webwork或则是srtus2.0熟悉的朋友应该对此并不陌生,对象树可以嵌套对象,比如user.cat.age 表示user对象的成员cat的年龄。除了对象还可以嵌套数组方法user.cat[0].sayHello();
我们这样声明一个JSON:
1. var user = { id:’1’, name:’sanyun’};
2. alert(user.id) //输出1
3. user = { id:’1’, cat:{age:2,color:’white’ }};
4. alert(user.cat.age) //输出2
var user = { id:’1’,name:’sanyun’};
alert(user.id) //输出1
user = { id:’1’,cat:{age:2,color:’white’ }};
alert(user.cat.age) //输出2
但是JSON本身是不能和后端通信的,不过我们可以通过
1. <script type="text/javascript" src="后端资源"> </script>
<script type="text/javascript" src="后端资源"> </script>
来和服务器后端通信.
我们可以把它封装成一个方法:
1. function CallBack(model) {
2. this.model = model;
3. }
4. CallBack.init = function (url) {
5. var headElement = document.getElementsByTagName("head").item(0);
6. var scriptTag = document.createElement("script");
7. scriptTag.setAttribute("type", "text/javascript");
8. scriptTag.setAttribute("src", url);
9. headElement.appendChild(scriptTag);
10. };
function CallBack(model) {
this.model = model;
}
CallBack.init = function (url) {
var headElement =document.getElementsByTagName("head").item(0);
var scriptTag =document.createElement("script");
scriptTag.setAttribute("type", "text/javascript");
scriptTag.setAttribute("src", url);
headElement.appendChild(scriptTag);
};
不过需要注意的是采用这种方式后台MIME必须要设置为 html/Javascritp,当然你也可以轻松把这种方式替换成Ajax.
解析
通信之后我们需要做的是解析数据,一般来说,我们可以通过for in 简单的遍列JSON
1. //model表示后端产生的JSON
2. CallBack.update(model){
3. for(i in model){
4. var node =document.getElementByID(i);
5. if(node){
6. node.value = model[i];
7. }
8. }
9. }
//model表示后端产生的JSON
CallBack.update(model){
for(i in model){
var node=document.getElementByID(i);
if(node){
node.value = model[i];
}
}
}
后台
1. public class ShowType extends HttpServlet {
2.
3. protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
4.
5. response.addHeader("Cache-Control", "no-cache"); //(1)
6. response.setContentType("HTML/JavaScript;charset=GBK");//(2)
7. PrintWriter out = response.getWriter();
8. String json = ” {name:'jiangyunpeng', status:'1',sex:'female'} ”//(3)
9. out.print("CallBack.update("+json+")"); //(4)
10. }
11. }
public class ShowType extends HttpServlet {
protected voiddoGet(HttpServletRequest request, HttpServletResponse response) throwsServletException, IOException {
response.addHeader("Cache-Control","no-cache"); //(1)
response.setContentType("HTML/JavaScript;charset=GBK");//(2)
PrintWriter out =response.getWriter();
String json = ” {name:'jiangyunpeng', status:'1',sex:'female'} ”//(3)
out.print("CallBack.update("+json+")"); //(4)
}
}
(1)首先需要设置缓存为空
(2)然后MIME必须要设置为 html/Javascritp
(3)产生一段JSON,这里我们是手动产生的,可以采用JSON开源框架
(4)调用我们前面页面定义的JS函数
通过这样处理了之后我们的页面再也没有任何JAVA代码或者自定义标签了,他完全是一个HTML页面(当然这里为了演示,把解析JSON过程过于简单化了),他具有这些好处:
1.它是一个HTML,响应速度比JSP快
2.对于一些表单元素,比如checkbox,select,如果采用java代码会很繁琐,
1. function initCheckbox(){
2. if('<%=status%>'==1){ //这里有JAVA代码
3. document.getElementById('checkbox').checked = true;
4. }else{
5. document.getElementById('checkbox').checked = fasle;
6. }
7. }
function initCheckbox(){
if('<%=status%>'==1){ //这里有JAVA代码
document.getElementById('checkbox').checked = true;
}else{
document.getElementById('checkbox').checked = fasle;
}
}
但是如果采用JSON的话
1. function initCheckbox(){
2. if(status==1){ //这里只有JSON
3. document.getElementById('checkbox').checked = true;
4. }else{
5. document.getElementById('checkbox').checked = fasle;
6. }
7. }
function initCheckbox(){
if(status==1){ //这里只有JSON
document.getElementById('checkbox').checked = true;
}else{
document.getElementById('checkbox').checked= fasle;
}
}
我们可以把这段代码放在解析方法里面,判断查询的对象如果是checkbox,就像上面这样处理,这样我们就可以更本不用关心它是否是checkbox
3.重用了数据.多个页面可以通过JSON访问相同的数据,这里没有setAttribute(),也不用考虑生命周期。
4.降低了服务器端的负载。因为我们把解析的数据任务放在客户端里面进行,服务器只需要产生一些JSON字符串。
5.分离了JAVA代码和JS,诸如验证,判断,很多时候在javascript里面嵌套java,可读性很差。
JQURY JSON
JQuery处理json与ajax返回JSON实例
[导读] json数据是一种经型的实时数据交互的数据存储方法,使用到最多的应该是ajax与json配合使用了,下面我来给大家介绍jquery处理json数据方法。 一、JSON的一些基础知识。JSON中对象通过{}来标识,一个{}代表一个对象
json数据是一种经型的实时数据交互的数据存储方法,使用到最多的应该是ajax与json配合使用了,下面我来给大家介绍jquery处理json数据方法。
一、JSON的一些基础知识。
JSON中对象通过“{}”来标识,一个“{}”代表一个对象,如{“AreaId”:”123”},对象的值是键值对的形式(key:value)。
“[]”,标识数组,数组内部各个数据之间通过“,”分割,如[“AreaId”:”123”,”AreaId”:”345”]。
很多情况下是对象数组,那就是这样:
代码如下 | 复制代码 |
[{“AreaId”:”123”},{“AreaId”:”345”}] |
其实数组也是一个对象,上面的格式也可以写成这样:
代码如下 | 复制代码 |
{“Area”:[{“AreaId”:”123”},{“AreaId”:”345”}]} |
这表示一个Area对象,他有两个子数据,每个子数据也是一个对象,每个子对象都是AreaId。
JSON中字符串和字符的定义格式和一般的类C语言定义是类似的,双引号定义字符串,单引号定义字符。
JSON的键(Key)用双引号括起来,比如上面的“Area“和”AreaId“,都是用双引号括起来的,在一些语言中构造JSON字符串的时候,可以使用转义字符转义双引号。
二、javascript操作JSON字符
1、先要区分JSON字符串和JSON对象
JSON字符串:
代码如下 | 复制代码 |
Var strJSON = “{“Area”:[{“AreaId”:”123”},{“AreaId”:”345”}]}”, |
其实也可以写成这样:
代码如下 | 复制代码 |
Var strJSON = ‘{“Area”:[{“AreaId”:”123”},{“AreaId”:”345”}]}’, |
这表示一个JSON字符串,由于在Js中单引号和双引号都可以表示一个字符串,所以上面第一个使用双引号和第二个使用单引号的都表示一个JSON字符串。
下面看看JSON对象
代码如下 | 复制代码 |
Var JSON = {“Area”:[{“AreaId”:”123”},{“AreaId”:”345”}]}, |
看到了吧,JSON对象最外面是没有单引号或者双引号的,这就表示一个JSON对象。
在服务器断的脚本:
代码如下 | 复制代码 |
<?php /* echo json_encode($da);//输出的是一个转化成json格式的字符串,可以直接在js中用(如下) |
jquery脚本:
返回到js后的处理:
第一种要用到varl转化的:是字符串的时候就要用eval转化成jquery对象(如下)
代码如下 | 复制代码 |
var arr = '{"red":{"id":1,"name":"mary"},"blue":{"id":2,"name":"u71d5u5b50"}}';//u71d5u5b50这个是php中自动转换的 |
第二种:不需要转化的:
代码如下 | 复制代码 |
var arr = {"red":{"id":1,"name":"mary"},"blue":{"id":2,"name":"u71d5u5b50"}}; |
循环也有两种方法:
//方法一:
代码如下 | 复制代码 |
$.each(arr,function(idx,item){ |
//方法二:
代码如下 | 复制代码 |
for(var key in arr){ |
大家可以试试效果。
ajax返回JSON时的处理方式
1,使用普通的aspx页面来处理
本人觉得这种方式处理起来是最简单的了,看下面的代码吧
代码如下 | 复制代码 |
$.ajax({ |
这里是后台传递数据的代码
代码如下 | 复制代码 |
Response.Clear(); |
这种处理的方式将传递过来的数据直接解析为json数据,也就是说这里的前台js代码可能直接把这些数据解析成json对象数据,而并非字符串数据,如data[0].demoData,这里就直接使用了这个json对象数据