2013年1月20日 星期日

[ Java 套件 ] JSON-lib - How to use json-lib


參考自 這裡
Preface:
最近要把視窗程式轉為 Web 介面的網頁, 因為該視窗程式包含蠻多服務, 所以想把 local 端的服務改成遠端呼叫的 web service. 如此該 Web 程式就可以專職顯示與人機互動. (即 MVC 中的 V=View). 在考慮 web service 間溝通的傳輸協定打算使用 json 格式, 故 survey 到 JSON-lib 這套 Java 的套件. 它的好處是可以直接將你已經用 Java 建立的物件 (map, bean etc) 直接轉為 json, 省掉你自己 coding 在 Java 世界與 json 世界中的轉換代碼, 相當方便. 下面將舉幾個範例提供後續使用參考.

Dependency and transformation limitation:
你要是用 JSON-lib 可以到 這裡下載 library, 但使用該 library 有下面相依性也要一併加入 classpath:
jakarta commons-lang 2.5
The standard Java libraries fail to provide enough methods for manipulation of its core classes. Apache Commons Lang provides these extra methods...

jakarta commons-beanutils 1.8.0
Most Java developers are used to creating Java classes that conform to the JavaBeans naming patterns for property getters and setters. It is natural to then access these methods directly, using calls to the corresponding getXxx and setXxx methods. However, there are some occasions where dynamic access to Java object properties (without compiled-in knowledge of the property getter and setter methods to be called) is needed...

jakarta commons-collections 3.2.1
The Java Collections Framework was a major addition in JDK 1.2. It added many powerful data structures that accelerate development of most significant Java applications. Since that time it has become the recognised standard for collection handling in Java...

jakarta commons-logging 1.1.1
When writing a library it is very useful to log information. However there are many logging implementations out there, and a library cannot impose the use of a particular one on the overall application that the library is a part of...

ezmorph 1.0.6
EZMorph is simple java library for transforming an Object to another Object...

需要注意的是上面對應的版本訊息, 如果你使用太新的版本, 可能會有不相容的問題.

再來是可以從 Java 世界到 json 世界的物件也不是每個都可以, 下面有個清單說明那些物件可以自由在兩端轉換:


接著就來看一些範例.

Working with arrays and collections:
首先我們要來看看如何在 Java 世界將 Collections 如 array 轉為 JSONArray 物件. 很直覺的是直接呼叫 JSONArray.fromObject() 方法就搞定:
  1. package demo;  
  2.   
  3. import java.util.ArrayList;  
  4. import java.util.List;  
  5.   
  6. import net.sf.json.JSONArray;  
  7.   
  8. public class Ex1 {  
  9.     public static void main(String[] args) {  
  10.         // 1.1) 建立 array  
  11.         boolean[] boolArray = new boolean[]{true,false,true};  
  12.         // 1.2) 轉換 Java 世界的 array 到  JSON 世界的 JSONArray  
  13.         JSONArray jsonArray = JSONArray.fromObject(boolArray);  
  14.         // 1.3) 檢查結果   
  15.         System.out.printf("\t[Info] jsonArray=%s\n", jsonArray);  // prints [true,false,true]   
  16.   
  17.         // 2.1) 建立 List 物件並添加元素.  
  18.         List list = new ArrayList();    
  19.         list.add( "first" );    
  20.         list.add( "second" );    
  21.         // 2.2) 轉換 Java 世界的 List 到 JSON 世界的 JSONArray  
  22.         JSONArray jsonArray2 = JSONArray.fromObject( list );    
  23.         // 2.3) 檢查結果  
  24.         System.out.printf("\t[Info] jsonArray2=%s\n", jsonArray2); // prints ["first","second"]      
  25.       
  26.         // 3.1) 透過 JSON 字串建立 JSONArray 物件.  
  27.         JSONArray jsonArray3 = JSONArray.fromObject( "['json','is','easy']" );  
  28.         // 3.2) 檢查結果  
  29.         System.out.printf("\t[Info] jsonArray3=%s\n", jsonArray3);   // prints ["json","is","easy"]           
  30.     }  
  31. }  
執行結果:
[Info] jsonArray=[true,false,true]
[Info] jsonArray2=["first","second"]
[Info] jsonArray3=["json","is","easy"]

From Beans & Maps to JSON:
如果是 key/value pairs 的形式, 則可以參考下面將 java 世界中的 Map 轉為 JSON 世界的 JSONObject 物件. 透過方法 JSONObject.fromObject() 可以完成這個轉換, 甚至你可以將自製的類別傳入該方法, 它會透過反射取出 getter/setter 對應的 key/value pairs 幫你生成對應 JSONObject:
  1. package demo;  
  2.   
  3. import java.util.List;  
  4. import java.util.ArrayList;  
  5. import java.util.HashMap;  
  6. import java.util.Map;  
  7.   
  8. import net.sf.json.JSONFunction;  
  9. import net.sf.json.JSONObject;  
  10.   
  11. public class Ex2 {  
  12.     public static class MyBean  
  13.     {  
  14.         private String name = "json";    
  15.         private int pojoId = 1;    
  16.         private char[] options = new char[]{'a','f'};    
  17.         private String func1 = "function(i){ return this.options[i]; }";    
  18.         private JSONFunction func2 = new JSONFunction(new String[]{"i"},"return this.options[i];");  
  19.         private List choices = new ArrayList();  
  20.           
  21.         public MyBean()  
  22.         {  
  23.             choices.add("Choice1");  
  24.             choices.add("Choice2");  
  25.         }  
  26.         public MyBean(String name, int pid, char[] opts, String func1, JSONFunction func2, List choices)  
  27.         {  
  28.             this.name = name;  
  29.             this.pojoId = pid;  
  30.             this.options = opts;  
  31.             this.func1 = func1;  
  32.             this.func2 = func2;           
  33.             this.choices = choices;  
  34.         }                 
  35.           
  36.         public String getName() {  
  37.             return name;  
  38.         }  
  39.         public void setName(String name) {  
  40.             this.name = name;  
  41.         }  
  42.         public int getPojoId() {  
  43.             return pojoId;  
  44.         }  
  45.         public void setPojoId(int pojoId) {  
  46.             this.pojoId = pojoId;  
  47.         }  
  48.         public char[] getOptions() {  
  49.             return options;  
  50.         }  
  51.         public void setOptions(char[] options) {  
  52.             this.options = options;  
  53.         }  
  54.         public String getFunc1() {  
  55.             return func1;  
  56.         }  
  57.         public void setFunc1(String func1) {  
  58.             this.func1 = func1;  
  59.         }  
  60.         public JSONFunction getFunc2() {  
  61.             return func2;  
  62.         }  
  63.         public void setFunc2(JSONFunction func2) {  
  64.             this.func2 = func2;  
  65.         }  
  66.         public List getChoices() {  
  67.             return choices;  
  68.         }  
  69.         public void setChoices(List choices) {  
  70.             this.choices = choices;  
  71.         }                 
  72.     }  
  73.   
  74.     public static void main(String[] args) {  
  75.         Map map = new HashMap();    
  76.         map.put( "name""json" );    
  77.         map.put( "bool", Boolean.TRUE );    
  78.         map.put( "int"new Integer(1) );    
  79.         map.put( "arr"new String[]{"a","b"} );    
  80.         map.put( "func""function(i){ return this.arr[i]; }" );    
  81.             
  82.         // 1) 轉換 Java 世界的 Map 物件到 JSON 世界的 JSONObject 物件.  
  83.         JSONObject jsonObject = JSONObject.fromObject(map);    
  84.         System.out.printf("\t[Info] jsonObject=%s\n", jsonObject);    
  85.   
  86.         // 2) 轉換 Java 世界的 Bean 物件到 JSON 世界的 JSONObject 物件.  
  87.         JSONObject jsonObject2 = JSONObject.fromObject(new MyBean());    
  88.         System.out.printf("\t[Info] jsonObject2=%s\n", jsonObject2);          
  89.     }  
  90.   
  91. }  
執行結果:
[Info] jsonObject={"arr":["a","b"],"int":1,"name":"json","func":function(i){ return this.arr[i]; },"bool":true}
[Info] jsonObject2={"choices":["Choice1","Choice2"],"func1":function(i){ return this.options[i]; },...,"options":["a","f"],"pojoId":1}

From JSON to Beans:
既然能從 Java 世界轉換到 JSON 世界, 自然也能從 JSON 世界轉換回來 Java 世界. 可以透過 JSONObject.toBean() 方法完成 JSONObject->DynaBean 轉換:
  1. package demo;  
  2.   
  3. import static org.junit.Assert.assertEquals;  
  4. import java.util.List;  
  5. import net.sf.json.JSONArray;  
  6. import net.sf.json.JSONObject;  
  7. import org.apache.commons.beanutils.PropertyUtils;  
  8. import org.junit.Test;  
  9. import demo.Ex2.MyBean;  
  10.   
  11. public class Ex3 {  
  12.     public static class MyBean  
  13.     {  
  14.         private String name = "name";  
  15.         private int id = 1;  
  16.         public String getName() {  
  17.             return name;  
  18.         }  
  19.         public void setName(String name) {  
  20.             this.name = name;  
  21.         }  
  22.         public int getId() {  
  23.             return id;  
  24.         }  
  25.         public void setId(int id) {  
  26.             this.id = id;  
  27.         }     
  28.           
  29.         @Override  
  30.         public boolean equals(Object o)  
  31.         {  
  32.             if(o instanceof MyBean)  
  33.             {  
  34.                 MyBean bean = (MyBean)o;  
  35.                 if(bean.name.equals(name) && bean.id == id) return true;  
  36.             }  
  37.             return false;  
  38.         }  
  39.     }  
  40.   
  41.     @Test  
  42.     public void test() throws Exception{  
  43.         // 1) Convert to DynaBean:  
  44.         String json = "{name=\"json\",bool:true,int:1,double:2.2,func:function(a){ return a; },array:[1,2]}";    
  45.         JSONObject jsonObject = JSONObject.fromObject(json);    
  46.         Object bean = JSONObject.toBean( jsonObject );    
  47.         assertEquals( jsonObject.get( "name" ), PropertyUtils.getProperty( bean, "name" ) );    
  48.         assertEquals( jsonObject.get( "bool" ), PropertyUtils.getProperty( bean, "bool" ) );    
  49.         assertEquals( jsonObject.get( "int" ), PropertyUtils.getProperty( bean, "int" ) );    
  50.         assertEquals( jsonObject.get( "double" ), PropertyUtils.getProperty( bean, "double" ) );    
  51.         assertEquals( jsonObject.get( "func" ), PropertyUtils.getProperty( bean, "func" ) );    
  52.         List expected = JSONArray.toList( jsonObject.getJSONArray( "array" ) );           
  53.         assertEquals("List size=2"2, expected.size());  
  54.           
  55.         // 2) Convert to MyBean:  
  56.         MyBean bean2 = new MyBean();    
  57.         JSONObject jsonObject2 = JSONObject.fromObject(bean2);  
  58.         MyBean tbean = (MyBean)JSONObject.toBean(jsonObject2, MyBean.class);  
  59.         assertEquals(bean2, tbean);       
  60.     }  
  61. }  
上面使用 JUnit4 撰寫 TestCase, 執行結果應該 All-pass. 有了以上的說明與範例, 相信接下來應用應該就不成問題, 更多的使用與教學可以參考 這裡.

Supplement:
JUnit4 Annotations : Test Examples and Tutorial
JUnit4 Annotations are single big change from JUnit 3 to JUnit 4 which is introduced in Java 5. With annotations creating and running a JUnit test becomes more easy and more readable, but you can only take full advantage of JUnit4 if you know the correct meaning of annotations used on this version and how to use them while writing tests...

JSON in Java
Here provides briefly review on each classes you may used in JSON-lib...

Blog of toright> Java JSON API 教學 – Json-lib
JSON為輕量級的資料表示格式,比起 XML 鬆散許多且不需要定義描述檔,JSON網站 http://json.org/ ...
This message was edited 20 times. Last update was at 21/01/2013 14:10:34

沒有留言:

張貼留言

[Git 常見問題] error: The following untracked working tree files would be overwritten by merge

  Source From  Here 方案1: // x -----删除忽略文件已经对 git 来说不识别的文件 // d -----删除未被添加到 git 的路径中的文件 // f -----强制运行 #   git clean -d -fx 方案2: 今天在服务器上  gi...