Java JSON组成和解析

JuneZero 2024-06-17 17:39:00 阅读 87

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



声明

本文内容仅代表作者观点,或转载于其他网站,本站不以此文作为商业用途
如有涉及侵权,请联系本站进行删除
转载本站原创文章,请注明来源及作者。