org.json的使用详解

本文作者:合肥工业大学 管理学院 钱洋 email:1563178220@qq.com 内容可能有不到之处,欢迎交流。

未经本人允许禁止转载

jar下载

基于maven工程的pom文件配置:

<!-- https://mvnrepository.com/artifact/org.json/json -->
		<dependency>
			<groupId>org.json</groupId>
			<artifactId>json</artifactId>
			<version>20180130</version>
		</dependency>

保存文件便可以下载所需的jar包。

JsonObject类中方法的使用

Bean对象转化为JsonObject对象

将Bean对象转化为JsonObject对象,需要使用JsonObject中的JSONObject(Object bean)构造方法,该构造方法源码为:

 /**
     * Construct a JSONObject from an Object using bean getters. It reflects on
     * all of the public methods of the object. For each of the methods with no
     * parameters and a name starting with <code>"get"</code> or
     * <code>"is"</code> followed by an uppercase letter, the method is invoked,
     * and a key and the value returned from the getter method are put into the
     * new JSONObject.
     * <p>
     * The key is formed by removing the <code>"get"</code> or <code>"is"</code>
     * prefix. If the second remaining character is not upper case, then the
     * first character is converted to lower case.
     * <p>
     * For example, if an object has a method named <code>"getName"</code>, and
     * if the result of calling <code>object.getName()</code> is
     * <code>"Larry Fine"</code>, then the JSONObject will contain
     * <code>"name": "Larry Fine"</code>.
     * <p>
     * Methods that return <code>void</code> as well as <code>static</code>
     * methods are ignored.
     * 
     * @param bean
     *            An object that has getter methods that should be used to make
     *            a JSONObject.
     */
    public JSONObject(Object bean) {
        this();
        this.populateMap(bean);
    }

这里提供了一个方法,可以在主函数中直接调用。

/***
	 * 使用JSONObject(Object bean)构造方法将Bean对象转化成JSONObject
	 */
	public static JSONObject BeanToJson (){
		BookModel book = new BookModel();
		book.setId("07");
		book.setLanguage("Java");
		book.setEdition("third");
		book.setAuthor("Herbert Schildt");
		//使用JSONObject(Object bean)构造方法
		return new JSONObject(book);
	}

Map集合转化为JsonObject对象

将Map集合转化为JsonObject对象,需要使用JsonObject中的JSONObject(Map<?, ?> m)构造方法,该构造方法源码为:

 /**
     * Construct a JSONObject from a Map.
     *
     * @param m
     *            A map object that can be used to initialize the contents of
     *            the JSONObject.
     */
    public JSONObject(Map<?, ?> m) {
        if (m == null) {
            this.map = new HashMap<String, Object>();
        } else {
            this.map = new HashMap<String, Object>(m.size());
        	for (final Entry<?, ?> e : m.entrySet()) {
                final Object value = e.getValue();
                if (value != null) {
                    this.map.put(String.valueOf(e.getKey()), wrap(value));
                }
            }
        }
    }

这里提供了一个方法,可以在主函数中直接调用。

/***
	 * 使用JSONObject(Map<?, ?> m)构造方法将Map集合数据转出成JSONObject
	 */
	public static JSONObject MapToJson (){
		Map<String,String> bookmap = new HashMap<String, String>();
		bookmap.put("id", "07");
		bookmap.put("author", "Herbert Schildt");
		bookmap.put("edition", "third");
		bookmap.put("language", "Java");
		//使用JSONObject(Object bean)构造方法
		return new JSONObject(bookmap);
	}

JSONTokener转化为JsonObject对象

将JSONTokener 对象转化为JsonObject对象,需要使用JsonObject中的JSONObject(JSONTokener x)构造方法,该构造方法源码为:

 /**
     * Construct a JSONObject from a JSONTokener.
     *
     * @param x
     *            A JSONTokener object containing the source string.
     * @throws JSONException
     *             If there is a syntax error in the source string or a
     *             duplicated key.
     */
    public JSONObject(JSONTokener x) throws JSONException {
        this();
        char c;
        String key;

        if (x.nextClean() != '{') {
            throw x.syntaxError("A JSONObject text must begin with '{'");
        }
        for (;;) {
            c = x.nextClean();
            switch (c) {
            case 0:
                throw x.syntaxError("A JSONObject text must end with '}'");
            case '}':
                return;
            default:
                x.back();
                key = x.nextValue().toString();
            }

            // The key is followed by ':'.

            c = x.nextClean();
            if (c != ':') {
                throw x.syntaxError("Expected a ':' after a key");
            }
            
            // Use syntaxError(..) to include error location
            
            if (key != null) {
                // Check if key exists
                if (this.opt(key) != null) {
                    // key already exists
                    throw x.syntaxError("Duplicate key \"" + key + "\"");
                }
                // Only add value if non-null
                Object value = x.nextValue();
                if (value!=null) {
                    this.put(key, value);
                }
            }

            // Pairs are separated by ','.

            switch (x.nextClean()) {
            case ';':
            case ',':
                if (x.nextClean() == '}') {
                    return;
                }
                x.back();
                break;
            case '}':
                return;
            default:
                throw x.syntaxError("Expected a ',' or '}'");
            }
        }
    }

而实例化JSONTokener对象的方法有三种,具体可以参考JSONTokener类的源码,这三种三别为:

  1. JSONTokener(Reader reader)
  2. JSONTokener(InputStream inputStream)
  3. JSONTokener(String s):这个案例中使用的是这种
    以下为使用案例。
/***
	 * 使用JSONObject(JSONTokener x)构造方法将Map集合数据转出成JSONObject
	 */
	public static JSONObject JSONTokenerToJson (){
		/***
		 * JSONTokener类中的构造方法有:
		 * 1. JSONTokener(Reader reader)
		 * 2. JSONTokener(InputStream inputStream)
		 * 3. JSONTokener(String s):这个案例中使用的是这种
		 */
		String jsonStr = "{\"id\":\"07\",\"language\": \"C++\",\"edition\": \"second\",\"author\": \"E.Balagurusamy\"}";
		JSONTokener jsonTokener = new JSONTokener(jsonStr);
		return new JSONObject(jsonTokener);
	}

基于反射机制构造JSONObject 对象

使用到的构造方法为JSONObject(Object object, String names[]),从源码中可以发现其使用的是反射机制。

 /**
     * Construct a JSONObject from an Object, using reflection to find the
     * public members. The resulting JSONObject's keys will be the strings from
     * the names array, and the values will be the field values associated with
     * those keys in the object. If a key is not found or not visible, then it
     * will not be copied into the new JSONObject.
     *
     * @param object
     *            An object that has fields that should be used to make a
     *            JSONObject.
     * @param names
     *            An array of strings, the names of the fields to be obtained
     *            from the object.
     */
    public JSONObject(Object object, String names[]) {
        this(names.length);
        Class<?> c = object.getClass();
        for (int i = 0; i < names.length; i += 1) {
            String name = names[i];
            try {
                this.putOpt(name, c.getField(name).get(object));
            } catch (Exception ignore) {
            }
        }
    }

关于java映射中Class类和Field类的学习,读者可参考javaschool的教程学习,地址为:

http://www.51gjie.com/java/777.html

Field是一个类,位于Java.lang.reflect包下,在Java反射中Field用于获取某个类的属性或该属性的属性值。这里简单讲解一下Field类的使用:

  • 获取Field类对象的方法:

(1 ) Class.getDeclaredField(String name):返回一个 Field 对象,该对象反映此 Class 对象所表示的类或接口的指定已声明字段(包括私有成员)。
(2 )Class.getDeclaredFields():返回 Field 对象的一个数组,该数组包含此 Class 对象所表示的类或接口所声明的所有字段(包括私有成员)。
(3)Class.getField(String name):返回一个 Field 对象,它反映此 Class 对象所表示的类或接口的指定公共成员字段。
(4)Class.getFields():返回一个包含某些 Field 对象的数组,该数组包含此 Class 对象所表示的类或接口的所有可访问公共字段。

  • 主要方法有:
    getType(): 获取属性声明时类型对象(返回class对象)
    getGenericType() : 返回属性声的Type类型
    getName() : 获取属性声明时名字
    getAnnotations() : 获得这个属性上所有的注释
    getModifiers() : 获取属性的修饰
    isEnumConstant() : 判断这个属性是否是枚举类
    isSynthetic() : 判断这个属性是否是 复合类
    get(Object obj) : 取得obj对象这个Field上的值
    set(Object obj, Object value) : 向obj对象的这个Field设置新值value

下面给出具体的使用案例:
首先我们编写一个类BookModel1 。在该类中,包含4个变量,其中三个是公有变量(id,language,)edition,一个是私有变量(author)。并且每个变量都有其set和get方法。

package com.model;

public class BookModel1 {
	public String id;
	public String language;
	public String edition;
	private String author;
	public String getId() {
		return id;
	}
	public void setId(String id) {
		this.id = id;
	}
	public String getLanguage() {
		return language;
	}
	public void setLanguage(String language) {
		this.language = language;
	}
	public String getEdition() {
		return edition;
	}
	public void setEdition(String edition) {
		this.edition = edition;
	}
	public String getAuthor() {
		return author;
	}
	public void setAuthor(String author) {
		this.author = author;
	}
}

我们以下面的程序演示获取Field类对象的方法

package com.orgjson.parse;

import java.lang.reflect.Field;
import com.model.BookModel1;


public class Demo {

	public static void main(String[] args) throws NoSuchFieldException, SecurityException, IllegalArgumentException, IllegalAccessException {
		BookModel1 book = new BookModel1();
		book.setId("07");
		book.setLanguage("Java");
		book.setEdition("third");
		book.setAuthor("Herbert Schildt");
		//获取 Class对象
		Class cls = book.getClass();
		System.out.println(cls);
		/*返回一个 Field对象,反映此 Class对象所表示的类或接口的指定公共成员字段。
		 * 注意这里如果使用getField("author")则会产生报错,原因是author是私有变量
		 * */
		Field field1 = cls.getField("id");
        System.out.println("Public field found: " + field1.toString());
        //共有变量和私有变量皆可行
        Field field2 = cls.getDeclaredField("author"); 
        System.out.println("Public and Private field found: " + field2.toString());
        //getDeclaredFields()
        System.out.println("getDeclaredFields()结果为:");
        Field[] fieldarr1 = cls.getDeclaredFields(); 
        for (int i = 0; i < fieldarr1.length; i++) {
        	System.out.println("Public and Private field found: " + fieldarr1[i].toString());
		}
        //getFields()
        System.out.println("getFields()结果为:");
        Field[] fieldarr2 = cls.getFields(); 
        for (int i = 0; i < fieldarr2.length; i++) {
        	System.out.println("Public field found: " + fieldarr2[i].toString());
		}
        /*
         * 演示主要方法
		 * */
        //获取属性值
       Object object =  field1.get(book);
       System.out.println(object);
       //获取类型对象
       Class<?> class_test = field1.getType();
       System.out.println(class_test);
	}

}

这个程序的运行结果为:
在这里插入图片描述

通过这个案例,再去看JSONObject(Object object, String names[]) 构造方法的源码时,发现其本质是将Object 的数据取出来put到Map集合中,然后构造JSONObject。

下面我将以一个程序演示该构造方法的使用
首先,编写一个类,这个类中只有共有变量:

package com.model;

public class BookModel2 {
	public String id;
	public String language;
	public String edition;
	public String author;
	public String getId() {
		return id;
	}
	public void setId(String id) {
		this.id = id;
	}
	public String getLanguage() {
		return language;
	}
	public void setLanguage(String language) {
		this.language = language;
	}
	public String getEdition() {
		return edition;
	}
	public void setEdition(String edition) {
		this.edition = edition;
	}
	public String getAuthor() {
		return author;
	}
	public void setAuthor(String author) {
		this.author = author;
	}	
}

下面为主函数:

package com.orgjson.parse;

import java.util.HashMap;
import java.util.Map;
import org.json.JSONObject;
import org.json.JSONTokener;
import com.model.BookModel;
import com.model.BookModel2;

public class OrgJsonBeanToObject {

	public static void main(String[] args) {
		JSONObject namesToJson = namesToJson();
		System.out.println(namesToJson);
	}
	
	/***
	 * 使用JSONObject(Object object, String names[])构造方法转出成JSONObject
	 */
	public static JSONObject namesToJson (){
		BookModel2 book = new BookModel2();
		book.setId("07");
		book.setLanguage("Java");
		book.setEdition("third");
		book.setAuthor("Herbert Schildt");
		String names[] = {"id","language","edition","author"};
		return new JSONObject(book,names);
	}
}

该程序成功得到json对象:

{“edition”:“third”,“language”:“Java”,“id”:“07”,“author”:“Herbert Schildt”}

基于json字符串构造JSONObject 对象

使用的构造方法为JSONObject(String source),对应的源码为:

 /**
     * Construct a JSONObject from a source JSON text string. This is the most
     * commonly used JSONObject constructor.
     *
     * @param source
     *            A string beginning with <code>{</code>&nbsp;<small>(left
     *            brace)</small> and ending with <code>}</code>
     *            &nbsp;<small>(right brace)</small>.
     * @exception JSONException
     *                If there is a syntax error in the source string or a
     *                duplicated key.
     */
    public JSONObject(String source) throws JSONException {
        this(new JSONTokener(source));
    }

这种方式在网络爬虫解析数据时非常常用。如下给出了一个简单的案例:
直接编写一个主函数调用这个函数就可以运行了。

	/***
	 * 使用JSONObject(String source)构造方法转出成JSONObject
	 */
	public static JSONObject stringToJson (){
		//json字符串
		String json = "{\"id\":\"07\",\"language\": \"C++\",\"edition\": \"second\",\"author\": \"E.Balagurusamy\"}";
		return new JSONObject(json);
	}

基于键值对的方式为JSONObject 对象添加内容

使用到的处理方法是accumulate和append方法,该方法的源码为:

public JSONObject accumulate(String key, Object value) throws JSONException {
        testValidity(value);
        Object object = this.opt(key);
        if (object == null) {
            this.put(key,
                    value instanceof JSONArray ? new JSONArray().put(value)
                            : value);
        } else if (object instanceof JSONArray) {
            ((JSONArray) object).put(value);
        } else {
            this.put(key, new JSONArray().put(object).put(value));
        }
        return this;
    }

    /**
     * Append values to the array under a key. If the key does not exist in the
     * JSONObject, then the key is put in the JSONObject with its value being a
     * JSONArray containing the value parameter. If the key was already
     * associated with a JSONArray, then the value parameter is appended to it.
     *
     * @param key
     *            A key string.
     * @param value
     *            An object to be accumulated under the key.
     * @return this.
     * @throws JSONException
     *             If the key is null or if the current value associated with
     *             the key is not a JSONArray.
     */
    public JSONObject append(String key, Object value) throws JSONException {
        testValidity(value);
        Object object = this.opt(key);
        if (object == null) {
            this.put(key, new JSONArray().put(value));
        } else if (object instanceof JSONArray) {
            this.put(key, ((JSONArray) object).put(value));
        } else {
            throw new JSONException("JSONObject[" + key
                    + "] is not a JSONArray.");
        }
        return this;
    }

针对上述源码中的两种方法以下提供了使用案例:

/***
	 * JSONObject accumulate(String key, Object value)方法的使用
	 */
	public static JSONObject accumulateToJson (){
		JSONObject jsonObject = new JSONObject();
		jsonObject.accumulate("id", "07");
		jsonObject.accumulate("language", "C++");
		jsonObject.accumulate("edition", "second");
		jsonObject.accumulate("author", "E.Balagurusamy");
		return jsonObject;
	}
	/***
	 * JSONObject append(String key, Object value)方法的使用
	 */
	public static JSONObject appendToJson (){
		JSONObject jsonObject = new JSONObject();
		jsonObject.append("id", "07");
		jsonObject.append("language", "C++");
		jsonObject.append("edition", "second");
		jsonObject.append("author", "E.Balagurusamy");
		return jsonObject;
	}

JSONArray类

评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值