Java中详谈net.sf.json包关于JSON与对象互转的坑

  

在网络开发过程中离不开数据的交互,这就需要规定交互数据的相关格式,以便数据在客户端与服务器之间进行传递。数据的格式通常有2种:1,xml; 2, JSON。通常来说都是使用JSON来传递数据。本文正是介绍在Java中JSON与对象之间互相转换时遇到的几个问题以及相关的建议。

  

  

JSON对象(JavaScript对象表示法,JavaScript对象表示法)。这看似只存是位JavaScript所定制的,但它作为一种语法是独立于语言以及平台的。只是说通常情况下我们在客户端(浏览器)向服务器端传递数据时,使用的是JSON格式,而这个格式是用于表示JavaScript对象。它是由一系列的“键-值”组成,如{" id ": 1、“名称”:“凯文”},这有点类似映射键值对的存储方式。在Java中所述的JSON对象,实际是指的JSONObject类,这在各个第三方的JSONjar包中通常都以这个名字命的名,不同的jar包对其内部实现略有不同。

  

JSON字符串. JSON对象和JSON字符串之间的转换是序列化与反序列化的过程,这就是好比Java对象的序列化与反序列化。在网络中数据的传递是通过字符串,或者是二进制流等等进行的,也就是说在客户端(浏览器)需要将数据以JSON格式传递时,此时在网络中传递的是字符串,而服务器端在接收到数据后当然也是字符串(String类型),有时就需要将JSON字符串转换为JSON对象再做下一步操作(String类型转换为JSONObject类型)。

  

以上两个概念的明确就基本明确了JSON这种数据格式,或者也称之为JSON语法. java中对于JSON的jar包有许多,最最“常”用的是“net.sf.json”提供的jar包了,本文要着重说的就是这个坑包,虽然坑,却有着广泛的应用。其实还有其他优秀的JSON包供我们使用,例如阿里号称最快的JSON包——fastjson还有谷歌的GSON,还有杰克逊。尽量,或者千万不要使用“net.sf.json”包,不仅有坑,而且已经很老了,老到都没法在思想里下载到源码,Maven仓库里显示它2010年在2.4版本就停止更新了。下面就谈我已知的“net.sf.json”的2个错误(我认为这是错误),以及这2个缺陷是如何产生的。

  

  

  

这是什么意思呢,例如现有以下Java对象。

        包sfjson;      进口并不知道;/* *   *由凯文>   {   “id”: 1、   “courseIds”: (1、2、3)   }      

然而在使用“net.sf。json”包的<强> JSONObject json=JSONObject.fromObject(学生), API转换后的结果却是:

  

详谈Java中net.sf.json包关于JSON与对象互转的坑

  

也就是说可以猜测到的是,“net.sf.json”获取Java对象中公共修饰符得到开头的方法,并将其后缀定义为JSON对象的“关键”,而将得到开头方法的返回值定义为对应的关键的“价值”,注意是公共修饰符得到开头的方法,且有返回值。

  

<强>我认为这是不合理的转换规则。强如果我在Java对象中定义了一个方法,仅仅因为这个方法是“获得”开的头,且有返回值就将其作为转换后JSON对象的“键-值”,那岂不是暴露出来了?或者在返回给客户端(浏览器)时候就直接暴露给了前端的控制台控制台?作者规定了这种转换规则,我想的大概原因是:既然你定义为了公众的方法,且命名为得到,那就是有意将此方法暴露出来让调用它的客户端有权获取。但我仍然认为这不合理,甚至我定义它是一个错误。我这么定义也许也不合理,因为据我实测发现,不仅是“net.sf.json”包会按照这个规则进行转换,fastjson和杰克逊同样也是照此规则,唯独谷歌的GSON并没有按照这个规则进行对象向JSON转换。

  

通过JSONObject json=JSONObject.fromObject(学生);将构造好学生的对象转换为json对象,学生如上文所述,进入此方法后会继续调用fromObject(对象,JsonConfig)的重载方法,在此重载方法中会通过instanceOf判断待转换的对象对象是否是枚举,注解等类型,这些特殊类型会有特别的判断方法。在这里是一个普通的Java POJO对象,所以会进入到_fromObject(对象,JsonConfig),在这个方法中会有一些判断,而最后则通过调用defaultBeanProcessing创建json对象。这个方法是关键,在里面还继续会通过PropertyUtils.getPropertyDescriptors (bean)方法获取“属性描述符”,实际上就是获取带得到的方法,它在这里封装成了PropertyDescriptor。这学生这个类中会获取4个,分别是:getClass, getId, getCourseIds getSql。

  

详谈Java中net.sf.json包关于JSON与对象互转的坑

Java中详谈net.sf.json包关于JSON与对象互转的坑