Java JSON组成和解析

java,json · 浏览次数 : 0

小编点评

本文主要介绍了一个简化的JSON解析框架,该框架能够解析JSON格式的数据,并将其转换成Java对象。文章首先介绍了JSON元素的三种类型:JsonArray、JsonObject和JsonString,然后详细阐述了如何解析每种类型的JSON数据。 1. **JsonArray**:表示一个数组,可以使用ArrayList来存储元素,并通过Array.newInstance生成数组。 - 创建数组对象 - 使用ArrayList添加元素 - 遍历数组 2. **JsonObject**:表示一个JSON对象,包含泛型字段。 - 获取泛型字段类型 - 生成新的字段类型 - 给泛型字段赋值 3. **JsonString**:表示一个JSON字符串,可以解析成指定的对应类型。 - 分析字符串 - 解析成指定类型 文章还提供了一个简陋版的解析代码示例,用于演示如何解析包含数字、字符串和对象的JSON数据。 总的来说,这个简化的JSON解析框架为开发者提供了一种方便的方式来处理和分析JSON格式的数据,并将其转换为Java对象。

正文

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

 

与Java JSON组成和解析相似的内容:

Java JSON组成和解析

本框架JSON元素组成和分析,JsonElement分三大类型JsonArray,JsonObject,JsonString。 JsonArray:数组和Collection子类,指定数组的话,使用ArrayList来add元素,遍历ArrayList再使用Array.newInstance生成数组

Android 序列化框架 Gson 原理分析,可以优化吗?

本文已收录到 AndroidFamily,技术和职场问题,请关注公众号 [彭旭锐] 提问。 前言 大家好,我是小彭。 Gson 是 Google 推出的 Java Json 解析库,具有接入成本低、使用便捷、功能扩展性良好等优点,想必大家都很熟悉了。在这篇文章里,我们将讨论 Gson 的基本用法和以

java与es8实战之六:用JSON创建请求对象(比builder pattern更加直观简洁)

向ES发送请求时,如何创建请求对象呢?官方推荐的builder patter,在面对复杂的请求对象结构时还好用吗?有没有更加直观简洁的方法,尽在本文一网打尽

Java开发如何通过IoT边缘ModuleSDK进行协议转换?

摘要:使用ModuleSDK开发插件应用,接入其他协议设备(如HTTP请求数据),将其他协议的数据转化为MQTT协议JSON数据上报到IoTDA。 本文分享自华为云社区《【华为云IoTEdge开发实战】Java开发如何通过IoT边缘ModuleSDK进行协议转换》,作者: 华为IoT云服务 。 操作

简单易懂的JSON框架

分享一个由本人编写的JSON框架。 JSON反序列化使用递归方式来解析JSON字符串,不使用任何第三方JAR包,只使用JAVA的反射来创建对象(必须要有无参构造器),赋值,编写反射缓存来提升性能。支持复杂的泛型类型,数组类型等所有类型。(不支持高版本JDK1.8以上的日期类型,如LocalDate,

[转帖]ELKStack入门篇(二)之Nginx、Tomcat、Java日志收集以及TCP收集日志使用

https://www.cnblogs.com/linuxk/p/9273160.html 1、收集Nginx的json格式日志 1.1、Nginx安装 View Code 1.2、配置logstash [root@linux-node1 ~]# vim /etc/logstash/conf.d/n

ElasticSearch 实现分词全文检索 - Java SpringBoot ES 文档操作

//准备一个Request对象 IndexRequest request = new IndexRequest(indexName); request.id(person.getId().toString()); //手动指定ID request.source(personJson, XContentType.JSON); //通过 Client 对象执行

每日一库:使用Viper处理Go应用程序的配置

在开发Go应用程序时,处理配置是一个常见的需求。配置可能来自于配置文件、环境变量、命令行参数等等。Viper是一个强大的库,可以帮助我们处理这些配置。 什么是Viper? Viper是一个应用程序配置解决方案,用于Go应用程序。它支持JSON、TOML、YAML、HCL、envfile和Java p

Java 方法中循环调用具有事务的方法

本文简要介绍了Java 方法中循环调用具有事务的具体方法示例,虽然@Transactional是Spring中最常用和推荐的方式,但是本文还简要介绍了其他5种方法可以实现类似的功能。

Java基础:线程的三种创建方式

一、继承Thread类 定义一个类继承线程类Thread 重写run()方法 创建线程对象 调用线程对象的start()方法创建线程 Thread类的常用API setName(String name):给线程取名字 getName():获取线程的名字 public static Thread cu