本文作者:合肥工业大学 管理学院 钱洋 email:[email protected] 内容可能有不到之处,欢迎交流。
未经本人允许禁止转载。
基于maven工程的pom文件配置:
<!-- https://mvnrepository.com/artifact/org.json/json -->
<dependency>
<groupId>org.json</groupId>
<artifactId>json</artifactId>
<version>20180130</version>
</dependency>
保存文件便可以下载所需的jar包。
将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 "get"
or
* "is"
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.
*
* The key is formed by removing the "get"
or "is"
* prefix. If the second remaining character is not upper case, then the
* first character is converted to lower case.
*
* For example, if an object has a method named "getName"
, and
* if the result of calling object.getName()
is
* "Larry Fine"
, then the JSONObject will contain
* "name": "Larry Fine"
.
*
* Methods that return void
as well as static
* 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对象,需要使用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对象,需要使用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类的源码,这三种三别为:
/***
* 使用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(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类的使用:
(1 ) Class.getDeclaredField(String name):返回一个 Field 对象,该对象反映此 Class 对象所表示的类或接口的指定已声明字段(包括私有成员)。
(2 )Class.getDeclaredFields():返回 Field 对象的一个数组,该数组包含此 Class 对象所表示的类或接口所声明的所有字段(包括私有成员)。
(3)Class.getField(String name):返回一个 Field 对象,它反映此 Class 对象所表示的类或接口的指定公共成员字段。
(4)Class.getFields():返回一个包含某些 Field 对象的数组,该数组包含此 Class 对象所表示的类或接口的所有可访问公共字段。
下面给出具体的使用案例:
首先我们编写一个类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”}
使用的构造方法为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 {
(left
* brace) and ending with }
* (right brace).
* @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);
}
使用到的处理方法是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;
}