Java JSON組成和解析

来源:https://www.cnblogs.com/JuneZero/p/18252639
-Advertisement-
Play Games

本框架JSON元素組成和分析,JsonElement分三大類型JsonArray,JsonObject,JsonString。 JsonArray:數組和Collection子類,指定數組的話,使用ArrayList來add元素,遍歷ArrayList再使用Array.newInstance生成數組 ...


  本框架JSON元素組成和分析,JsonElement分三大類型JsonArray,JsonObject,JsonString。

  JsonArray:數組和Collection子類,指定數組的話,使用ArrayList來add元素,遍歷ArrayList再使用Array.newInstance生成數組並添加元素即可.

  JsonObject:帶有泛型的封裝類,給帶有泛型的欄位賦值,關鍵在於如何根據“指定的類型”和“Field.getGenericType”來生成新的欄位Type。

    需要你瞭解java.lang.reflect.Type的子類

    java.lang.reflect.GenericArrayType   //通用數組類型 T[]
    java.lang.reflect.ParameterizedType //參數類型,如:  java.util.List<java.lang.String>    java.util.Map<java.lang.String,java.lang.Object>
    java.lang.reflect.TypeVariable  //類型變數 K,V
    java.lang.reflect.WildcardType //通配符類,例如: ?, ? extends Number, ? super Integer

    java.lang.Class  //int.class User.class .....

  JsonString:分析字元串並解析成指定的對應類型

  下麵是本JSON框架的分析圖

 

下麵是簡陋版的解析代碼。該類沒有解析日期,數值等代碼,只是方便理解解析過程。

package june.zero.json.reader;

import java.io.IOException;
import java.io.Reader;
import java.io.StringReader;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

public class JsonSimpleParser implements CharSequence {

    public static void main(String[] args) {
        String json = "[{a:1,b:2},[1,2,3]]";
        Object obj = new JsonSimpleParser().parse(json);
        System.out.println(obj);
    }
    
    protected static final String JSON_EXTRA_CHAR_ERROR = "Extra characters exist! ";
    protected static final String JSON_OBJECT_COLON_ERROR = "Wrong format of JsonObject, no separator colon! ";
    protected static final String JSON_OBJECT_END_ERROR = "The JsonObject format must end with comma as a separator or with right curly brace! ";
    protected static final String JSON_ARRAY_END_ERROR = "The JsonArray format must end with comma as a separator or with right bracket! ";
    protected static final String JSON_STRING2_END_ERROR = "The character starts with double quotation marks, but does not end with double quotation marks! ";
    protected static final String JSON_STRING1_END_ERROR = "The character starts with single quotation marks, but does not end with single quotation marks! ";
    
    protected Reader reader;
    protected static final int capacity = 1024;
    protected final char[] cache = new char[capacity];
    protected int count;
    protected int position;
    
    public void read() throws IOException {
        this.position = 0;
        this.count = this.reader.read(this.cache,0,capacity);
    }
    
    /**
     * 當前指針指向的字元
     * @return
     */
    public char current() {
        if(this.count==-1) return '\uffff';
        return this.cache[this.position];
    }
    /**
     * 當前指針指向的索引下標
     * @return
     */
    public int position() {
        return this.position;
    }

    /**
     * 指針指向下一個字元,判斷是否需要重新讀取數據
     * @return
     * @throws IOException
     */
    public boolean nextRead() throws IOException {
        return ++this.position>=this.count;
    }
    
    /**
     * 指針指向下一個字元
     * @return
     * @throws IOException
     */
    public void next() throws IOException {
        if(++this.position>=this.count){
            this.position = 0;
            this.count = this.reader.read(this.cache,0,capacity);
        }
    }
    /**
     * 跳過空白字元
     * @throws IOException
     */
    public void skip() throws IOException {
        while(this.count!=-1&&Character.isWhitespace(this.current())){
            if(++this.position>=this.count){
                this.position = 0;
                this.count = this.reader.read(this.cache,0,capacity);
            }
        }
    }
    
    public Object parse(String json) throws RuntimeException {
        return parse(new StringReader(json));
    }
    
    /**
     * 解析
     */
    public Object parse(Reader reader) throws RuntimeException {
        try {
            this.reader = reader;
            this.read();
            Object value = parse();
            this.skip();
            if(this.count!=-1){
                throw new RuntimeException(JSON_EXTRA_CHAR_ERROR);
            }
            return value;
        } catch (Throwable e) {
            throw new RuntimeException(e);
        } finally {
            try {
                this.close();
            } catch (IOException e) {
                
            }
        }
    }
    
    protected Object parse() throws IOException {
        this.skip();
        char current = this.current();
        if(current=='{'){
            this.next();
            this.skip();
            Map<Object, Object> object = new HashMap<Object, Object>();
            if(this.current() == '}') {
                this.next();
                return object;
            }
            do{
                Object key = parse();
                this.skip();
                if(this.current()!=':'){
                    throw new RuntimeException(JSON_OBJECT_COLON_ERROR);
                }
                this.next();
                object.put(key, parse());
                this.skip();
                current = this.current();
                if(current=='}') break;
                if(current!=','){
                    throw new RuntimeException(JSON_OBJECT_END_ERROR);
                }
                this.next();
                this.skip();
            }while(true);
            this.next();
            return object;
        }
        if(current=='['){
            this.next();
            this.skip();
            List<Object> array = new ArrayList<Object>();
            if(this.current() == ']'){
                this.next();
                return array;
            }
            do{
                array.add(parse());
                this.skip();
                current = this.current();
                if(current==']') break;
                if(current!=','){
                    throw new RuntimeException(JSON_ARRAY_END_ERROR);
                }
                this.next();
                this.skip();
            }while(true);
            this.next();
            return array;
        }
        this.skip();
        StringBuilder string = new StringBuilder();
        if(current=='"'){
            this.next();
            
            int offset = this.position;
            while(this.count!=-1&& this.current()!='"'){
                if(this.nextRead()){
                    string.append(this, offset, this.position);
                    offset = 0;
                    this.position = 0;
                    this.count = this.reader.read(this.cache,0,capacity);
                }
            }
            string.append(this, offset, this.position);
            
            if(this.current()!='"'){
                throw new RuntimeException(JSON_STRING2_END_ERROR);
            }
            this.next();
            
            return string;
        }
        if(current=='\''){
            if(++this.position>=this.count){
                this.position = 0;
                this.count = this.reader.read(this.cache,0,capacity);
            }
            
            int offset = this.position;
            while(this.count!=-1&&this.current()!='\''){
                if(this.nextRead()){
                    string.append(this, offset, this.position);
                    offset = 0;
                    this.read();
                }
            }
            string.append(this, offset, this.position);
            
            if(this.current()!='\''){
                throw new RuntimeException(JSON_STRING1_END_ERROR);
            }
            this.next();
            
            return string;
        }
        
        int offset = this.position;
        while(this.count!=-1&&
                (current = this.current())!=','&&
                current!=':'&&
                current!=']'&&
                current!='}'&&
                !Character.isWhitespace(current)){
            if(this.nextRead()){
                string.append(this, offset, this.position);
                offset = 0;
                this.read();
            }
        }
        string.append(this, offset, this.position);
        return string;
    }
    
    /**
     * 關閉流
     * @throws IOException
     */
    public void close() throws IOException{
        if(this.reader!=null){
            this.reader.close();
            this.reader = null;
        }
    }
    
    @Override
    public char charAt(int index) {
        return this.cache[index];
    }
    @Override
    public int length() {
        return this.count;
    }
    @Override
    public CharSequence subSequence(int start, int end) {
        if (start < 0)
            throw new StringIndexOutOfBoundsException(start);
        if (end > count)
            throw new StringIndexOutOfBoundsException(end);
        if (start > end)
            throw new StringIndexOutOfBoundsException(end - start);
        StringBuilder string = new StringBuilder();
        for (int i = start; i < end; i++) {
            string.append(this.cache[i]);
        }
        return string;
    }
    @Override
    public String toString() {
        if(this.count<0) return null;
        return new String(this.cache,this.position,this.count-this.position);
    }
    
}

 

轉載請標明該來源。https://www.cnblogs.com/JuneZero/p/18252639

源碼和jar包及其案例:https://www.cnblogs.com/JuneZero/p/18237283 

 


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • Spring Cloud是一個相對比較成熟的微服務框架。雖然,Spring Cloud於2016年才推出1.0的release版本, 時間最短, 但是相比Dubbo等RPC框架, Spring Cloud提供的全套的分散式系統解決方案。 Spring Cloud是一系列框架的有序集合。它利用Spri ...
  • Windows應用軟體開發,會有很多常用的模塊,比如資料庫、配置文件、日誌、後臺通信、進程通信、埋點、瀏覽器等等。下麵是目前我們公司windows梳理的部分組件,梳理出來方便大家瞭解組件概念以及依賴關係: 每個應用里,現在或者以後都可能會存在這些模塊。以我團隊開發的全家桶為例,十多個應用對後臺訪問, ...
  • 通過本文我們深入瞭解了RabbitMQ的集群模式及其優缺點。無論是普通集群還是鏡像集群,都有其適用的場景和局限性。普通集群利用Erlang語言的集群能力,但消息可靠性和高可用性方面存在一定挑戰;而鏡像集群通過主動消息同步提高了消息的可靠性和高可用性,但可能會占用大量網路帶寬。因此,在選擇集群方案時,... ...
  • 寫在前面 在現目前項目開發中,一般都是前後端分離項目。前端小姐姐負責開發前端,苦逼的我們負責後端開發 事實是一個人全乾,在這過程中編寫介面文檔就顯得尤為重要了。然而作為一個程式員,最怕的莫過於自己寫文檔和別人不寫文檔 大家都不想寫文檔,那這活就交給今天的主角Swagger來實現了 一、專業名詞介紹 ...
  • 1 Zero-shot learning 零樣本學習。 1.1 任務定義 利用訓練集數據訓練模型,使得模型能夠對測試集的對象進行分類,但是訓練集類別和測試集類別之間沒有交集;期間需要藉助類別的描述,來建立訓練集和測試集之間的聯繫,從而使得模型有效。 Zero-shot learning 就是希望我們 ...
  • 本文基於 OpenJDK17 進行討論,垃圾回收器為 ZGC。 提示: 為了方便大家索引,特將在上篇文章 《以 ZGC 為例,談一談 JVM 是如何實現 Reference 語義的》 中討論的眾多主題獨立出來。 FinalReference 對於我們來說是一種比較陌生的 Reference 類型,因 ...
  • 目錄智能指針場景引入 - 為什麼需要智能指針?記憶體泄漏什麼是記憶體泄漏記憶體泄漏的危害記憶體泄漏分類如何避免記憶體泄漏智能指針的使用及原理RAII簡易常式智能指針的原理智能指針的拷貝問題智能指針的發展歷史std::auto_ptr模擬實現auto_ptr常式:這種方案存在的問題:Boost庫中的智能指針un ...
  • NumPy 助你處理數學問題:計算序列的差分用`np.diff()`,示例返回`[5, 10, -20]`;找最小公倍數(LCM)用`np.lcm()`,數組示例返回`18`;最大公約數(GCD)用`np.gcd.reduce()`,數組示例返回`4`;三角函數如`np.sin()`,`np.deg... ...
一周排行
    -Advertisement-
    Play Games
  • 前言 本文介紹一款使用 C# 與 WPF 開發的音頻播放器,其界面簡潔大方,操作體驗流暢。該播放器支持多種音頻格式(如 MP4、WMA、OGG、FLAC 等),並具備標記、實時歌詞顯示等功能。 另外,還支持換膚及多語言(中英文)切換。核心音頻處理採用 FFmpeg 組件,獲得了廣泛認可,目前 Git ...
  • OAuth2.0授權驗證-gitee授權碼模式 本文主要介紹如何筆者自己是如何使用gitee提供的OAuth2.0協議完成授權驗證並登錄到自己的系統,完整模式如圖 1、創建應用 打開gitee個人中心->第三方應用->創建應用 創建應用後在我的應用界面,查看已創建應用的Client ID和Clien ...
  • 解決了這個問題:《winForm下,fastReport.net 從.net framework 升級到.net5遇到的錯誤“Operation is not supported on this platform.”》 本文內容轉載自:https://www.fcnsoft.com/Home/Sho ...
  • 國內文章 WPF 從裸 Win 32 的 WM_Pointer 消息獲取觸摸點繪製筆跡 https://www.cnblogs.com/lindexi/p/18390983 本文將告訴大家如何在 WPF 裡面,接收裸 Win 32 的 WM_Pointer 消息,從消息裡面獲取觸摸點信息,使用觸摸點 ...
  • 前言 給大家推薦一個專為新零售快消行業打造了一套高效的進銷存管理系統。 系統不僅具備強大的庫存管理功能,還集成了高性能的輕量級 POS 解決方案,確保頁面載入速度極快,提供良好的用戶體驗。 項目介紹 Dorisoy.POS 是一款基於 .NET 7 和 Angular 4 開發的新零售快消進銷存管理 ...
  • ABP CLI常用的代碼分享 一、確保環境配置正確 安裝.NET CLI: ABP CLI是基於.NET Core或.NET 5/6/7等更高版本構建的,因此首先需要在你的開發環境中安裝.NET CLI。這可以通過訪問Microsoft官網下載並安裝相應版本的.NET SDK來實現。 安裝ABP ...
  • 問題 問題是這樣的:第三方的webapi,需要先調用登陸介面獲取Cookie,訪問其它介面時攜帶Cookie信息。 但使用HttpClient類調用登陸介面,返回的Headers中沒有找到Cookie信息。 分析 首先,使用Postman測試該登陸介面,正常返回Cookie信息,說明是HttpCli ...
  • 國內文章 關於.NET在中國為什麼工資低的分析 https://www.cnblogs.com/thinkingmore/p/18406244 .NET在中國開發者的薪資偏低,主要因市場需求、技術棧選擇和企業文化等因素所致。歷史上,.NET曾因微軟的閉源策略發展受限,儘管後來推出了跨平臺的.NET ...
  • 在WPF開發應用中,動畫不僅可以引起用戶的註意與興趣,而且還使軟體更加便於使用。前面幾篇文章講解了畫筆(Brush),形狀(Shape),幾何圖形(Geometry),變換(Transform)等相關內容,今天繼續講解動畫相關內容和知識點,僅供學習分享使用,如有不足之處,還請指正。 ...
  • 什麼是委托? 委托可以說是把一個方法代入另一個方法執行,相當於指向函數的指針;事件就相當於保存委托的數組; 1.實例化委托的方式: 方式1:通過new創建實例: public delegate void ShowDelegate(); 或者 public delegate string ShowDe ...