程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> JAVA編程 >> JAVA綜合教程 >> [Java]簡單的JSON庫(重復造輪子系列),json輪子

[Java]簡單的JSON庫(重復造輪子系列),json輪子

編輯:JAVA綜合教程

[Java]簡單的JSON庫(重復造輪子系列),json輪子


話說好久沒更新這個博客了

都快忘記還有博客這件事了....

因為之前在造一個簡單的HTTP框架的輪子,裡面用了JSON...當時隨便拉了個FastJSON的庫就用了,然而...嗯,毫無疑問,輪子還是要自己造才好玩,雖然不會在生產環境用,但是寫和不寫多少還是有些差距的

於是今天就造了這個簡單的JSON庫輪子,實現了FastJSON裡最常用的toJSON和fromJSON功能,支持Map List Array BeanObject 的JSON文本轉換,JSON文本解析的話只實現了到Map和List的解析...BeanObject懶得寫了,等以後輪子的坑造完了完善後再一起丟到Github玩好了

 

總之簡單的放一下這個毫無效率的MyJSON代碼,為了實現簡單各種遞歸應該不復雜,至於兼容性...不知道,沒測試多少測試用例,如果有BUG歡迎評論反饋(循環引用會導致生成json文本死循環,對此並不打算修復...嗯,說到底JSON裡我怎麼才能表示的出循環引用啊

 

對了,寫這個的時候完全沒有參考JSON規范....全靠自己對JSON的理解強行撸出來的,如果有不符合規范的地方歡迎指正QwQ

 

從對象生成JSON(所有的包引用就不貼了)

  1     /**
  2      * 根據對象封裝到JSON文本,支持Map,List和Bean對象,如果鍵是一個對象,那麼需要自行重寫toString
  3      * @param object
  4      * @return
  5      */
  6     public static String toJSON(Object object){
  7         StringBuffer jsonString = new StringBuffer();
  8         if (object instanceof Map){
  9             getMapObjectText(jsonString,object);
 10         }else if(object instanceof List || object.getClass().isArray()){
 11             getListObjectText(jsonString,object);
 12         }else{
 13             getBeanObjectText(jsonString,object);
 14         }
 15         return jsonString.toString();
 16     }
 17     //從Object中解析並生成JSON字符串,如果無法作為Java Bean解析,則直接toString輸出文本
 18     private static void getBeanObjectText(StringBuffer json,Object object) {
 19         int i = 0;
 20         try{
 21             Class c = object.getClass();
 22             Field[] fields = c.getDeclaredFields();
 23             for(Field field : fields){
 24                 PropertyDescriptor pd = new PropertyDescriptor(field.getName(), c);
 25                 Method getMethod = pd.getReadMethod();
 26                 Object value = getMethod.invoke(object);
 27                 if (i++ == 0)
 28                     json.append("{");
 29                 else
 30                     json.append(",");
 31                 json.append("\"").append(field.getName()).append("\":");
 32                 getValueText(json, value);
 33             }
 34         }catch(Exception e){}
 35         if (i != 0)
 36             json.append("}");
 37         else
 38             json.append("\"").append(object.toString()).append("\"");
 39     }
 40     //從Map中解析並生產JSON字符串
 41     private static void getMapObjectText(StringBuffer json,Object object){
 42         Map<Object,Object> map = (Map)object;
 43         json.append("{");
 44         int i = 0;
 45         for(Entry entry : map.entrySet()){
 46             if (entry.getKey() != null){
 47                 if (i++ != 0){
 48                     json.append(",");
 49                 }
 50                 json.append("\"").append(entry.getKey().toString()).append("\":");
 51                 getValueText(json, entry.getValue());
 52             }
 53         }
 54         json.append("}");
 55     }
 56     //從List或者Arrays中解析並生成JSON字符串
 57     private static void getListObjectText(StringBuffer json,Object object){
 58         json.append("[");
 59         List list = null;
 60         if(object.getClass().isArray()){
 61             list = Arrays.asList((Object[])object);
 62         }
 63         if (list == null)
 64             list = (List)object;
 65         int i = 0;
 66         for(Object value : list){
 67             if (i++ != 0)
 68                 json.append(",");
 69             getValueText(json,  value);
 70         }
 71         json.append("]");
 72     }
 73     //獲取value的值並寫入json字符串中
 74     private static void getValueText(StringBuffer json,Object value){
 75         if (value == null){
 76             json.append("null");
 77             return;
 78         }
 79         if (value instanceof String)//基本數據類型處理
 80             json.append("\"").append(encoderJsonText(value.toString())).append("\"");
 81         else if(value instanceof Integer)
 82             json.append(((Integer) value).intValue());
 83         else if(value instanceof Boolean)
 84             json.append(((Boolean) value).booleanValue());
 85         else if(value instanceof Character)
 86             json.append("\"").append(value.toString()).append("\"");
 87         else if(value instanceof Long)
 88             json.append(((Long) value).longValue());
 89         else if(value instanceof Double)
 90             json.append(((Double) value).doubleValue());
 91         else if(value instanceof Float)
 92             json.append(((Float) value).floatValue());
 93         else if(value instanceof Map)//Map List Arrays Bean遞歸處理
 94             getMapObjectText(json,value);
 95         else if(value instanceof List || value.getClass().isArray())
 96             getListObjectText(json,value);
 97         else
 98             getBeanObjectText(json, value);
 99     }
100     //對JSON中的文字進行編碼轉換,主要是"換行等符號的轉義
101     private static String encoderJsonText(String s){
102         s = s.replace("\"", "\\\"");
103         s = s.replace("\\", "\\\\");
104         s = s.replace("\n", "\\\n");
105         return s;
106     }

使用方法(Bean對象請自行腦補)

 1         TestBean bean = new TestBean();
 2         bean.setBean1("Stri\"ngTe[]}xt");
 3         bean.setBeanBool(true);
 4         bean.setBeanFloat((float)3.14);
 5         bean.setBeanInt(233);
 6         Map<String,Object> map = new HashMap<>();
 7         map.put("test", "a");
 8         map.put("test2", 0);
 9         map.put("test3", new Object());
10         Map<String,Object> map2 = new HashMap<>();
11         map2.put("map2", "qwq");
12         Object[] array = new Object[]{"1","2",map2};
13         bean.setBeanMap(map);
14         bean.setBeanList(Arrays.asList(array));
15         System.out.println(MyJSON.toJSON(bean));

 

接下來上JSON解析代碼,思路和上面一樣,全靠遞歸簡化

  1     private final static char[] BLANKLIST = new char[]{' ','\t','\r','\n'};//空白字符
  2     private final static char[] LISTENDS = new char[]{',',']'};//LIST結束字符
  3     private final static char[] MAPENDS = new char[]{',','}'};//MAP結束字符
  4     private final static char[] COLONCHAR = new char[]{':'};//冒號CHAR
  5     private final static char[] QUOTESCHAR = new char[]{'"'};//引號CHAR
  6     
  7     /**
  8      * 解析JSON並返回解析結果,如果是鍵值對則封裝成Map,如果是有序集合則封裝成List
  9      * @param json
 10      * @return
 11      */
 12     public static Object fromJSON(String json){
 13         json = json.trim();
 14         if (json.startsWith("{"))
 15             return getMapObjectFromJson(json, new int[]{1});
 16         else if (json.startsWith("["))
 17             return getListObjectFromJson(json, new int[]{1});
 18         else
 19             throw new IllegalArgumentException("開頭不是{或者[");
 20     }
 21     //根據JSON文本封裝成Map,pos為當前處理位置
 22     private static Map getMapObjectFromJson(String json,int[] pos){
 23         Map<String,Object> resultMap = new HashMap<>();
 24         while(pos[0] < json.length()){
 25             //跳到第一個"
 26             jumpCharByChars(json, pos, QUOTESCHAR);
 27             //取到下一個"為止是key
 28             String key = getCharsByEnds(json, pos, QUOTESCHAR);
 29             pos[0]++;//跳過"符號
 30             //跳到中間分割字符:
 31             jumpCharByChars(json, pos, COLONCHAR);
 32             //跳到下一個非空值為止
 33             jumpCharByChars(json,pos,null);
 34             pos[0]--;//調回非空值第一個數據
 35             char c = json.charAt(pos[0]);
 36             if (c == '{'){//是一個嵌套Map
 37                 pos[0]++;//跳過{符號
 38                 resultMap.put(key, getMapObjectFromJson(json, pos));
 39             }else if(c == '['){//是一個嵌套List
 40                 pos[0]++;//跳過[符號
 41                 resultMap.put(key, getListObjectFromJson(json, pos));
 42             }else if(c == '"'){//文本值處理
 43                 pos[0]++;
 44                 String value = getCharsByEnds(json, pos, QUOTESCHAR);
 45                 pos[0]++;
 46                 resultMap.put(key, decoderJsonText(value));
 47             }else{//其他格式處理
 48                 String value = getCharsByEnds(json, pos, MAPENDS);
 49                 resultMap.put(key, getTextValue(value));
 50             }
 51             if (isEnds(json,pos))//是否結束
 52                 return resultMap;
 53         }
 54         throw new IllegalArgumentException("異常的結尾,請檢查JSON字符串是否完整");
 55     }
 56     //根據JSON中的文本值獲取對應實例(主要是int bool null三種特殊值)
 57     private static Object getTextValue(String s){
 58         s = s.trim();
 59         if ("true".equals(s))
 60             return true;
 61         if ("false".equals(s))
 62             return false;
 63         if ("null".equals(s))
 64             return null;
 65         if (s.indexOf(".")==-1){
 66             try{
 67                 return Integer.parseInt(s);
 68             }catch(NumberFormatException e){
 69                 return Long.parseLong(s);
 70             }
 71         }else{
 72             try{
 73                 return Float.parseFloat(s);
 74             }catch(NumberFormatException e){
 75                 return Double.parseDouble(s);
 76             }
 77         }
 78     }
 79     //根據JSON文本封裝成List,pos為當前處理位置
 80     private static List getListObjectFromJson(String json,int[] pos){
 81         List<Object> resultList = new ArrayList<>();
 82         while(pos[0] < json.length()){
 83             jumpCharByChars(json, pos, null);
 84             pos[0]--;
 85             char c = json.charAt(pos[0]);
 86             if (c == '{'){
 87                 pos[0]++;
 88                 resultList.add(getMapObjectFromJson(json, pos));
 89             }else if (c == '['){
 90                 pos[0]++;
 91                 resultList.add(getListObjectFromJson(json, pos));
 92             }else if (c == '"'){
 93                 pos[0]++;
 94                 String value = getCharsByEnds(json, pos, QUOTESCHAR);
 95                 pos[0]++;
 96                 resultList.add(decoderJsonText(value));
 97             }else{
 98                 String value = getCharsByEnds(json, pos, LISTENDS);
 99                 resultList.add(getTextValue(value));
100             }
101             if (isEnds(json,pos))
102                 return resultList;
103         } 
104         throw new IllegalArgumentException("異常的結尾,請檢查JSON字符串是否完整");
105     }
106     //判斷是否結束
107     private static boolean isEnds(String json,int[] pos){
108         int i = pos[0];
109         while(i < json.length()){
110             char c = json.charAt(i++);
111             if (!isBlank(c)){
112                 if (c == '}' || c == ']'){
113                     pos[0] = i;
114                     return true;
115                 }else if (c == ','){
116                     pos[0] = i;
117                     return false;
118                 }else
119                     throw new IllegalArgumentException("未知的字符[" + c + "],在"+i+"位置");
120             }
121         }
122         throw new IllegalArgumentException("異常的結尾,請檢查JSON字符串是否完整");
123     }
124     //根據chars跳過一定數量的位置,如果遇到非空且不在chars中的字符則拋出異常
125     private static void jumpCharByChars(String json,int[] pos,char[] chars){
126         while(pos[0] < json.length()){
127             char c = json.charAt(pos[0]);
128             if (!isBlank(c)){
129                 if (charInChars(c,chars))
130                     break;
131                 throw new IllegalArgumentException("未知的字符[" + c + "],在"+pos[0]+"位置");
132             }
133             pos[0]++;
134         }
135         pos[0]++;
136         if (pos[0] > json.length())
137             throw new IllegalArgumentException("異常的結尾,請檢查JSON字符串是否完整");
138     }
139     //根據ends來獲取ends前的所有內容文本,轉義字符完整輸出不作處理
140     private static String getCharsByEnds(String json,int[] pos,char[] ends){
141         CharArrayWriter out = new CharArrayWriter(1);
142         while(pos[0] < json.length()){
143             char c = json.charAt(pos[0]);
144             if (c == '\\'){
145                 out.write(c);
146                 out.write(json.charAt(++pos[0]));
147             }else if(charInChars(c,ends)){
148                 break;
149             }else{
150                 out.write(c);
151             }
152             pos[0]++;
153         }
154         if (pos[0]+1 > json.length())
155             throw new IllegalArgumentException("異常的結尾,請檢查JSON字符串是否完整");
156         String result = null;
157         result = new String(out.toCharArray());
158         out.close();
159         return result;
160     }
161     //檢測字符是不是在字符數組中
162     private static boolean charInChars(char c,char[] chars){
163         if (chars == null)
164             return true;
165         for(char cc : chars)
166             if (cc == c)
167                 return true;
168         return false;
169     }
170     //檢測字符是不是空白
171     private static boolean isBlank(char s){
172         for(char c : BLANKLIST)
173             if (s == c)
174                 return true;
175         return false;
176     }
177     //解碼JSON文本,主要是對轉義字符的解釋
178     private static String decoderJsonText(String s){
179         s = s.replace("\\\"", "\"");
180         s = s.replace("\\\\", "\\");
181         s = s.replace("\\\n", "\n");
182         return s;
183     }

使用方法

1 public void test(){
2     Map m = (Map)MyJSON.fromJSON("{\"test\":[{\"test\":2},{\"test2\":[1,2,3]}]}");
3     System.out.print(m);
4 }

 

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved