轉json操作

zhyp29發表於2016-05-10
json教程系列(1)-使用json所要用到的jar包
json是個非常重要的資料結構,在web開發中應用十分廣泛。我覺得每個人都應該好好的去研究一下json的底層實現,基於這樣的認識,金絲燕網推出了一個關於json的系列教程,分析一下json的相關內容,希望大家能有所收穫。首先給大家說一下使用json前的準備工作,需要準備下面的六個jar包:
commons-lang-1.0.4.jar
commons-collections-2.1.jar
commons-beanutils-1.8.0.jar
json-lib-2.4.jar
ezmorph-1.0.6.jar
commons-logging-1.1.jar
需要說明幾點:
(1)json-lib最新版本可以從這個地方下載:http://sourceforge.net/projects/json-lib/files/json-lib/
(2)ezmorph是一個簡單的java類庫,用於將一種bean轉換成另外一種bean。其動態bean的實現依賴於commons-beanutils包。ezmorph可以在這個地方下載原始碼:http://sourceforge.net/projects/ezmorph/files/ezmorph/
(3)commons-beanutils是操作Java Bean的類庫,依賴於commons-collections。
(4)commons-collections類庫是各種集合類和集合工具類的封裝。
(本文於2015年5月29日修訂)


json教程系列(2)-生成JSONObject的方法
生成JSONObject一般有兩種方式,通過javabean或者map型別來生成。如下面的例子

public class User
{
    public String username;
    public String password;
    public String getUsername()
    {
      return username;
    }
    public void setUsername(String username)
    {
      this.username = username;
    }
    public String getPassword()
    {
       return password;
    }
    public void setPassword(String password)
    {
       this.password = password;
    }
}

import java.util.HashMap;
import net.sf.json.JSONObject;
public class Test {
 
public static void main(String args[]) {
    
    User user = new User();
    user.setUsername("root");
    user.setPassword("1234");
    JSONObject json1 = JSONObject.fromObject(user);
    System.out.println(json1.toString());
    HashMap<Object,Object> userMap= new HashMap<Object,Object>();
    userMap.put("username", "root");
    userMap.put("password", "1234");
    JSONObject json2 = JSONObject.fromObject(userMap);
    System.out.println(json2.toString());
    
}
}
下面從原始碼層次分析一下JSONObject.fromObject()方法:


public static JSONObject fromObject(Object object)
{
    return fromObject(object, new JsonConfig());
}
此函式可以接受的引數型別為:JSON formatted strings,Maps,DynaBeans and JavaBeans。
【注意】DynaBeans是commons-beanutils定義的動態bean。DynaBean並不是Java中所定義的Bean,而是一種"假"的Bean。因為它並不是通過getXXX和setXXX方法,對XXX屬性進行取值和設值的。
如果object是其他型別的引數呢?比如說數字,邏輯值,非json格式的字串,那麼將生產空的JSONObject物件。


if (JSONUtils.isNumber(object) || JSONUtils.isBoolean(object) || JSONUtils.isString(object))
{
    return new JSONObject();
}
JSONObject的建構函式有兩個:


public JSONObject()
{
        this.properties = new ListOrderedMap();
}
public JSONObject(boolean isNull)
{
        this();
        this.nullObject = isNull;
}
不過,說實話,第二個建構函式使用情況很少。


json教程系列(3)-JSONObject的過濾設定
我們通常對一個json串和java物件進行互轉時,經常會有選擇性的過濾掉一些屬性值。例如下面的類:


public class Person
{
    private String name;
    private String address;
    private String sex;
 
    public String getAddress()
    {
        return address;
    }
 
    public void setAddress(String address)
    {
        this.address = address;
    }
 
    public String getName()
    {
        return name;
    }
 
    public void setName(String name)
    {
        this.name = name;
    }
 
    public String getSex()
    {
        return sex;
    }
 
    public void setSex(String sex)
    {
        this.sex = sex;
    }
}
如果我想過濾address屬性怎麼辦?

方法一:實現JSONString介面

import net.sf.json.JSONString;
public class Person implements JSONString
{
    private String name;
    private String sex;
    private String address;
    public String toJSONString()
    {
        return "{\"name\":\"" + name + "\",\"sex\":\"" + sex + "\"}";
    }
    public String getAddress()
    {
        return address;
    }
    public void setAddress(String address)
    {
        this.address = address;
    }
    public String getName()
    {
        return name;
    }
    public void setName(String name)
    {
        this.name = name;
    }
    public String getSex()
    {
        return sex;
    }
    public void setSex(String sex)
    {
        this.sex = sex;
    }
}


import net.sf.json.JSONObject;
public class Test {
public static void main(String args[]) {
       Person person = new Person();
        person.setName("swiftlet");
        person.setSex("men");
        person.setAddress("china");
        JSONObject json = JSONObject.fromObject(person);
        System.out.println(json.toString());
    }
}
方法二:設定jsonconfig例項,對包含和需要排除的屬性進行新增或刪除。

import net.sf.json.JSONObject;
import net.sf.json.JsonConfig;
public class Test
{
    public static void main(String args[])
    {
        Person person = new Person();
        person.setName("swiftlet");
        person.setSex("men");
        person.setAddress("china");
        JsonConfig jsonConfig = new JsonConfig();
        jsonConfig.setExcludes(new String[]
        { "address" });
        JSONObject json = JSONObject.fromObject(person, jsonConfig);
        System.out.println(json.toString());
    }
}
方法三:使用propertyFilter例項過濾屬性。

import net.sf.json.JSONObject;
import net.sf.json.JsonConfig;
import net.sf.json.util.PropertyFilter;
public class Test
{
    public static void main(String args[])
    {
        Person person = new Person();
        person.setName("swiftlet");
        person.setSex("men");
        person.setAddress("china");
        JsonConfig jsonConfig = new JsonConfig();
        jsonConfig.setJsonPropertyFilter(new PropertyFilter() {
            public boolean apply(Object source, String name, Object value)
            {
                return source instanceof Person && name.equals("address");
            }
        });
        JSONObject json = JSONObject.fromObject(person, jsonConfig);
        System.out.println(json.toString());
    }
}

json教程系列(4)-optXXX方法的使用
在JSONObject獲取value有多種方法,如果key不存在的話,這些方法無一例外的都會丟擲異常。如果線上環境丟擲異常,就會使出現error頁面,影響使用者體驗,針對這種情況最好是使用optXXX方法。
getString方法會丟擲異常,如下所示:
public String getString(String key)
    {
        verifyIsNull();
        Object o = get(key);
        if (o != null)
        {
            return o.toString();
        }
        throw new JSONException("JSONObject[" + JSONUtils.quote(key) + "] not found.");
    }

getInt方法會丟擲異常,如下所示:
public int getInt(String key)
    {
        verifyIsNull();
        Object o = get(key);
        if (o != null)
        {
            return o instanceof Number ? ((Number) o).intValue() : (int) getDouble(key);
        }
        throw new JSONException("JSONObject[" + JSONUtils.quote(key) + "] is not a number.");
    }
getDouble方法會丟擲異常,如下所示:    


public double getDouble(String key)
    {
        verifyIsNull();
        Object o = get(key);
        if (o != null)
        {
            try
            {
                return o instanceof Number ? ((Number) o).doubleValue() : Double.parseDouble((String) o);
            }
            catch (Exception e)
            {
                throw new JSONException("JSONObject[" + JSONUtils.quote(key) + "] is not a number.");
            }
        }
        throw new JSONException("JSONObject[" + JSONUtils.quote(key) + "] is not a number.");
 
    }
getBoolean方法會丟擲異常,如下所示:  
public boolean getBoolean(String key)
    {
        verifyIsNull();
        Object o = get(key);
        if (o != null)
        {
            if (o.equals(Boolean.FALSE) || (o instanceof String && ((String) o).equalsIgnoreCase("false")))
            {
                return false;
            }
            else 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.");
    }
JSONObject有很多optXXX方法,比如optBoolean,optString,optInt。它們的意思是,如果JsonObject有這個屬性,則返回這個屬性,否則返回一個預設值。下面以optString方法為例說明一下其底層實現過程:


    public String optString(String key)
    {
        verifyIsNull();
        return optString(key, "");
    }


    public String optString(String key, String defaultValue)
    {
        verifyIsNull();
        Object o = opt(key);
        return o != null ? o.toString() : defaultValue;
    }

相關文章