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