Java JSON技术框架选型与实例_JAVA_编程开发_程序员俱乐部

中国优秀的程序员网站程序员频道CXYCLUB技术地图
热搜:
更多>>
 
您所在的位置: 程序员俱乐部 > 编程开发 > JAVA > Java JSON技术框架选型与实例

Java JSON技术框架选型与实例

 2011/10/12 9:15:11  truemylife  http://truemylife.iteye.com  我要评论(0)
  • 摘要:JSONJSON英文全称为JavaScriptObjectNatation,采用key:value键值对的方式存贮数据,与xml格式相比,JSON是一种轻量级的数据交换格式;不要被Javascript这个单词迷惑,实际上JSON只是一种数据格式,与具体语言并无关系。JSON已被广泛应用于业界,比如目前NoSQL数据库存贮大都采用key:value存贮结构,以Mongo为例,其脚本语法甚至直接使用Javascript;在数据传输时,采用JSON格式也被广泛应用
  • 标签:Java 实例 JSON 技术 JS

?

JSON

JSON英文全称为JavaScript Object Natation,采用key:value键值对的方式存贮数据,与xml格式相比,JSON是一种轻量级的数据交换格式;不要被Javascript这个单词迷惑,实际上JSON只是一种数据格式,与具体语言并无关系。JSON已被广泛应用于业界,比如目前NoSQL数据库存贮大都采用key:value存贮结构,以Mongo为例,其脚本语法甚至直接使用Javascript;在数据传输时,采用JSON格式也被广泛应用,大部分开放API都开放JSON模式的数据输出;在ajax请求数据时,json格式也被广泛推荐。json更多信息的可以查看json官方网站http://json.org

Java transient关键字

?? JAVA规范原文The transient marker is not fully specified by the Java Language Specification but is used in object serialization to mark member variables that should not be serialized.为了方便存贮和网络传输,java有系列化对象机制,transient可用来指定当前不想被系列化的成员对象。举个例子说明transient的应用,在Mongo+Morphia开源项目下,如果对Java PO的成员指定transient,那么该成员数据将不会被存入Mongo数据库。另外一种应用场景就是这里要讲到的JSON,如果JAVA PO使用了Refrence(MongoRefrence)或者LazyLoading(可以理解Hibernate LazyLoading概念),那么大部分的开源JAVA JSON相关项目,会自动加载这些RefrenceLazyLoading对象,如果PO形成相互引用,那就会形成死循环,即使没有形成死循环,大量不必要的数据被输出到客户端对资源的浪费也不容小觑。加上transient一种解决办法

基于JAVAJSON主要开源项目及其对比

Json开源项目非常多,如org.json JSON-LibjsontoolJacksonGsonSimpleJSON等等,后来专门查看了几种json开源测试数据对比后,决定采用fastjson。展示两组测试数据。首先来看大侠wangym(原博客http://wangym.iteye.com/blog/738933)JacksonJSON-LibGson的测试结果

JSONBean5线程并发,约200字节对象,1千万次转换:

?

Jackson

JSON-lib

Gson

吞吐量

64113.7

8067.4

13952.8

总耗时()

155

1238

700

?BeanJSON5个线程并发,约200字节对象,1千万次转换:

?

Jackson

JSON-lib

Gson

吞吐量

54802

15093.2

17308.2

总耗时()

181

661

560

显而易见,无论是哪种形式的转换,Jackson > Gson > Json-lib

?????Jackson的处理能力甚至高出Json-lib10倍左右

?

然后再拿温少的fastjsonJSON-LibSimple-JSONJackson性能测试对比数据

性能对比

测试案例

JSON-Lib

Simple-JSON

Fastjson

Jackson

IntArray1000Decode

3,626

1,431

563

596

StringArray1000Decode

2,698

2,283

677

774

Map100StringDecode

515

597

208

230

功能对比

特性

JSON-Lib

Simple-JSON

Fastjson

Jackson

序列化支持数组

不支持

不支持

支持

支持

序列化支持Enum

不支持

不支持

支持

支持

支持JavaBean

不直接支持

不直接支持

支持

支持

?

可以看到Fastjson在性能方面,超越目前的所有java json proccesor,包括jackson

?

FastJson应用实例

1、利用Jquery ajax请求fastjson数据来显示用户列表例子实现

//定义一个User PO对象

public class User implements Serializable {
   
    private static final long serialVersionUID = 1738399846398814044L;
   
    private String userid;
    private String username;
    //注意这里使用了Refrence及Lazyloading相关的引用
@Refrence
    private UserDetail userDeatil;
    public String getUserid() {
       return userid;
    }
    public void setUserid(String userid) {
       this.userid = userid;
    }
    public String getUsername() {
       return username;
    }
    public void setUsername(String username) {
       this. username = username;
    }
public UserDetail getUserDetail() {
       return userDetail;
    }
    public void setUserDetail (UserDetail userDetail) {
       this. userDetail = userDetail;
    }
}
?

?

//定义一个UserDetail PO对象

public class UserDetail implements Serializable {
   
    private static final long serialVersionUID = 1738399846398814045L;
   
    private String address;
   
public String getAddress() {
       return address;
    }
    public void setAddress (String address) {
       this. address = address;
    }
}
?

?

编写Action,输出List<User>,这里使用伪码

….
List<User> ls= userService.getUserList();
PrintWriter out = null;
       try {
           out = getResponse().getWriter();
           out.write(JSON.toJSONString(ls));
           out.flush();
       } catch (IOException e) {
           e.printStackTrace();
       } finally {
           out.close();
       }
…
?

?

编写jquery ajax请求打出用户列表

$.ajax({
       type:"GET",
       url:"/user/getuserlist", //假设这是你配置后的action地址
       dataType:"json",
       cache:false,
       success: function(users){
            var html=””;
            if(users.length>0){
           for(var i in users){
               html=html+”username:”+users[i]+username+” address:”+users[i].userDetail.address;
           }
          alert(html);
}
});
?

?

2、如何解决RefrenceLazyLoading引起的死循环问题?

从上述例子可以看到fastjson会正确取出userDetail下的address数据,实际上所有的json开源项目都支持这种关联取出。但有时候我们并不需要userDetail下的数据,如果自动加载一堆无关的数据,甚至产生死循环,怎么解决呢?

第一种办法:

前面已经讲过,加上transient关键字,如给User POUserDetail定义改成

private transient  UserDetail userDeatil;
 
?

第二种办法:

第一种办法是通用的办法,使用其他json开源项目,也可以达到效果,在FastJson下还可以使用@JSONField(serialize=false)

@JSONField(serialize=false)
private transient  UserDetail userDeatil;
?

当然JSONField还有其他参数可以指定,以实现成员定制序列化,一般情况下,如果我们确定成员可以为非序列化,首先建议使用transient。但有时候指定了transient会引起其他问题,假如User对象下有长字段remark,如果给remark指定了transient,那么在比如使用Mongo数据库情况下,会导致页面提交的remark数据不能被保存到数据库,其他没有加transient关键字的字段能正常保存。这时就可以使用@JSONField来解决问题。

?

第三种办法:

?? 假如有更进一步的优化,比如场景A的时候需要系列化remark,而在场景B的时候又不需要系列化,那就使用fastjson定制过滤器,fastjson可以按namepropertyvalue三种过滤,以property例,重写获取List<user>这段伪码:

….
List<User> ls= userService.getUserList();
PropertyFilter filter = new PropertyFilter() {
    public boolean apply(Object source, String name, Object value) {
        if("remark ".equals(name)) {
            return true;
        }
        return false;
    }
};
 SerializeWriter sw = new SerializeWriter();
JSONSerializer serializer = new JSONSerializer(sw);
serializer.getPropertyFilters().add(filter);
serializer.write(ls);
PrintWriter out = null;
       try {
           out = getResponse().getWriter();
           out.write(sw.toString());
           out.flush();
       } catch (IOException e) {
           e.printStackTrace();
       } finally {
           out.close();
       }
…
?

这样在碰到场景B时就使用第三种办法把remark这个成员给过滤掉,在场景A的情况下不加过滤器即可。

更多fastjson信息可以查看http://code.alibabatech.com/wiki/display/FastJSON/Home

?

发表评论
用户名: 匿名