net.sf.json.JSONException- null object_json数组转json对象

发布时间:2025-12-09 13:58:40 浏览次数:4

1 简介

在程序开发过程中,在参数传递,函数返回值等方面,越来越多的使用JSON。JSON(JavaScript Object Notation)是一种轻量级的数据交换格式,同时也易于机器解析和生成、易于理解、阅读和撰写,而且Json采用完全独立于语言的文本格式,这使得Json成为理想的数据交换语言。
JSON建构于两种结构:

  1. “名称/值”对的集合(A Collection of name/value pairs),在不同的语言中,它被理解为对象(Object), 记录(record), 结构(struct), 字典(dictionary), 有趣列表(keyed list), 哈希表(hash table)或者关联数组(associative array)。
  2. 值得有序列表(An order list of values)。在大多数语言中,它被理解为数组(array).
    在C++程序设计中,可以使用RapidJson、Jsoncpp等工具,因为才开始从事Java程序的开发,为了提升开发效率,因此也要熟练掌握一种Json生成和解析的工具。在Java中较为常见的Json解析工具有阿里巴巴的fastjson,但由于项目中自带有net.sf.json包。因此使用该包进行Json的构建和解析。

2 详细描述

JSON-lib是一个用于转换beans、maps、collections、java arrays、XML成JSON对象以及反之转化成benas和DynaBeans的java库。JSON-lib建立在Douglas Crockford的工作基础之上。

2.1 JSONObject

public final class JSONObject extends AbstractJSON implements JSON, Map, Comparable {    

从上述的接口声明中,可以看到JSONObject实现了接口Map,Comparable,这两个接口为java jdk自带的接口,而JSON接口代码如下:

package net.sf.json;import java.io.Serializable;import java.io.Writer;public interface JSON extends Serializable {        boolean isArray();    boolean isEmpty();    int size();    String toString(int var1);    String toString(int var1, int var2);    Writer write(Writer var1); }

一个JSONObject是一个无序的name/value对集合。它的外部形式是一个由花括号“{}”括起的字符串,在name和value之间使用冒号“:”隔开,在names/values之间用逗号隔开。JSONObjet的图示如下:

如下例所示:

{    "errCode": 200,    "msg": "success",    "data": { "jguan": "11", "xming": "11", "dwei_name": "", "zji_code": "", "is_cbdwfzltxiu": "", "fzltxiu_date": "2", } }

内部的形式是一个拥有get和opt方法来根据name访问value、put方法来根据name增加或替换value的对象。在JSONObject中,值可以为以下类型:

Boolean、 JSONObject、 JSONArray、 Number、 String、 或者JSONNull对象

JSONObject类型的构造器可以用于转换外部形式的JSON text成一种可以由get和opt方法访问的内部形式,或者使用element方法和toString方法把值转换成为JSON text。如果name存在,则get会返回对应的值,否则会抛出异常JSONException。而opt方法则会在不存在所要检索的name时可以指定一个默认值而不是抛出异常,这样可以获取可选择值。
普通的get()和opt()方法会返回Object,因而可以对返回值进行强制类型转换。也可以使用类型化的get和opt方法进行类型审核和强转。
String myString = new JSONObject().put(“JSON”, “Hello, World!”).toString();
将会产生{“JSON”: “Hello, World”}

2.2 JSONArray

JSONArray是一个有序的值得序列。它的外部形式是包括在方括号[]内的字符串,由逗号分隔值。

[“aaa”, “bbb”, “ccc”]

内部的形式是一个拥有get和opt方法的对象,这两个方法可以根据索引访问值,element方法可以用来添加和替换值。

这些值可以是任意类型

Boolean、 JSONObject、 JSONArray、 Number、 String、 或者JSONNull对象

图示如下:

JSONArray的类型定义如下:

public final class JSONArray extends AbstractJSON implements JSON, List, Comparable {    

因此在操作JSONArray对象时可以使用JSON接口、List接口以及Comparable接口提供的方法,可以把JSONArray看成一个List对象。
构造器可以把一个JSON text转换成为Java对象,toString方法转换成JSON text。

3 如何安装

可以使用Maven快速导入该net.sf.json包,对应放入pom.xml依赖说明如下:

<dependency>    <groupId>net.sf.json-lib</groupId><artifactId>json-lib</artifactId><version>2.4</version><classifier>jdk15</classifier></dependency>

在pom.xml文件中添加上述的依赖,Import Changes即可。

注意:添加的依赖文件必须含有标记,不然maven无法从仓库中下载成功

4 JSONObject

4.1 构造器

JSONObject有两种常见的构造方法,一般常用的构造函数为JSONObject(),构造一个不含任何name/value的JSONObject对象

JSONObjectpublic JSONObject()Construct an empty JSONObject. JSONObjectpublic JSONObject(boolean isNull)Creates a JSONObject that is null. 

4.2 判断方法

由于JSONObject继承自Map接口,因此该类型自动的包含一些判断方法,简要介绍如下:

4.2.1 判空

判空的含义是JSONObject对象中是否不包含任何name/value对映射。

public boolean isEmpty()Description copied from interface: JSONReturns true if this object has no elements or keys. Specified by:isEmpty in interface MapSpecified by:isEmpty in interface JSON

<>4.2.2 判Null
判Null则对应构造函数的第二种形式,即该对象为null,而相应的在这类对象的基础上,如果添加了键值对,则会重新分配空间。

isNullObjectpublic boolean isNullObject()Returs if this object is a null JSONObject. 

4.2.3 包含name

public boolean containsKey(uObject key)Specified by:containsKey in interface Map

该方法确保JSONObject中是否包含键的判断。
JSONObject对象也提供了has方法

public boolean has(String key)Determine if the JSONObject contains a specific key. Parameters:key - A key string. Returns:true if the key exists in the JSONObject.

4.2.4 包含value

该接口继承自Map接口

public boolean containsValue(Object value)Specified by:containsValue in interface Map

4.2.5 判等

两个JSONObject对象相等表示两个JSONObject包含相同的键集合,同时每个键对应的值也相等。

public boolean equals(Object obj)Specified by:equals in interface MapOverrides:equals in class Object

4.2.6 判断是否为数组

判断一个name对应的value类型是否为数组的方法声明如下:

public boolean isArray()Description copied from interface: JSONReturns true if this object is a JSONArray, false otherwise. Specified by:isArray in interface JSON

4.3 存储name/value

在JSONObject中可以存放name/value的方法有如下几种:accumulate方法、element方法、put方法、putAll方法、在此简要介绍这几个方法的用处。

4.3.1 追加

在JSONObject中由于name的类型为字符串类型,而值可以为JSONObject,JSONArray,Boolean、 JSONObject、 JSONArray、 Number、 String、 或者JSONNull对象。
在同一个name下,放置多个值,即组成JSONArray类型。
在下面的方法中,在一个key下累加一个值,如果已经有一个值为存储在key对应的对象中,该函数与element方法类似,此时会在key对应的位置存储一个JSONArray对象保存所有积累的值。如果已经有一个JSONArray对象,那么新值会追加到该JSONArray对象。作为对比,replace方法会替换之前的值。

public JSONObject accumulate(String key,                             boolean value)Accumulate values under a key. It is similar to the element method except that if there is already an object stored under the key then a JSONArray is stored under the key to hold all of the accumulated values. If there is already a JSONArray, then the new value is appended to it. In contrast, the replace method replaces the previous value. Parameters:key - A key string.value - An object to be accumulated under the key. Returns:this.  Throws: JSONException - If the value is an invalid number or if the key is null.

通过accumulate类方法可以把value累加到对应的name下而不会覆盖原有的value值而是形成一个JSONArray对象,不断追加新的Value。
类似的方法如下:

public JSONObject accumulate(String key, boolean value);public JSONObject accumulate(String key, double value);public JSONObject accumulate(String key, int value) ;public JSONObject accumulate(String key, long value) ;public JSONObject accumulate(String key, Object value);public JSONObject accumulate(String key, Object value, JsonConfig jsonConfig) ;public void accumulateAll(Map map);public void accumulateAll(Map map, JsonConfig jsonConfig) ;

accumulate方法代码片段如下;

JSONArray array = new JSONArray();array.add("123");array.add(1);Map<String, Integer> val = new HashMap<>();val.put("1", 20);val.put("2", 30);System.out.println(array.toString());array.add(val);System.out.println(array.toString());JSONObject json = new JSONObject(true);System.out.println(json.isNullObject());//Can't accumulate on null object//json.accumulate("1", 1);//null object//json.put("1", 1);json = new JSONObject();json.accumulate("1", 1);json.accumulate("1", val);System.out.println(json.toString());json.putAll(val);System.out.println(json.toString());打印结果如下:["123",1]["123",1,{    "1":20,"2":30}]true{    "1":[1,{    "1":20,"2":30}]}{    "1":20,"2":30}

阅读上述代码片段,可以看到几个注意点:

注意:如果使用构造器new
JSONObject(true);则构造出来的JSONObject对象无法accumulate和put。否则会抛出异常,由代码片段中的注释可以看出。
另外put方法会进行替换而不会追加到name对应的value集合中。 最后的json.putAll(val); 中有name
“1”,替换了之前”1”对应的集合。

4.3.2 替换或存储

在JSONObject中替换name对应的value时,可以使用put方法实现

JSONObject json = new JSONObject();SONArray jsonInner = new JSONArray();//java.lang.IndexOutOfBoundsException: Index: 5, Size: 0 //jsonInner.add(5, "1");for(int i=0; i<5; i++) {         jsonInner.add(i);}json.put("1", jsonInner);System.out.println(json.toString());json.put("1", new int[]{    1, 2, 6});System.out.println(json.toString());Map<String, String> vals = new HashMap<String, String>();vals.put("1", "sqh");vals.put("3", "lww");vals.put("2", "computer");json.putAll(vals);System.out.println(json.toString());

向JSONObject对象中存储name/value对可以通过put存放。该接口继承自Map接口
当name已经存在于JSONObject中,实际作用是用新值替换旧值,与以下函数等价
json.replace(“1”, “sqh”);

4.3.3 存储

还有一类增加的方法为elemnent方法

public JSONObject element(String key,                          double value)Put a key/double pair in the JSONObject. Parameters:key - A key string.value - A double which is the value. Returns:this. Throws: JSONException - If the key is null or if the number is invalid.

该类方法与put方法类似,但由于element方法的返回值类型为JSONObject,因此可以使用链式存储的方式,非常方便。
element方法代码片段如下:

JSONObject json = new JSONObject();json.element("1", 1).element("2", 2);System.out.println(json.toString());json.element("1", 3).element("2", 4);System.out.println(json.toString());

该代码片段运行结果如下:

{"1":1,"2":2}{"1":3,"2":4}

从代码执行来看,第一次打印的值和第二次打印的值,分析得到实际执行取代了name ”1”和”2”的值。实际方法实现如下:

public JSONObject element(String key, int value) {            this.verifyIsNull();            return this.element(key, (Object)(new Integer(value)));}

上述为JDK代码对应的代码实现,存放时转化为(Object)类型。

public JSONObject element(String key, boolean value) ;public JSONObject element(String key, Collection value);public JSONObject element(String key, Collection value, JsonConfig jsonConfig);public JSONObject element(String key, double value) ;public JSONObject element(String key, int value) ;public JSONObject element(String key, long value);public JSONObject element(String key, Map value) ;public JSONObject element(String key, Map value, JsonConfig jsonConfig);public JSONObject element(String key, Object value) ;public JSONObject element(String key, Object value, JsonConfig jsonConfig) ;

4.4 检索

从JSONObject检索数据也提供了一些常用的方法,例如一些列的get方法,opt方法。介绍如下:

getpublic Object get(Object key)Specified by:get in interface Map________________________________________getpublic Object get(String key)Get the value object associated with a key. Parameters:key - A key string. Returns:The object associated with the key. Throws: JSONException - if this.isNull() returns true.

4.4.1 getXXX

上述的两个方法第一个方法继承自Map接口,因此key的类型为Object,返回值类型也为Object,由于返回值类型为根类型,因此需要强制转换为具体的类型。

getBooleanpublic boolean getBoolean(String key)Get the boolean value associated with a key. Parameters:key - A key string. Returns:The truth. Throws: JSONException - if the value is not a Boolean or the String "true" or "false".

getBoolean方法如果key为null,或者值不是Boolean或者串”true”或”false”,会抛出JSONException异常。通过getXXX可以获取指定类型的Value而不需要强制转换,较为方便,
getBoolean方法实际实现如下:

public boolean getBoolean(String key) {this.verifyIsNull();Object o = this.get(key);if (o != null) {        if (o.equals(Boolean.FALSE) || o instanceof String && ((String)o).equalsIgnoreCase("false")) {            return false;        }        if (o.equals(Boolean.TRUE) || o instanceof String && ((String)o).equalsIgnoreCase("true")) {            return true;        }    }    throw new JSONException("JSONObject[" + JSONUtils.quote(key) + "] is not a Boolean.");}

同类型的方法如下:

public boolean getBoolean(String key) ;public double getDouble(String key) {this.verifyIsNull();    Object o = this.get(key);    if (o != null) {        try {            return o instanceof Number ? ((Number)o).doubleValue() : Double.parseDouble((String)o);        } catch (Exception var4) {            throw new JSONException("JSONObject[" + JSONUtils.quote(key) + "] is not a number.");        }    } else {        throw new JSONException("JSONObject[" + JSONUtils.quote(key) + "] is not a number.");    }}public int getInt(String key) ;public JSONArray getJSONArray(String key) ;public JSONObject getJSONObject(String key);public long getLong(String key) ;public String getString(String key) ;

4.4.2 optXXX

JSONObject同时提供了optXXX的方法获取name对应的value值。

public Object opt(String key) ;public boolean optBoolean(String key) ;public boolean optBoolean(String key, boolean defaultValue) ;public double optDouble(String key) ;public double optDouble(String key, double defaultValue);public int optInt(String key) ;public int optInt(String key, int defaultValue) ;public JSONArray optJSONArray(String key) ;public JSONObject optJSONObject(String key) {    this.verifyIsNull();    Object o = this.opt(key);    return o instanceof JSONObject ? (JSONObject)o : null;}public long optLong(String key);public long optLong(String key, long defaultValue) ;public String optString(String key) ;public String optString(String key, String defaultValue);

optXXX的方法与getXXX最大的区别是,optXXX方法可以指定默认值。

optDoublepublic double optDouble(String key,                        double defaultValue)Get an optional double associated with a key, or the defaultValue if there is no such key or if its value is not a number. If the value is a string, an attempt will be made to evaluate it as a number. Parameters:key - A key string.defaultValue - The default. Returns:An object which is the value.

4.5 遍历

在遍历JSONObject对象时,需要使用下述的方式。确保正确使用返回值,即迭代器或者Set集合,或者JSONArray

public Iterator keys()Get an enumeration of the keys of the JSONObject. Returns:An iterator of the keys.public Set keySet()Specified by:keySet in interface Mappublic JSONArray names()Produce a JSONArray containing the names of the elements of this JSONObject. Returns:A JSONArray containing the key strings, or null if the JSONObject is empty.public Set entrySet()Specified by:entrySet in interface Mappublic Collection values()Specified by:values in interface Map

使用上述方法的代码片段如下:

JSONObject json = new JSONObject();json.element("1", new int[]{    1, 2, 3}).element("2", (new JSONArray()).element(1).element(2));json.element("3", 5.6);json.element("4", "abc");for (Object str:json.keySet()) {     String key = (String)str;     System.out.println(json.get(key));}Set<Object> ss = json.entrySet();for (Object o:ss) {     System.out.println(o);}Collection<Object> col = json.values();System.out.println(col);Iterator<Object> it = col.iterator();while(it.hasNext()) {    //取出迭代器对应的值    System.out.println(it.next());}

4.6 Map或Bean转换成JSONObject

//从一个Map构造JSONObjectMap 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 jObject = JSONObject.fromObject( map );System.out.println( jObject );// prints ["name":"json","bool":true,"int":1,"arr":["a","b"],"func":func

从Bean转换为JSONObject

class MyBean{        private String name = "json";        private int pojoId = 1;        private char[] options = new char[]{    'a','f'};        private String func1 = "function(i){ return this.options[i]; }";        private JSONFunction func2 = new JSONFunction(new String[]{    "i"},"return this.options[i];");}getset方法//从一个Java对象(Java Bean构造JSONObject)    JSONObject jsonObject = JSONObject.fromObject( new MyBean() );    System.out.println( jsonObject );/* prints  {    "name":"json","pojoId":1,"options":["a","f"],  "func1":function(i){ return this.options[i];},  "func2":function(i){ return this.options[i];}}*/

5 代码演示

5.1 JSONObject

JSONObject的演示代码如下:public class JSONObjectUse {    public static void main(String[] args) {        //创建JSONObject对象        JSONObject jsonObject = new JSONObject();        jsonObject.put("username","wln");        jsonObject.put("password","123");        System.out.println("1:" + jsonObject);        //增加属性        jsonObject.element("sex","男");        System.out.println("2:" + jsonObject);        //判断输出对象的类型        boolean isArray = jsonObject.isArray();        boolean isEmpty = jsonObject.isEmpty();        boolean isNullObject = jsonObject.isNullObject();        System.out.println("3:" + "是否是数组:" + isArray +" 是否是空:" + isEmpty + " 是否是空对象:" + isNullObject);        //创建JSONArray        JSONArray jsonArray = new JSONArray();        jsonArray.add(0,"aa");        jsonArray.add("BB");        jsonArray.add(1,"AB");        jsonArray.add("cc");        //将JSONArray 添加到JSONObject        jsonObject.element("student",jsonArray);        System.out.println("4:" + jsonObject);    }}

结果:

1:{    "username":"wln","password":"123"}2:{    "username":"wln","password":"123","sex":"男"}3:是否是数组:false 是否是空:false 是否是空对象:false4:{    "username":"wln","password":"123","sex":"男","student":["aa","AB","BB","cc"]}

5.2 JSONArray

public class JSONArrayUse {    public static void main(String[] args) {        //创建JSONArray对象        JSONArray jsonArray = new JSONArray();        jsonArray.add(0,"aa");        jsonArray.add(1,"BB");        jsonArray.element("cc");        jsonArray.add("DD");        System.out.println("1:" + jsonArray);        //根据下标获取数据        System.out.println("2:" + jsonArray.get(0));        //根据下标设置数据        jsonArray.set(0,"AAA");        System.out.println("3:" + jsonArray);        //创建JSONObject        JSONObject jsonObject = new JSONObject();        jsonObject.put("username", "lwc");        jsonObject.put("password", "123");        //把JSONObject放入到JSONArray中        jsonArray.add(jsonObject);        System.out.println("4:" + jsonArray);        //遍历        System.out.println("5:");        for(int i=0;i<jsonArray.size();i++){            System.out.print(jsonArray.get(i)+"\t");        }    }}

结果:

1:["aa","BB","cc","DD"]2:aa3:["AAA","BB","cc","DD"]4:["AAA","BB","cc","DD",{    "username":"lwc","password":"123"}]5:AAA    BB    cc    DD    {    "username":"lwc","password":"123"}

5.3 Spring-MVC中用于参数接受

在使用JSONObject进行Java Web开发时,常用的便是json参数的解析和传送。在下述的代码片段中可以使用url进行访问:

url:localhost:8080/netjson?a=1&b=2

同时使用postman工具指定url Body为

{   "name":"sqh",    "pwd":"123",    "phone":1234 }

想要以一种非常方便的方式接受参数,则可以如下设置:

public JSONObject sfJsonTest(HttpServletRequest request, @RequestBody JSONObject content) {    

通过指定@RequestBody类型为JSONObject,可以完成从JSON text到JSONObject的自动转换。

package com.example.demo;import net.sf.json.JSONObject;import org.springframework.web.bind.annotation.RequestBody;import org.springframework.web.bind.annotation.RequestMapping;import org.springframework.web.bind.annotation.ResponseBody;import org.springframework.web.bind.annotation.RestController;import javax.servlet.http.HttpServletRequest;@RestControllerpublic class NetSfJsonTest {    @ResponseBody    @RequestMapping("/netsfjson")    public JSONObject sfJsonTest(HttpServletRequest request, @RequestBody JSONObject content) {        System.out.println("?后的内容: "+request.getQueryString());        String name = (String)content.get("name");        Integer phone = (Integer)content.get("phone");        String pwd = (String)content.get("pwd");        JSONObject result = new JSONObject();        result.put("errCode", 200);        result.put("errMsg", "success");        result.put("data", content);        return result;    }}

6 总结

由于在项目开发时必须以json的格式接受并且向前端以json的方式回传数据,因此比较熟悉某种json解析的方式非常有帮助。在C++开发时较为详细的了解了rapidJSON工具的使用,而Java开发时net.sf.json包的使用可以扮演同样的角色,熟练这个使用可以提升开发的效率。
文档位于

https://download.csdn.net/download/lk142500/10652591

7 引用

www.json.org/json-zh.html
https://www.cnblogs.com/nananana/p/9263708.html

需要做网站?需要网络推广?欢迎咨询客户经理 13272073477