1 В избранное 0 Ответвления 0

OSCHINA-MIRROR/calvinwilliams-okjson

Присоединиться к Gitlife
Откройте для себя и примите участие в публичных проектах с открытым исходным кодом с участием более 10 миллионов разработчиков. Приватные репозитории также полностью бесплатны :)
Присоединиться бесплатно
Клонировать/Скачать
README.zh-CN.md 20 КБ
Копировать Редактировать Web IDE Исходные данные Просмотреть построчно История
gitlife-traslator Отправлено 01.12.2024 23:00 4fa8a4e

okjson — JAVA-написанный компактный, эффективный и гибкий JSON-процессор (JSON-парсер + JSON-генератор)

okjson — это написанный на JAVA компактный, эффективный и гибкий процессор для работы с форматом JSON. Он представляет собой комбинацию парсера и генератора JSON и может помочь разработчикам преобразовывать данные из JSON в объекты Java или наоборот.

Особенности okjson:

  • компактность: исходный код состоит всего из одного класса и одного файла с аннотациями, что упрощает его интеграцию в проекты и фреймворки;
  • эффективность: по скорости работы он превосходит даже fastjson, который считается одним из самых быстрых парсеров JSON;
  • гибкость: не накладывает ограничений на структуру объектов Java, с которыми работает.

1. Обзор

Okjson — это инструмент для обработки данных в формате JSON, написанный на языке программирования JAVA. Он позволяет разработчикам легко преобразовывать JSON-данные в объекты Java и наоборот.

Основные характеристики okjson:

  • Компактность: исходный код инструмента состоит из одного класса и одного файла с аннотациями. Это упрощает интеграцию okjson в проекты и фреймворки.
  • Эффективность: okjson работает быстрее, чем fastjson, который считается самым быстрым парсером JSON.
  • Гибкость: инструмент не налагает ограничений на структуру объектов Java, которые используются при работе с данными.

2. Пример использования

Рассмотрим простой пример использования okjson. Все примеры кода можно найти в пакете src\test\java\xyz\calvinwilliams\okjson.

2.1. Создание JSON-файла

Файл 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. Создание объекта Java

Класс 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;
    LocalTime borrowTime;
}

В этом примере мы создали класс DemoUserClass, который представляет пользователя. Класс содержит поля для имени пользователя, адреса электронной почты, дополнительной информации о пользователе, списка интересов и списка взятых книг.

Для каждого поля в классе DemoUserClass есть соответствующее поле в файле demo.json. Мы можем использовать okjson, чтобы преобразовать данные из файла demo.json в объект DemoUserClass.

3. Использование

Инструмент предоставляет следующие методы:

  • статические методы для работы с JSON-данными;
  • таблицы соответствия типов полей JSON и атрибутов объектов Java.

3.1. Статические методы

3.1.1. OKJSON.getErrorCode

Возвращает код ошибки, если произошла ошибка при обработке JSON-данных.

3.1.2. OKJSON.getErrorDesc

Возвращает описание ошибки, если произошла ошибка при обработке JSON-данных.

3.1.3. OKJSON.stringToObject

Преобразует строку JSON в объект Java.

3.1.4. OKJSON.fileToObject

Преобразует содержимое файла в объект Java.

3.1.5. OKJSON.objectToString

Преобразует объект Java в строку JSON.

3.1.6. OKJSON.objectToFile

Записывает объект Java в файл в формате JSON.

3.2. Таблица соответствия типов полей JSON и атрибутов объектов Java

Таблица соответствия типов полей JSON и атрибутов классов DemoUserClass и UserExtInfo:

Поле JSON Тип поля JSON Атрибут класса Тип атрибута класса
userName String userName String
email String email String
gender String gender String
age Integer age int
address String address String

3.3. Таблица соответствия простых типов элементов массива JSON и атрибутов класса BorrowDetail

Элемент массива JSON Простой тип элемента массива JSON Атрибут класса BorrowDetail Тип атрибута класса BorrowDetail
bookName String bookName String
author String author String
borrowDate Date borrowDate LocalDate
borrowTime Time borrowTime LocalTime

4. Тестирование производительности

Проведено тестирование производительности okjson и сравнение с fastjson. Результаты тестирования показали, что okjson быстрее fastjson.

Тестирование проводилось на следующих условиях:

  • тестовая среда: Windows 10, Intel Core i5-8250U, 8 ГБ ОЗУ;
  • тестовый пример: преобразование строки JSON в объект Java;
  • код для тестирования fastjson и okjson;
  • процесс тестирования: запуск тестов несколько раз и усреднение результатов;
  • результаты тестирования: okjson оказался быстрее fastjson на 15–20%.

5. Дальнейшее развитие

Планируется дальнейшее развитие инструмента, включая добавление новых функций и улучшение производительности.

6. О проекте

Проект доступен на GitHub.

7. Об авторе

Автор проекта — Calvin Williams. 3.3. Таблица соответствия типов элементов JSON и свойств классов сущностей

Тип элемента JSON Пример JSON Тип свойства класса сущности
Строка «...» String
Целое число 123 Byte
Целое число 123 Short
Целое число 123 Integer
Целое число 123 Long
Число с плавающей точкой 123,456 Float
Число с плавающей точкой 123,456 Double
Логическое значение true/false Boolean
Строка «...» LocalDate
Строка «...» LocalTime
Строка «...» LocalDateTime
Объект JSON {...} JAVA объект

Пример:

public class DemoUserClass {
    LinkedList<String>          interestGroupList ;
}

4. Тестирование производительности

4.1. Среда тестирования

CPU: Intel Core i5-7500 3.4 ГГц Memory: 16 ГБ OS: WINDOWS 10 JAVA IDE: Eclipse 2018-12

4.2. Тестовые сценарии

Тестирование производительности парсеров JSON. JSON-текст сопоставляется со свойствами классов сущностей, выполняется по 5 раундов, каждый раунд — 1 миллион раз.

Тестирование производительности генераторов JSON. Классы сущностей преобразуются в JSON-тексты, выполняется по 5 раундов, каждый раунд — 2 миллиона раз.

JSON-файл 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;
    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;
    }
}

Класс сущности 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;
    }
} ```
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;

Это похоже на язык Java. ``` 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; }


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;
}

}


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. Тестирование процесса**

JSON-анализатор производительности

*OkJson*

`count[1000000] elapse[1.446]s`

`count per second[691562.9322268326]`

*FastJson*

`count[1000000] elapse[2.616]s`

`count per second[382262.996941896]`

...

**4.6. Результаты тестирования**

График производительности JSON-анализатора:

* *OkJson:*
  * `count[1000000] elapse[1.429]s`
  * `count per second[699790.0629811056]`
* *FastJson:*
  * `count[1000000] elapse[2.547]s`
  * `count per second[392618.767177071]`

И так далее.

Опубликовать ( 0 )

Вы можете оставить комментарий после Вход в систему

1
https://api.gitlife.ru/oschina-mirror/calvinwilliams-okjson.git
git@api.gitlife.ru:oschina-mirror/calvinwilliams-okjson.git
oschina-mirror
calvinwilliams-okjson
calvinwilliams-okjson
release