Skip to content

oleg-cherednik/json-api

Repository files navigation

JSON-API

Typing SVG

Maven Central javadoc java8 License

github-ci vulnerabilities license-scan quality coverage

develop

github-ci quality coverage

Table of contest


Getting Started

Imagine you would like to use jackson 2.16.1 as a json framework in your application. In this case, you have several options:

  1. Add jackson dependencies and use it directly;
  2. Along with jackson dependencies add jackson-json-api and use Jackson via json-api.

If you choose 2nd option, you should add json-api implementation for jackson (which is json-jackson-impl) along with existed Jackson dependencies, because json-api implementation does not contain concrete version of the json framework. The version should be additionally specified. I.e. version of json-api implementation does not depend on the version of the json framework.

Gradle

implementation 'ru.oleg-cherednik.json:json-jackson-impl:3.0'
implementation 'com.fasterxml.jackson.core:jackson-databind:2.16.0'

Maven

<dependencies>
  <dependency>
    <groupId>ru.oleg-cherednik.json</groupId>
    <artifactId>json-jackson-impl</artifactId>
    <version>3.0</version>
  </dependency>
  <dependency>
    <groupId>ru.oleg-cherednik.json</groupId>
    <artifactId>json-jackson-impl</artifactId>
    <version>3.0</version>
  </dependency>
</dependencies>

Features

  • Single file API for all json actions;
  • Give an easy way to provide custom engine implementation;
  • It's free of any engine's specific code;
  • It's fully open-source and does not depend on any limited licenses.

Glossary

  • json framework is a framework for working with json files like jackson, gson, json-simple, etc. Usually, we use json framework in the application directly by adding required dependencies. In general, all these json frameworks have its own API and style of coding.
  • json engine is an abstraction above all json framework. The main idea is to provide a unified API over all json frameworks. I.e., using this unified API (json engine), the client is not able to use some specific logic of concrete json framework, but the most common use-cases are available.
  • json decorator is a decorator over json engine. There are read and write decorators that contain the complete set of not static methods for json manipulation. You can use default decorators or create custom once with required settings. The decorator is used to work with json engine with given settings.
  • JSON-API is an abstraction over various json decorators. It provides a simple way to do the most common use-cases of json manipulations. Moreover, it provides the way of single point configuration and exception handling. Using this json-api you are able to not depend on the specific json framework directly and use any of them via given json engine.
  • json-api-impl is a concreted implementation of json-api for given json framework. E.g., an implementation of json-api for jackson called json-jackson-impl and contains instance of json engine called JacksonEngine.

Requirements

Usage

json-api provides set of classes to work with json. You should use only these classes for any json manipulations.

Json class

Read json from String

String to a custom object type (except a collection)
class Data {

  int intVal;
  String strVal;

  public static void demo() {
    String json = """
         {
            "intVal" : 666,
            "strVal" : "omen"
         }
        """;
    Data data = Json.readValue(json, Data.class);
  }

}
String to a List of Object type
class Data {

  public static void demo() {
    String json = """
        [
            {
                "intVal" : 555,
                "strVal" : "victory"
            },
            {
                "intVal" : 666,
                "strVal" : "omen"
            }
        ]
        """;
    List<Object> res = Json.readList(json);
  }

}
String to a Set of Object type
class Data {

  public static void demo() {
    String json = """
        [
            {
                "intVal" : 555,
                "strVal" : "victory"
            },
            {
                "intVal" : 666,
                "strVal" : "omen"
            }
        ]
        """;
    Set<Object> res = Json.readSet(json);
  }

}
String to a List of custom object type
class Data {

  int intVal;
  String strVal;

  public static void demo() {
    String json = """
        [
            {
                "intVal" : 555,
                "strVal" : "victory"
            },
            {
                "intVal" : 666,
                "strVal" : "omen"
            }
        ]
        """;
    List<Data> res = Json.readList(json, Data.class);
  }

}
String to a Set of custom object type
class Data {

  int intVal;
  String strVal;

  public static void demo() {
    String json = """
        [
            {
                "intVal" : 555,
                "strVal" : "victory"
            },
            {
                "intVal" : 666,
                "strVal" : "omen"
            }
        ]
        """;
    Set<Data> res = Json.readSet(json, Data.class);
  }

}
String to a List of Map
class Data {

  int intVal;
  String strVal;

  public static void demo() {
    String json = """
        [
            {
                "intVal" : 555,
                "strVal" : "victory"
            },
            {
                "intVal" : 666,
                "strVal" : "omen"
            }
        ]
        """;
    List<Map<String, Object>> res = Json.readListOfMap(json);
  }

}
String to a Map of String key and Object value type
public class Book {

  private String title;
  private ZonedDateTime date;
  private int year;
  private List<String> authors;

  public static void demo() {
    String json = """
        {
            "one": {
                "title": "Thinking in Java",
                "date": "2017-07-23T13:57:14.225Z",
                "year": 1998,
                "authors": [
                    "Bruce Eckel"
                ]
            },
            "two": {
                "title": "Ready for a victory",
                "date": "2020-07-23T13:57:14.225Z",
                "year": 2020,
                "authors": [
                    "Oleg Cherednik"
                ]
            }
        }
        """;
    Map<String, Object> res = Json.readMap(json);
  }

}
String to a Map of String key and custom value type
public class Book {

  private String title;
  private ZonedDateTime date;
  private int year;
  private List<String> authors;

  public static void demo() {
    String json = """
        {
            "one": {
                "title": "Thinking in Java",
                "date": "2017-07-23T13:57:14.225Z",
                "year": 1998,
                "authors": [
                    "Bruce Eckel"
                ]
            },
            "two": {
                "title": "Ready for a victory",
                "date": "2020-07-23T13:57:14.225Z",
                "year": 2020,
                "authors": [
                    "Oleg Cherednik"
                ]
            }
        }
        """;
    Map<String, Book> res = Json.readMap(json, Book.class);
  }

}
String to a Map of custom key and value type
public class Book {

  private String title;
  private ZonedDateTime date;
  private int year;
  private List<String> authors;

  public static void demo() {
    String json = """
        {
            "1": {
                "title": "Thinking in Java",
                "date": "2017-07-23T13:57:14.225Z",
                "year": 1998,
                "authors": [
                    "Bruce Eckel"
                ]
            },
            "2": {
                "title": "Ready for a victory",
                "date": "2020-07-23T13:57:14.225Z",
                "year": 2020,
                "authors": [
                    "Oleg Cherednik"
                ]
            }
        }
        """;
    Map<Integer, Book> res = Json.readMap(json, Integer.class, Book.class);
  }

}

Read json from ByteBuffer

ByteBuffer to a custom object type (except a collection)
class Data {

  int intVal;
  String strVal;

  public static void demo() {
    String json = """
         {
            "intVal" : 666,
            "strVal" : "omen"
         }
        """;
    ByteBuffer buf = ByteBuffer.wrap(json.getBytes(StandardCharsets.UTF_8));
    Data data = Json.readValue(buf, Data.class);
  }

}
ByteBuffer to a List of Object type
class Data {

  public static void demo() {
    String json = """
        [
            {
                "intVal" : 555,
                "strVal" : "victory"
            },
            {
                "intVal" : 666,
                "strVal" : "omen"
            }
        ]
        """;
    ByteBuffer buf = ByteBuffer.wrap(json.getBytes(StandardCharsets.UTF_8));
    List<Object> res = Json.readList(buf);
  }

}
ByteBuffer to a Set of Object type
class Data {

  public static void demo() {
    String json = """
        [
            {
                "intVal" : 555,
                "strVal" : "victory"
            },
            {
                "intVal" : 666,
                "strVal" : "omen"
            }
        ]
        """;
    ByteBuffer buf = ByteBuffer.wrap(json.getBytes(StandardCharsets.UTF_8));
    Set<Object> res = Json.readSet(buf);
  }

}
ByteBuffer to a List of custom object type
class Data {

  int intVal;
  String strVal;

  public static void demo() {
    String json = """
        [
            {
                "intVal" : 555,
                "strVal" : "victory"
            },
            {
                "intVal" : 666,
                "strVal" : "omen"
            }
        ]
        """;
    ByteBuffer buf = ByteBuffer.wrap(json.getBytes(StandardCharsets.UTF_8));
    List<Data> res = Json.readList(buf, Data.class);
  }

}
ByteBuffer to a Set of custom object type
class Data {

  int intVal;
  String strVal;

  public static void demo() {
    String json = """
        [
            {
                "intVal" : 555,
                "strVal" : "victory"
            },
            {
                "intVal" : 666,
                "strVal" : "omen"
            }
        ]
        """;
    ByteBuffer buf = ByteBuffer.wrap(json.getBytes(StandardCharsets.UTF_8));
    Set<Data> res = Json.readSet(buf, Data.class);
  }

}
ByteBuffer to a List of Map
class Data {

  int intVal;
  String strVal;

  public static void demo() {
    String json = """
        [
            {
                "intVal" : 555,
                "strVal" : "victory"
            },
            {
                "intVal" : 666,
                "strVal" : "omen"
            }
        ]
        """;
    ByteBuffer buf = ByteBuffer.wrap(json.getBytes(StandardCharsets.UTF_8));
    List<Map<String, Object>> res = Json.readListOfMap(buf);
  }

}
ByteBuffer to a Map of String key and Object value type
public class Book {

  private String title;
  private ZonedDateTime date;
  private int year;
  private List<String> authors;

  public static void demo() {
    String json = """
        {
            "one": {
                "title": "Thinking in Java",
                "date": "2017-07-23T13:57:14.225Z",
                "year": 1998,
                "authors": [
                    "Bruce Eckel"
                ]
            },
            "two": {
                "title": "Ready for a victory",
                "date": "2020-07-23T13:57:14.225Z",
                "year": 2020,
                "authors": [
                    "Oleg Cherednik"
                ]
            }
        }
        """;
    ByteBuffer buf = ByteBuffer.wrap(json.getBytes(StandardCharsets.UTF_8));
    Map<String, Object> res = Json.readMap(buf);
  }

}
ByteBuffer to a Map of String key and custom value type
public class Book {

  private String title;
  private ZonedDateTime date;
  private int year;
  private List<String> authors;

  public static void demo() {
    String json = """
        {
            "one": {
                "title": "Thinking in Java",
                "date": "2017-07-23T13:57:14.225Z",
                "year": 1998,
                "authors": [
                    "Bruce Eckel"
                ]
            },
            "two": {
                "title": "Ready for a victory",
                "date": "2020-07-23T13:57:14.225Z",
                "year": 2020,
                "authors": [
                    "Oleg Cherednik"
                ]
            }
        }
        """;
    ByteBuffer buf = ByteBuffer.wrap(json.getBytes(StandardCharsets.UTF_8));
    Map<String, Book> res = Json.readMap(buf, Book.class);
  }

}
ByteBuffer to a Map of custom key and value type
public class Book {

  private String title;
  private ZonedDateTime date;
  private int year;
  private List<String> authors;

  public static void demo() {
    String json = """
        {
            "1": {
                "title": "Thinking in Java",
                "date": "2017-07-23T13:57:14.225Z",
                "year": 1998,
                "authors": [
                    "Bruce Eckel"
                ]
            },
            "2": {
                "title": "Ready for a victory",
                "date": "2020-07-23T13:57:14.225Z",
                "year": 2020,
                "authors": [
                    "Oleg Cherednik"
                ]
            }
        }
        """;
    ByteBuffer buf = ByteBuffer.wrap(json.getBytes(StandardCharsets.UTF_8));
    Map<Integer, Book> res = Json.readMap(buf, Integer.class, Book.class);
  }

}
Read json from ByteBuffer lazy
ByteBuffer to an Iterator of Object type with lazy reading
class Data {

  int intVal;
  String strVal;

  public static void demo() {
    String json = """
        [
            {
                "intVal" : 555,
                "strVal" : "victory"
            },
            {
                "intVal" : 666,
                "strVal" : "omen"
            }
        ]
        """;
    ByteBuffer buf = ByteBuffer.wrap(json.getBytes(StandardCharsets.UTF_8));
    Iterator<Object> it = Json.readListLazy(buf);
  }

}
ByteBuffer to an Iterator of custom object type with lazy reading
class Data {

  int intVal;
  String strVal;

  public static void demo() {
    String json = """
        [
            {
                "intVal" : 555,
                "strVal" : "victory"
            },
            {
                "intVal" : 666,
                "strVal" : "omen"
            }
        ]
        """;
    ByteBuffer buf = ByteBuffer.wrap(json.getBytes(StandardCharsets.UTF_8));
    Iterator<Data> it = Json.readListLazy(buf, Data.class);
  }

}
ByteBuffer to an Iterator of Map with lazy reading
class Data {

  int intVal;
  String strVal;

  public static void demo() {
    String json = """
        [
            {
                "intVal" : 555,
                "strVal" : "victory"
            },
            {
                "intVal" : 666,
                "strVal" : "omen"
            }
        ]
        """;
    ByteBuffer buf = ByteBuffer.wrap(json.getBytes(StandardCharsets.UTF_8));
    Iterator<Map<String, Object>> it = Json.readListOfMapLazy(buf);
  }

}

Read json from InputStream

InputStream to a custom object type (except a collection)
class Data {

  int intVal;
  String strVal;

  public static void demo() {
    String json = """
         {
            "intVal" : 666,
            "strVal" : "omen"
         }
        """;
    InputStream in = new ByteArrayInputStream(json.getBytes());
    Data data = Json.readValue(in, Data.class);
  }

}
InputStream to a List of Object type
class Data {

  public static void demo() {
    String json = """
        [
            {
                "intVal" : 555,
                "strVal" : "victory"
            },
            {
                "intVal" : 666,
                "strVal" : "omen"
            }
        ]
        """;
    InputStream in = new ByteArrayInputStream(json.getBytes());
    List<Object> res = Json.readList(in);
  }

}
InputStream to a Set of Object type
class Data {

  public static void demo() {
    String json = """
        [
            {
                "intVal" : 555,
                "strVal" : "victory"
            },
            {
                "intVal" : 666,
                "strVal" : "omen"
            }
        ]
        """;
    InputStream in = new ByteArrayInputStream(json.getBytes());
    Set<Object> res = Json.readSet(in);
  }

}
InputStream to a List of custom object type
class Data {

  int intVal;
  String strVal;

  public static void demo() {
    String json = """
        [
            {
                "intVal" : 555,
                "strVal" : "victory"
            },
            {
                "intVal" : 666,
                "strVal" : "omen"
            }
        ]
        """;
    InputStream in = new ByteArrayInputStream(json.getBytes());
    List<Data> res = Json.readList(in, Data.class);
  }

}
InputStream to a Set of custom object type
class Data {

  int intVal;
  String strVal;

  public static void demo() {
    String json = """
        [
            {
                "intVal" : 555,
                "strVal" : "victory"
            },
            {
                "intVal" : 666,
                "strVal" : "omen"
            }
        ]
        """;
    InputStream in = new ByteArrayInputStream(json.getBytes());
    Set<Data> res = Json.readSet(in, Data.class);
  }

}
InputStream to a List of Map
class Data {

  int intVal;
  String strVal;

  public static void demo() {
    String json = """
        [
            {
                "intVal" : 555,
                "strVal" : "victory"
            },
            {
                "intVal" : 666,
                "strVal" : "omen"
            }
        ]
        """;
    InputStream in = new ByteArrayInputStream(json.getBytes());
    List<Map<String, Object>> res = Json.readListOfMap(in);
  }

}
InputStream to a Map of String key and Object value type
public class Book {

  private String title;
  private ZonedDateTime date;
  private int year;
  private List<String> authors;

  public static void demo() {
    String json = """
        {
            "one": {
                "title": "Thinking in Java",
                "date": "2017-07-23T13:57:14.225Z",
                "year": 1998,
                "authors": [
                    "Bruce Eckel"
                ]
            },
            "two": {
                "title": "Ready for a victory",
                "date": "2020-07-23T13:57:14.225Z",
                "year": 2020,
                "authors": [
                    "Oleg Cherednik"
                ]
            }
        }
        """;
    InputStream in = new ByteArrayInputStream(json.getBytes());
    Map<String, Object> res = Json.readMap(in);
  }

}
InputStream to a Map of String key and custom value type
public class Book {

  private String title;
  private ZonedDateTime date;
  private int year;
  private List<String> authors;

  public static void demo() {
    String json = """
        {
            "one": {
                "title": "Thinking in Java",
                "date": "2017-07-23T13:57:14.225Z",
                "year": 1998,
                "authors": [
                    "Bruce Eckel"
                ]
            },
            "two": {
                "title": "Ready for a victory",
                "date": "2020-07-23T13:57:14.225Z",
                "year": 2020,
                "authors": [
                    "Oleg Cherednik"
                ]
            }
        }
        """;
    InputStream in = new ByteArrayInputStream(json.getBytes());
    Map<String, Book> res = Json.readMap(in, Book.class);
  }

}
InputStream to a Map of custom key and value type
public class Book {

  private String title;
  private ZonedDateTime date;
  private int year;
  private List<String> authors;

  public static void demo() {
    String json = """
        {
            "1": {
                "title": "Thinking in Java",
                "date": "2017-07-23T13:57:14.225Z",
                "year": 1998,
                "authors": [
                    "Bruce Eckel"
                ]
            },
            "2": {
                "title": "Ready for a victory",
                "date": "2020-07-23T13:57:14.225Z",
                "year": 2020,
                "authors": [
                    "Oleg Cherednik"
                ]
            }
        }
        """;
    InputStream in = new ByteArrayInputStream(json.getBytes());
    Map<Integer, Book> res = Json.readMap(in, Integer.class, Book.class);
  }

}
Read json from InputStream lazy
InputStream to an Iterator of Object type with lazy reading
class Data {

  int intVal;
  String strVal;

  public static void demo() {
    String json = """
        [
            {
                "intVal" : 555,
                "strVal" : "victory"
            },
            {
                "intVal" : 666,
                "strVal" : "omen"
            }
        ]
        """;
    InputStream in = new ByteArrayInputStream(json.getBytes());
    AutoCloseableIterator<Object> it = Json.readListLazy(in);
  }

}
InputStream to an Iterator of custom object type with lazy reading
class Data {

  int intVal;
  String strVal;

  public static void demo() {
    String json = """
        [
            {
                "intVal" : 555,
                "strVal" : "victory"
            },
            {
                "intVal" : 666,
                "strVal" : "omen"
            }
        ]
        """;
    InputStream in = new ByteArrayInputStream(json.getBytes());
    AutoCloseableIterator<Data> it = Json.readListLazy(in, Data.class);
  }

}
InputStream to an Iterator of Map with lazy reading
class Data {

  int intVal;
  String strVal;

  public static void demo() {
    String json = """
        [
            {
                "intVal" : 555,
                "strVal" : "victory"
            },
            {
                "intVal" : 666,
                "strVal" : "omen"
            }
        ]
        """;
    InputStream in = new ByteArrayInputStream(json.getBytes());
    AutoCloseableIterator<Map<String, Object>> it = Json.readListOfMapLazy(in);
  }

}

Read json from Reader

Reader to a custom object type (except a collection)
class Data {

  int intVal;
  String strVal;

  public static void demo() {
    String json = """
         {
            "intVal" : 666,
            "strVal" : "omen"
         }
        """;
    Reader reader = new ByteArrayInputStream(json.getBytes());
    Data data = Json.readValue(reader, Data.class);
  }

}
Reader to a List of Object type
class Data {

  public static void demo() {
    String json = """
        [
            {
                "intVal" : 555,
                "strVal" : "victory"
            },
            {
                "intVal" : 666,
                "strVal" : "omen"
            }
        ]
        """;
    Reader reader = new StringReader(json);
    List<Object> res = Json.readList(reader);
  }

}
Reader to a Set of Object type
class Data {

  public static void demo() {
    String json = """
        [
            {
                "intVal" : 555,
                "strVal" : "victory"
            },
            {
                "intVal" : 666,
                "strVal" : "omen"
            }
        ]
        """;
    Reader reader = new StringReader(json);
    Set<Object> res = Json.readSet(reader);
  }

}
Reader to a List of custom object type
class Data {

  int intVal;
  String strVal;

  public static void demo() {
    String json = """
        [
            {
                "intVal" : 555,
                "strVal" : "victory"
            },
            {
                "intVal" : 666,
                "strVal" : "omen"
            }
        ]
        """;
    Reader reader = new StringReader(json);
    List<Data> res = Json.readList(reader, Data.class);
  }

}
Reader to a Set of custom object type
class Data {

  int intVal;
  String strVal;

  public static void demo() {
    String json = """
        [
            {
                "intVal" : 555,
                "strVal" : "victory"
            },
            {
                "intVal" : 666,
                "strVal" : "omen"
            }
        ]
        """;
    Reader reader = new StringReader(json);
    Set<Data> res = Json.readSet(reader, Data.class);
  }

}
Reader to a List of Map
class Data {

  int intVal;
  String strVal;

  public static void demo() {
    String json = """
        [
            {
                "intVal" : 555,
                "strVal" : "victory"
            },
            {
                "intVal" : 666,
                "strVal" : "omen"
            }
        ]
        """;
    Reader reader = new StringReader(json);
    List<Map<String, Object>> res = Json.readListOfMap(reader);
  }

}
Reader to a Map of String key and Object value type
public class Book {

  private String title;
  private ZonedDateTime date;
  private int year;
  private List<String> authors;

  public static void demo() {
    String json = """
        {
            "one": {
                "title": "Thinking in Java",
                "date": "2017-07-23T13:57:14.225Z",
                "year": 1998,
                "authors": [
                    "Bruce Eckel"
                ]
            },
            "two": {
                "title": "Ready for a victory",
                "date": "2020-07-23T13:57:14.225Z",
                "year": 2020,
                "authors": [
                    "Oleg Cherednik"
                ]
            }
        }
        """;
    Reader reader = new StringReader(json);
    Map<String, Object> res = Json.readMap(reader);
  }

}
Reader to a Map of String key and custom value type
public class Book {

  private String title;
  private ZonedDateTime date;
  private int year;
  private List<String> authors;

  public static void demo() {
    String json = """
        {
            "one": {
                "title": "Thinking in Java",
                "date": "2017-07-23T13:57:14.225Z",
                "year": 1998,
                "authors": [
                    "Bruce Eckel"
                ]
            },
            "two": {
                "title": "Ready for a victory",
                "date": "2020-07-23T13:57:14.225Z",
                "year": 2020,
                "authors": [
                    "Oleg Cherednik"
                ]
            }
        }
        """;
    Reader reader = new StringReader(json);
    Map<String, Book> res = Json.readMap(reader, Book.class);
  }

}
Reader to a Map of custom key and value type
public class Book {

  private String title;
  private ZonedDateTime date;
  private int year;
  private List<String> authors;

  public static void demo() {
    String json = """
        {
            "1": {
                "title": "Thinking in Java",
                "date": "2017-07-23T13:57:14.225Z",
                "year": 1998,
                "authors": [
                    "Bruce Eckel"
                ]
            },
            "2": {
                "title": "Ready for a victory",
                "date": "2020-07-23T13:57:14.225Z",
                "year": 2020,
                "authors": [
                    "Oleg Cherednik"
                ]
            }
        }
        """;
    Reader reader = new StringReader(json);
    Map<Integer, Book> res = Json.readMap(reader, Integer.class, Book.class);
  }

}
Read json from Reader lazy
Reader to an Iterator of Object type with lazy reading
class Data {

  int intVal;
  String strVal;

  public static void demo() {
    String json = """
        [
            {
                "intVal" : 555,
                "strVal" : "victory"
            },
            {
                "intVal" : 666,
                "strVal" : "omen"
            }
        ]
        """;
    Reader reader = new StringReader(json);
    AutoCloseableIterator<Object> it = Json.readListLazy(reader);
  }

}
Reader to an Iterator of custom object type with lazy reading
class Data {

  int intVal;
  String strVal;

  public static void demo() {
    String json = """
        [
            {
                "intVal" : 555,
                "strVal" : "victory"
            },
            {
                "intVal" : 666,
                "strVal" : "omen"
            }
        ]
        """;
    Reader reader = new StringReader(json);
    AutoCloseableIterator<Data> it = Json.readListLazy(reader, Data.class);
  }

}
Reader to an Iterator of Map with lazy reading
class Data {

  int intVal;
  String strVal;

  public static void demo() {
    String json = """
        [
            {
                "intVal" : 555,
                "strVal" : "victory"
            },
            {
                "intVal" : 666,
                "strVal" : "omen"
            }
        ]
        """;
    Reader reader = new StringReader(json);
    AutoCloseableIterator<Map<String, Object>> it = Json.readListOfMapLazy(reader);
  }

}

Write json

Write to String
class Data {

  int intVal;
  String strVal;

  public static void demo() {
    Data data = new Data(666, "omen");
    String json = Json.writeValue(data);
  }

}
Write to OutputStream
class Data {

  int intVal;
  String strVal;

  public static void demo() {
    Data data = new Data(666, "omen");

    try (OutputStream out = new ByteArrayOutputStream()) {
      Json.writeValue(data, out);
    }
  }

}
Write to Writer
class Data {

  int intVal;
  String strVal;

  public static void demo() {
    Data data = new Data(666, "omen");

    try (Writer out = new StringWriter()) {
      Json.writeValue(data, out);
    }
  }

}

Get default decorators

Get current default instance of JsonReader
class Data {

  public static void demo() {
    String json = """
         {
            "intVal" : 666,
            "strVal" : "omen"
         }
        """;

    // using static method
    Data data1 = Json.readValue(json, Data.class);

    // alternative: using JsonReader instance
    JsonReader reader = Json.reader();
    Data data2 = reader.readValue(json, Data.class);
  }

}
Get current default instance of JsonWriter
class Data {

  public static void demo() {
    Data data = new Data(666, "omen");

    // using static method
    String json1 = Json.writeValue(data);

    // alternative: using JsonWriter instance
    JsonWriter writer = Json.writer();
    String json2 = writer.writeValue(data);
  }

}
Get current default instance of JsonWriter with enabled pretty-print option
class Data {

  public static void demo() {
    Data data = new Data(666, "omen");

    // there is no way for pretty-print using static method

    // using JsonWriter instance with pretty-print option
    JsonWriter writer = Json.prettyPrint();
    String json = writer.writeValue(data);
  }

}

Create copy of default decorators

Create a new instance of JsonReader with default settings
class Data {

  public static void demo() {
    String json = """
         {
            "intVal" : 666,
            "strVal" : "omen"
         }
        """;

    // using static method
    Data data1 = Json.readValue(json, Data.class);

    // alternative: using new JsonReader instance
    JsonReader reader = Json.createReader();
    Data data2 = reader.readValue(json, Data.class);
  }

}
Create a new instance of JsonWriter with default settings
class Data {

  public static void demo() {
    Data data = new Data(666, "omen");

    // using static method
    String json1 = Json.writeValue(data);

    // alternative: using new JsonWriter instance
    JsonWriter writer = Json.createWriter();
    String json2 = writer.writeValue(data);
  }

}
Create a new instance of JsonWriter with default settings and enabled pretty-print option
class Data {

  public static void demo() {
    Data data = new Data(666, "omen");

    // there is no way for pretty-print using static method

    // using new JsonWriter instance with pretty-print option
    JsonWriter writer = Json.createPrettyPrint();
    String json = writer.writeValue(data);
  }

}

Create custom decorators

Create a new instance of JsonReader with custom settings
class Data {

  public static void demo() {
    String json = """
         {
            "intVal" : 666,
            "strVal" : "omen"
         }
        """;

    // there is no way for pretty-print using static method

    // using new JsonReader instance with custom settings
    JsonSettings settings = new JsonSettings();
    JsonReader reader = Json.createReader(settings);
    Data data = reader.readValue(json, Data.class);
  }

}
Create a new instance of JsonWriter with custom settings
class Data {

  public static void demo() {
    Data data = new Data(666, "omen");

    // there is no way for pretty-print using static method

    // using new JsonWriter instance with custom settings
    JsonSettings settings = new JsonSettings();
    JsonWriter writer = Json.createWriter(settings);
    String json = writer.writeValue(data);
  }

}
Create a new instance of JsonWriter with custom settings and enabled pretty-print option
class Data {

  public static void demo() {
    Data data = new Data(666, "omen");

    // there is no way for pretty-print using static method

    // using new JsonWriter instance with custom settings and pretty-print option
    JsonSettings settings = new JsonSettings();
    JsonWriter writer = Json.createPrettyPrint(settings);
    String json = writer.writeValue(data);
  }

}

Convert object

Convert any Object instance to Map
class Data {

  public static void demo() {
    Data data = new Data(666, "omen");
    Map<String, Object> map = Json.convertToMap(data);
  }

}

JsonHelper class

Work with enum

Custom json-api implementation

For now there are two implementations: json-jackson-impl and json-gson-impl. To create another implementation, you have to a few steps. Let's make an example for Jackson framework.

JacksonFactory

The name of the class is up to you, but it's better to call this class similar to existed implementations: JacksonFactory for Jackson or GsonFactory for Gson.

This class is responsible

// TODO my recommendation to keep the package like this
package ru.olegcherednik.json.impl;

/*
 * The class is responsible to create two instances of `JsonEngine`:
 * normal and pretty print using given settings.
 */
final class JacksonFactory {

    /*
     * Retrieves a new instance of `JsonEngine` based on the give settings.
     * The instance should be completely new (not cached).
     *
     * @param settings not `null` settings configuration
     * @return not `null` instance of `JsonEngine` for current json framework
     */
    public static JacksonEngine createJsonEngine(JsonSettings settings) {
    }

    /*
     * Retrieves a new instance of `JsonEngine` with pretty print option based
     * on the given settings. The instance should be completely new (not cached).
     *
     * @param settings not `null` settings configuration
     * @return not `null` instance of `JsonEngine` with pretty print for current
     * json framework
     */
    public static JacksonEngine createPrettyPrintJsonEngine(JsonSettings settings) {
    }
}

StaticJsonEngineFactory

The full name of this class is ru.olegcherednik.json.impl.StaticJsonEngineFactory. This is an implementation of the JsonEngineFactory interface. json-api does not scan the whole project for the factory class, it just tries to find the one with predefined name. So this is an entry point to the implementation.

// TODO the package name is predefined
package ru.olegcherednik.json.impl;

public final class StaticJsonEngineFactory implements JsonEngineFactory {

    private static final StaticJsonEngineFactory INSTANCE = new StaticJsonEngineFactory();

    /*
     * Mandatory method.
     *
     * Retrieves a singleton instance of the factory. The method must have the
     * signature like this. Do not change it!
     *
     * @return not `null` singleton instance of the factory
     */
    public static StaticJsonEngineFactory getInstance() {
        return INSTANCE;
    }

    /*
     * Mandatory method.
     *
     * Retrieves a full name of the main class of the json framework. You should
     * not use class' declaration like ёObjectMapper.class.getName()`. You should
     * use only simple string instead. This is very important not to load the
     * class instance at this step.
     *
     * @return not `null` string containing the full name of the main class of
     * the json framework
     */
    public static String getMainClass() {
        return "com.fasterxml.jackson.databind.ObjectMapper";
    }

    @Override
    public JsonEngine createJsonEngine(JsonSettings settings) {
        return JacksonFactory.createJsonEngine(settings);
    }

    @Override
    public JsonEngine createPrettyPrintJsonEngine(JsonSettings settings) {
        return JacksonFactory.createPrettyPrintJsonEngine(settings);
    }
}

There are two main classes. All other code of the implementation is under your control. As an example you can use any of existed implementations, e.g. json-jackson-impl or json-gson-impl.

Links