首页 > 编程语言 >Java JSON组成和解析

Java JSON组成和解析

时间:2024-06-17 16:54:11浏览次数:25  
标签:count Java return current JSON new position 解析

  本框架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 

 

标签:count,Java,return,current,JSON,new,position,解析
From: https://www.cnblogs.com/JuneZero/p/18252639

相关文章

  • java构造器
    构造器分为无参构造与有参构造每一个类都有一个隐藏起来的无参构造这个午餐构造没有返回值和返回类型,且方法名必须与类名相同,且必须是public1.使用new关键字必须要有构造器2.构造器用来初始化alt+insert快捷键快速创建构造器当有有参构造,却想调用无参构造时,必须有一个显示......
  • Java入门:02.java中数据的类型转换
    上两篇文章,大家了解到了常量与变量。以此为基础,我们引入了数据和数据类型的概念,今天我就和大家一起来更加深入的了解一下数据之间的类型转换吧。还是这张图,我们可以看到,各个类型之间,每个关键字所占用得内容空间大小也是各不相同的,而在Java中,一些数据类型是可以进行转换的。......
  • Linux上java-jar Spingboot项目
    百度的,后面再补一个Linux文档操作手册,是不是很大胆?准备工作1、首先得有两个软件Xftp(用来上传文件到)和XShell(连接服务器执行命令)2、Linux上有JDK(怎么安装可以转到Linux安装JDK流程)3、项目的JAR包项目jar包导jar<build><plugins><plugin><groupId......
  • Javaweb实现简易记事簿 jdbc实现Java连接数据库
    //相关代码packageUserAct;importjakarta.servlet.;importjakarta.servlet.annotation.WebServlet;importjakarta.servlet.http.;importjava.io.;importjava.sql.;//登出@WebServlet("/UserAct.DeleteEvent")publicclassDeleteEventimplementsServlet{......
  • [javascript]何为变量提升?
    【版权声明】未经博主同意,谢绝转载!(请尊重原创,博主保留追究权)https://www.cnblogs.com/cnb-yuchen/p/18252500出自【进步*于辰的博客】关于编译与解释,详述可查阅博文《[Java]知识点》中的【编译与解释】一栏。参考笔记二,P43.3、P46.1、P9.3。目录1、什么是“变量提升?2、va......
  • Java速成笔记 2024.6.17版
    变量:可以变化的容器不同变量可以存储不同类型的值变量声明方法:变量类型变量名=初始值;E.G.inta=1;变量类型:整型:intlong浮点数:floatdouble布尔:boolean字符串:String字符:char变量命名注意事项:不能重名不能以数字开头常量:关键字:final语法:finalfl......
  • 基于Java+Vue的采购管理系统:实现采购业务数字化(全套源码)
    前言:采购管理系统是一个综合性的管理平台,旨在提高采购过程的效率、透明度,并优化供应商管理。以下是对各个模块的详细解释:一、供应商准入供应商注册:供应商通过在线平台进行注册,填写基本信息和资质文件。资质审核:系统对供应商提交的资质文件进行自动或人工审核,确保供应商符......
  • JavaScript妙笔生花:打造沉浸式中国象棋游戏体验
    前言随着信息技术的飞速发展,Web开发领域也出现了翻天覆地的变化。JavaScript作为前端开发中不可或缺的编程语言,其重要性不言而喻。而当我们谈论到利用JavaScript打造一款沉浸式的中国象棋游戏体验时,我们不仅仅是在开发一个游戏,更是在进行一种文化的传承和创新。以下将探讨......
  • PTA 6-3 tjrac - Java集合类之Set的HashSet之常用方法的使用
    importjava.util.HashSet;importjava.util.Scanner;importjava.util.Set;publicclassMain{publicstaticvoidmain(String[]args){ Scannerscan=newScanner(System.in); Stringzi=scan.nextLine();//首先我们定义一个字符串输入; ......
  • PTA JAVA 7-5 sdust-Java-字符串集合求并集
    7-5sdust-Java-字符串集合求并集分数20全屏浏览切换布局作者 张峰单位 山东科技大学从键盘接收N个英文字符串(其中不同的字符串数量大于10),从头开始取5个不同的字符串放入一个集合S1,然后接着取5个不同的字符串放入另一个集合S2,按照字母顺序输出S1和S2的并集中的每个......