Score
0
Watch 26 Star 103 Fork 14

calvinwilliams / okjsonJavaApache-2.0

Join us
Explore and code with more than 5 million developers,Free private repositories !:)
Sign up
JAVA编写的小巧、高效、灵活的JSON处理器(JSON解析器+JSON生成器) spread retract

Clone or download
Loading...
README.md

okjson - A small efficient flexible JSON parser/generator for Java

1. Overview

okjson is A small efficient flexible JSON parser/generator for Java

2. A demo

2.1. Write json file

demo.json

{
	"userName" : "Calvin" ,
	"email" : "calvinwilliams@163.com" ,
	"userExtInfo" : {
		"gender" : "M" ,
		"age" : 30 ,
		"address" : "I won't tell you"
	} ,
	"interestGroupList" : [
		"Programing", "Playing game", "Reading", "Sleeping"
	] ,
	"borrowDetailList" : [
		{
			"bookName" : "Thinking in JAVA" ,
			"author" : "Bruce Eckel" ,
			"borrowDate" : "2014-01-02" ,
			"borrowTime" : "17:30:00"
		} ,
		{
			"bookName" : "Thinking in C++" ,
			"author" : "Bruce Eckel too" ,
			"borrowDate" : "2014-02-04" ,
			"borrowTime" : "17:35:00"
		} ,
		{
			"bookName" : "Thinking in okjson" ,
			"author" : "It's me !!!" ,
			"borrowDate" : "2014-03-06" ,
			"borrowTime" : "17:40:00"
		}
	]
}

2.2. Write mapping class file

DemoUserClass.java

package xyz.calvinwilliams.okjson;

import java.time.LocalDate;
import java.time.LocalTime;
import java.util.LinkedList;

public class DemoUserClass {
	String				userName ;
	String				email ;
	UserExtInfo			userExtInfo ;
	LinkedList<String>			interestGroupList ;
	LinkedList<BorrowDetail>	borrowDetailList ;
}

class UserExtInfo {
	String				gender ;
	int					age ;
	String				address ;
}

class BorrowDetail {
	String				bookName ;
	String				author ;
	@OkJsonDateTimeFormatter(format="yyyy-MM-dd")
	LocalDate			borrowDate ;
	@OkJsonDateTimeFormatter(format="HH:mm:ss")
	LocalTime			borrowTime ;
}

2.3. Write demo

package xyz.calvinwilliams.okjson;

import java.time.format.DateTimeFormatter;

public class Demo {

	public static void printDemoUser( DemoUserClass demoUser ) {
		...
	}
	
	public static void main(String[] args) {
		DemoUserClass	demoUser = new DemoUserClass() ;
		
		System.out.println( "OKJSON.stringToObject ..." );
		demoUser = OKJSON.fileToObject( "demo.json", DemoUserClass.class, OKJSON.OKJSON_OTIONS_DIRECT_ACCESS_PROPERTY_ENABLE ) ;
		if( demoUser == null ) {
			System.out.println( "OKJSON.stringToObject failed["+OKJSON.getErrorCode()+"]["+OKJSON.getErrorDesc()+"]" );
			return;
		} else {
			System.out.println( "OKJSON.stringToObject ok" );
			printDemoUser( demoUser );
		}
	}
}

3. Refenence

3.1. Static mathod

3.1.1. OKJSON.getErrorCode

Prototype Integer getErrorCode();

3.1.2. OKJSON.getErrorDesc

Prototype String getErrorDesc();

3.1.3. OKJSON.stringToObject

Prototype T stringToObject( String jsonString, Class clazz, int options );

options
OKJSON.OPTIONS_DIRECT_ACCESS_PROPERTY_ENABLE
OKJSON.OPTIONS_STRICT_POLICY

errcode
OKJSON_ERROR_END_OF_BUFFER
OKJSON_ERROR_UNEXPECT
OKJSON_ERROR_EXCEPTION
OKJSON_ERROR_INVALID_BYTE
OKJSON_ERROR_FIND_FIRST_LEFT_BRACE
OKJSON_ERROR_NAME_INVALID
OKJSON_ERROR_EXPECT_COLON_AFTER_NAME
OKJSON_ERROR_UNEXPECT_TOKEN_AFTER_LEFT_BRACE
OKJSON_ERROR_PORPERTY_TYPE_NOT_MATCH_IN_OBJECT
OKJSON_ERROR_NAME_NOT_FOUND_IN_OBJECT
OKJSON_ERROR_NEW_OBJECT

3.1.4. OKJSON.fileToObject

Prototype T fileToObject( String filePath, Class clazz, int options );

3.1.5. OKJSON.objectToString

Prototype String objectToString( Object object, int options );

options
OKJSON.OPTIONS_DIRECT_ACCESS_PROPERTY_ENABLE
OKJSON.OPTIONS_PRETTY_FORMAT_ENABLE

errcode
OKJSON_ERROR_END_OF_BUFFER
OKJSON_ERROR_EXCEPTION
OKJSON_ERROR_NEW_OBJECT

3.1.6. OKJSON.objectToFile

Prototype int objectToFile( Object object, String filePath, int options );

3.2. JSON element value mapping JAVA class/type

JSON element value JAVA class/type
"..." String
123 Byte或byte
123 Short或short
123 Integer或int
123 Long或long
123.456 Float或float
123.456 Double或double
true/false Boolean或boolean
"..." LocalDate
"..." LocalTime
"..." LocalDateTime
[...] ArrayList
[...] LinkedList
{...} JAVA对象

3.3. JSON array simple-value mapping JAVA class/type

JSON array simple-value JAVA class/type
"..." String
123 Byte
123 Short
123 Integer
123 Long
123.456 Float
123.456 Double
true/false Boolean
"..." LocalDate
"..." LocalTime
"..." LocalDateTime
{...} JAVA对象

3. Benchmark

CPU : Intel Core i5-7500 3.4GHz 3.4GHz Momey : 16GB OS : WINDOWS 10 JAVA IDE : Eclipse 2018-12

press.json

{
	"str1" : "str1" ,
	"int1" : 1234 ,
	"double1" : 1.234 ,
	"boolean1" : true ,
	
	"press2" : {
		"byte2" : 2 ,
		"short2" : 23 ,
		"long2" : 23456789 ,
		"float2" : 2.345
	}
}

PressDataClass.java

package xyz.calvinwilliams.test_jsonparser;

public class PressDataClass {
	private String			str1 ;
	private int				int1 ;
	private Double			double1 ;
	private boolean			boolean1 ;
	private String			null1 ;
	public PressDataClass2	press2 ;
	
	public String getStr1() {
		return str1;
	}
	public void setStr1(String str1) {
		this.str1 = str1;
	}

	public int getInt1() {
		return int1;
	}
	public void setInt1(int int1) {
		this.int1 = int1;
	}

	public Double getDouble1() {
		return double1;
	}
	public void setDouble1(Double double1) {
		this.double1 = double1;
	}

	public boolean isBoolean1() {
		return boolean1;
	}
	public void setBoolean1(boolean boolean1) {
		this.boolean1 = boolean1;
	}

	public PressDataClass2 getPress2() {
		return press2;
	}
	public void setPress2(PressDataClass2 press2) {
		this.press2 = press2;
	}
	
	public String getNull1() {
		return null1;
	}
	public void setNull1(String null1) {
		this.null1 = null1;
	}
}

PressDataClass2.java

package xyz.calvinwilliams.test_jsonparser;

public class PressDataClass2 {
	private byte		byte2 ;
	private short		short2 ;
	private Long		long2 ;
	private float		float2 ;
	
	public byte getByte2() {
		return byte2;
	}
	public void setByte2(byte byte2) {
		this.byte2 = byte2;
	}
	
	public short getShort2() {
		return short2;
	}
	public void setShort2(short short2) {
		this.short2 = short2;
	}
	
	public Long getLong2() {
		return long2;
	}
	public void setLong2(Long long2) {
		this.long2 = long2;
	}
	
	public float getFloat2() {
		return float2;
	}
	public void setFloat2(float float2) {
		this.float2 = float2;
	}
}

fastjson

PressFastJsonParser.java

package xyz.calvinwilliams.test_jsonparser;

import java.io.File;
import java.io.FileInputStream;

import com.alibaba.fastjson.*;

public class PressFastJsonParser {

	public static void main(String[] args) {
		
		File file = new File( "press.json" ) ;
		Long fileSize = file.length() ;
		byte[] json = new byte[fileSize.intValue()] ;
		try {
			FileInputStream in = new FileInputStream(file);
			in.read(json);
			in.close();
		} catch (Exception e) {
			e.printStackTrace();
			return;
		}
		String jsonString = new String(json) ;
		
		long l , count = 1000000 ;
		long beginMillisSecondstamp = System.currentTimeMillis() ;
		
		for( l = 0 ; l < count ; l++ ) {
			PressDataClass obj = JSON.parseObject(jsonString, new TypeReference<PressDataClass>() {}) ;
			if( obj == null ) {
				System.out.println( "JSON.stringToObject failed" );
				return;
			}
			else if( l == 0 ){
				System.out.println( "JSON.stringToObject ok" );
				
				System.out.println( "------------------------------ dump PressDataClass" );
				System.out.println( "DataClass.str1["+obj.getStr1()+"]" );
				System.out.println( "PressDataClass.int1["+obj.getInt1()+"]" );
				System.out.println( "PressDataClass.Double1["+obj.getDouble1()+"]" );
				System.out.println( "PressDataClass.boolean1["+obj.isBoolean1()+"]" );
				
				System.out.println( "------------------------------ dump PressDataClass.press2" );
				if( obj.press2 != null ) {
					System.out.println( "PressDataClass.branch2.byte2["+obj.press2.getByte2()+"]" );
					System.out.println( "PressDataClass.branch2.short2["+obj.press2.getShort2()+"]" );
					System.out.println( "PressDataClass.branch2.Long2["+obj.press2.getLong2()+"]" );
					System.out.println( "PressDataClass.branch2.float2["+obj.press2.getFloat2()+"]" );
				}
			}
		}
		
		long endMillisSecondstamp = System.currentTimeMillis() ;
		double elpaseSecond = (endMillisSecondstamp-beginMillisSecondstamp)/1000.0 ;
		System.out.println( "count["+count+"] elapse["+elpaseSecond+"]s" );
		double countPerSecond = count / elpaseSecond ;
		System.out.println( "count per second["+countPerSecond+"]" );
		
		return;
	}
}

PressFastJsonGenerator.java

package xyz.calvinwilliams.test_jsonparser;

import java.io.File;
import java.io.FileInputStream;

import com.alibaba.fastjson.*;

public class PressFastJsonGenerator {

	public static void main(String[] args) {
		
		PressDataClass	object = new PressDataClass() ;
		
		object.setStr1("str1");
		object.setInt1(1234);
		object.setDouble1(1.234);
		object.setBoolean1(true);
		object.setNull1(null);
		
		object.press2 = new PressDataClass2() ;
		object.press2.setByte2((byte)2);
		object.press2.setShort2((short)23);
		object.press2.setLong2(23456789L);
		object.press2.setFloat2(2.345f);
		
		System.out.println( "------------------------------ dump PressDataClass" );
		System.out.println( "DataClass.str1["+object.getStr1()+"]" );
		System.out.println( "PressDataClass.int1["+object.getInt1()+"]" );
		System.out.println( "PressDataClass.Double1["+object.getDouble1()+"]" );
		System.out.println( "PressDataClass.boolean1["+object.isBoolean1()+"]" );
		System.out.println( "PressDataClass.null1["+object.getNull1()+"]" );
		
		System.out.println( "------------------------------ dump PressDataClass.press2" );
		if( object.press2 != null ) {
			System.out.println( "PressDataClass.branch2.byte2["+object.press2.getByte2()+"]" );
			System.out.println( "PressDataClass.branch2.short2["+object.press2.getShort2()+"]" );
			System.out.println( "PressDataClass.branch2.Long2["+object.press2.getLong2()+"]" );
			System.out.println( "PressDataClass.branch2.float2["+object.press2.getFloat2()+"]" );
		}
		
		long l , count = 5000000 ;
		long beginMillisSecondstamp = System.currentTimeMillis() ;
		
		for( l = 0 ; l < count ; l++ ) {
			String jsonString = JSON.toJSONString( object ) ;
			if( jsonString == null ) {
				System.out.println( "JSON.toJSONString failed" );
				return;
			}
			else if( l == count-1 ){
				System.out.println( "JSON.toJSONString ok" );
				System.out.println( jsonString );
			}
		}
		
		long endMillisSecondstamp = System.currentTimeMillis() ;
		double elpaseSecond = (endMillisSecondstamp-beginMillisSecondstamp)/1000.0 ;
		System.out.println( "count["+count+"] elapse["+elpaseSecond+"]s" );
		double countPerSecond = count / elpaseSecond ;
		System.out.println( "count per second["+countPerSecond+"]" );
		
		return;
	}
}

4.4. okjson

PressOkJsonParser.java

package xyz.calvinwilliams.test_jsonparser;

import java.io.File;
import java.io.FileInputStream;

import xyz.calvinwilliams.okjson.*;
import xyz.calvinwilliams.test_jsonparser.PressDataClass;

public class PressOkJsonParser {

	public static void main(String[] args) {
		
		File file = new File( "press.json" ) ;
		Long fileSize = file.length() ;
		byte[] json = new byte[fileSize.intValue()] ;
		try {
			FileInputStream in = new FileInputStream(file);
			in.read(json);
			in.close();
		} catch (Exception e) {
			e.printStackTrace();
			return;
		}
		String jsonString = new String(json) ;
		
		long l , count = 1000000 ;
		long beginMillisSecondstamp = System.currentTimeMillis() ;
		
		for( l = 0 ; l < count ; l++ ) {
			PressDataClass object = OKJSON.stringToObject( jsonString, PressDataClass.class, OKJSON.OPTIONS_DIRECT_ACCESS_PROPERTY_ENABLE ) ;
			if( object == null ) {
				System.out.println( "okjson.stringToObject failed["+OKJSON.getErrorCode()+"]" );
				return;
			} else if( l == 0 ){
				System.out.println( "okjson.stringToObject ok" );
				
				System.out.println( "------------------------------ dump PressDataClass" );
				System.out.println( "DataClass.str1["+object.getStr1()+"]" );
				System.out.println( "PressDataClass.int1["+object.getInt1()+"]" );
				System.out.println( "PressDataClass.Double1["+object.getDouble1()+"]" );
				System.out.println( "PressDataClass.boolean1["+object.isBoolean1()+"]" );
				
				System.out.println( "------------------------------ dump PressDataClass.press2" );
				if( object.press2 != null ) {
					System.out.println( "PressDataClass.branch2.byte2["+object.press2.getByte2()+"]" );
					System.out.println( "PressDataClass.branch2.short2["+object.press2.getShort2()+"]" );
					System.out.println( "PressDataClass.branch2.Long2["+object.press2.getLong2()+"]" );
					System.out.println( "PressDataClass.branch2.float2["+object.press2.getFloat2()+"]" );
				}
			}
		}
		
		long endMillisSecondstamp = System.currentTimeMillis() ;
		double elpaseSecond = (endMillisSecondstamp-beginMillisSecondstamp)/1000.0 ;
		System.out.println( "count["+count+"] elapse["+elpaseSecond+"]s" );
		double countPerSecond = count / elpaseSecond ;
		System.out.println( "count per second["+countPerSecond+"]" );
		
		return;
	}
}

PressOkJsonGenerator.java

package xyz.calvinwilliams.test_jsonparser;

import java.io.File;
import java.io.FileInputStream;

import xyz.calvinwilliams.okjson.OKJSON;
import xyz.calvinwilliams.test_jsonparser.PressDataClass;

public class PressOkJsonGenerator {

	public static void main(String[] args) {
		
		PressDataClass	object = new PressDataClass() ;
		
		object.setStr1("str1");
		object.setInt1(1234);
		object.setDouble1(1.234);
		object.setBoolean1(true);
		object.setNull1(null);
		
		object.press2 = new PressDataClass2() ;
		object.press2.setByte2((byte)2);
		object.press2.setShort2((short)23);
		object.press2.setLong2(23456789L);
		object.press2.setFloat2(2.345f);
		
		System.out.println( "------------------------------ dump PressDataClass" );
		System.out.println( "DataClass.str1["+object.getStr1()+"]" );
		System.out.println( "PressDataClass.int1["+object.getInt1()+"]" );
		System.out.println( "PressDataClass.Double1["+object.getDouble1()+"]" );
		System.out.println( "PressDataClass.boolean1["+object.isBoolean1()+"]" );
		System.out.println( "PressDataClass.null1["+object.getNull1()+"]" );
		
		System.out.println( "------------------------------ dump PressDataClass.press2" );
		if( object.press2 != null ) {
			System.out.println( "PressDataClass.branch2.byte2["+object.press2.getByte2()+"]" );
			System.out.println( "PressDataClass.branch2.short2["+object.press2.getShort2()+"]" );
			System.out.println( "PressDataClass.branch2.Long2["+object.press2.getLong2()+"]" );
			System.out.println( "PressDataClass.branch2.float2["+object.press2.getFloat2()+"]" );
		}
		
		long l , count = 5000000 ;
		long beginMillisSecondstamp = System.currentTimeMillis() ;
		
		for( l = 0 ; l < count ; l++ ) {
			String jsonString = OKJSON.objectToString( object, 0 ) ;
			if( jsonString == null ) {
				System.out.println( "okjson.stringToObject failed["+OKJSON.getErrorCode()+"]["+OKJSON.getErrorDesc()+"]" );
				return;
			} else if( l == count-1 ){
				System.out.println( "okjson.stringToObject ok" );
				System.out.println( jsonString );
			}
		}
		
		long endMillisSecondstamp = System.currentTimeMillis() ;
		double elpaseSecond = (endMillisSecondstamp-beginMillisSecondstamp)/1000.0 ;
		System.out.println( "count["+count+"] elapse["+elpaseSecond+"]s" );
		double countPerSecond = count / elpaseSecond ;
		System.out.println( "count per second["+countPerSecond+"]" );
		
		return;
	}
}

4.5. Benchmarking

JSON Parser benchmarking

okjson

count[1000000] elapse[1.446]s
count per second[691562.9322268326]

fastjson

count[1000000] elapse[2.616]s
count per second[382262.996941896]

okjson

count[1000000] elapse[1.429]s
count per second[699790.0629811056]

fastjson

count[1000000] elapse[2.547]s
count per second[392618.767177071]

okjson

count[1000000] elapse[1.42]s
count per second[704225.3521126761]

fastjson

count[1000000] elapse[2.473]s
count per second[404367.1653861707]

okjson

count[1000000] elapse[1.432]s
count per second[698324.0223463688]

fastjson

count[1000000] elapse[2.48]s
count per second[403225.8064516129]

okjson

count[1000000] elapse[1.434]s
count per second[697350.069735007]

fastjson

count[1000000] elapse[2.459]s
count per second[406669.37779585196]

JSON Generator benchmarking

okjson

count[2000000] elapse[1.399]s
count per second[1429592.5661186562]

fastjson

count[2000000] elapse[1.51]s
count per second[1324503.311258278]

okjson

count[2000000] elapse[1.347]s
count per second[1484780.9948032666]

fastjson

count[2000000] elapse[1.507]s
count per second[1327140.0132714002]

okjson

count[2000000] elapse[1.364]s
count per second[1466275.6598240468]

fastjson

count[2000000] elapse[1.403]s
count per second[1425516.7498218103]

okjson

count[2000000] elapse[1.363]s
count per second[1467351.4306676448]

fastjson

count[2000000] elapse[1.512]s
count per second[1322751.3227513228]

okjson

count[2000000] elapse[1.37]s
count per second[1459854.01459854]

fastjson

count[2000000] elapse[1.409]s
count per second[1419446.4158978]

4.6. Result

json_parsers_benchmark.png

json_generators_benchmark.png

5. TODO

  • Support more field type, for example : JAVA old-version Date Time class
  • XML Parser, Generator

6. About project

Download source at : giteegithub

Apache Maven

<dependency>
  <groupId>xyz.calvinwilliams</groupId>
  <artifactId>okjson</artifactId>
  <version>0.0.10.0</version>
</dependency>

Gradle Kotlin DSL

compile("xyz.calvinwilliams:okjson:0.0.10.0")

7. About author

Mailto : neteaseGmail

Comments ( 15 )

Sign in for post a comment

Java
1
https://gitee.com/calvinwilliams/okjson.git
git@gitee.com:calvinwilliams/okjson.git
calvinwilliams
okjson
okjson
release

Help Search

205735 778617b6 1899542 205747 347fc4a1 1899542