{"id":15719857,"url":"https://github.com/dorkbox/json","last_synced_at":"2025-03-30T22:45:54.302Z","repository":{"id":186428772,"uuid":"674896400","full_name":"dorkbox/Json","owner":"dorkbox","description":"Lightweight Kotlin/JSON serialization","archived":false,"fork":false,"pushed_at":"2024-01-22T16:36:49.000Z","size":285,"stargazers_count":1,"open_issues_count":0,"forks_count":0,"subscribers_count":2,"default_branch":"master","last_synced_at":"2025-02-06T04:13:09.821Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"Kotlin","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"other","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/dorkbox.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2023-08-05T05:06:42.000Z","updated_at":"2023-11-22T22:27:58.000Z","dependencies_parsed_at":"2024-10-24T16:08:12.718Z","dependency_job_id":"6d801116-d6cb-4cb6-bc62-5cf45ade1490","html_url":"https://github.com/dorkbox/Json","commit_stats":null,"previous_names":["dorkbox/json"],"tags_count":8,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/dorkbox%2FJson","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/dorkbox%2FJson/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/dorkbox%2FJson/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/dorkbox%2FJson/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/dorkbox","download_url":"https://codeload.github.com/dorkbox/Json/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":246390857,"owners_count":20769476,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2024-10-03T21:57:00.853Z","updated_at":"2025-03-30T22:45:54.279Z","avatar_url":"https://github.com/dorkbox.png","language":"Kotlin","funding_links":[],"categories":[],"sub_categories":[],"readme":"Reflection based JSON reading and writing\n\n###### [![Dorkbox](https://badge.dorkbox.com/dorkbox.svg \"Dorkbox\")](https://git.dorkbox.com/dorkbox/Json) [![Github](https://badge.dorkbox.com/github.svg \"Github\")](https://github.com/dorkbox/Json) [![Gitlab](https://badge.dorkbox.com/gitlab.svg \"Gitlab\")](https://gitlab.com/dorkbox/Json)\n\n\n## Json\n\n- [Overview](#Overview)\n- [Writing object graphs](#writing-object-graphs)\n- [Reading object graphs](#reading-object-graphs)\n- [Customizing serialization](#customizing-serialization)\n- [Event based parsing](#event-based-parsing)\n\n## Overview\n\nJson is a lightweight library that makes it easy to serialize and deserialize Java object graphs to and from JSON. The JAR is 45k and has minimal dependencies. It is not designed to be fast or optimized, but rather to be simple and easy to understand. Four small classes make up the important parts of the library:\n\n- `JsonWriter`: A builder style API for emitting JSON.\n- `JsonReader`: Parses JSON and builds a DOM of `JsonValue` objects.\n- `JsonValue`: Describes a JSON object, array, string, float, long, boolean, or null.\n- `Json`: Reads and writes arbitrary object graphs using `JsonReader` and `JsonWriter`.\n\n## Writing object graphs\n\nThe `Json` class uses reflection to automatically serialize objects to JSON. For example, here are two classes (getters/setters and constructors omitted):\n\n```java\n    public class Person {\n       private String name;\n       private int age;\n       private ArrayList numbers;\n    }\n    \n    public class PhoneNumber {\n       private String name;\n       private String number;\n    }\n```\n\nExample object graph using these classes:\n\n```java\n    Person person = new Person();\n    person.setName(\"Nate\");\n    person.setAge(31);\n    ArrayList numbers = new ArrayList();\n    numbers.add(new PhoneNumber(\"Home\", \"206-555-1234\"));\n    numbers.add(new PhoneNumber(\"Work\", \"425-555-4321\"));\n    person.setNumbers(numbers);\n```\n\nThe JsonBeans code to serialize this object graph:\n\n```java\n    Json json = new Json();\n    System.out.println(json.toJson(person));\n```\n```json \n{\"numbers\":[{\"class\":\"com.example.PhoneNumber\",\"name\":\"Home\",\"number\":\"206-555-1234\"},{\"class\":\"com.example.PhoneNumber\",\"name\":\"Work\",\"number\":\"425-555-4321\"}],\"age\":31,\"name\":\"Nate\"}\n```\n\nThat is compact, but hardly legible. The `prettyPrint` method can be used:\n\n```java\n    Json json = new Json();\n    System.out.println(json.prettyPrint(person));\n```\n```json\n    {\n    \"name\": \"Nate\",\n    \"age\": 31,\n    \"numbers\": [\n       {\n          \"name\": \"Home\",\n          \"class\": \"com.example.PhoneNumber\",\n          \"number\": \"206-555-1234\"\n       },\n       {\n          \"name\": \"Work\",\n          \"class\": \"com.example.PhoneNumber\",\n          \"number\": \"425-555-4321\"\n       }\n    ]\n    }\n```\n\nNote that the class for the `PhoneNumber` objects in the `ArrayList numbers` field appears in the JSON. This is required to recreate the object graph from the JSON because `ArrayList` can hold any type of object. Class names are only output when they are required for deserialization. If the field was `ArrayList\u003cPhoneNumber\u003e numbers` then class names would only appear when an item in the list extends `PhoneNumber`. If you know the concrete type or aren't using generics, you can avoid class names being written by telling the `Json` class the types:\n\n```java\n    Json json = new Json();\n    json.setElementType(Person.class, \"numbers\", PhoneNumber.class);\n    System.out.println(json.prettyPrint(person));\n```\n```json\n    {\n    \"name\": \"Nate\",\n    \"age\": 31,\n    \"numbers\": [\n       {\n          \"name\": \"Home\",\n          \"number\": \"206-555-1234\"\n       },\n       {\n          \"name\": \"Work\",\n          \"number\": \"425-555-4321\"\n       }\n    ]\n    }\n```\n\nWhen writing the class cannot be avoided, an alias can be given:\n\n```java\n    Json json = new Json();\n    json.addClassTag(\"phoneNumber\", PhoneNumber.class);\n    System.out.println(json.prettyPrint(person));\n```\n```json\n    {\n    \"name\": \"Nate\",\n    \"age\": 31,\n    \"numbers\": [\n       {\n          \"name\": \"Home\",\n          \"class\": \"phoneNumber\",\n          \"number\": \"206-555-1234\"\n       },\n       {\n          \"name\": \"Work\",\n          \"class\": \"phoneNumber\",\n          \"number\": \"425-555-4321\"\n       }\n    ]\n    }\n```\n\nJson can write and read both JSON and a couple JSON-like formats. It supports \"javascript\", where the object property names are only quoted when needed. It also supports a \"minimal\" format, where both object property names and values are only quoted when needed.\n\n```java\n    Json json = new Json();\n    json.setOutputType(OutputType.minimal);\n    json.setElementType(Person.class, \"numbers\", PhoneNumber.class);\n    System.out.println(json.prettyPrint(person));\n```\n```json\n    {\n    name: Nate,\n    age: 31,\n    numbers: [\n       {\n          name: Home,\n          number: \"206-555-1234\"\n       },\n       {\n          name: Work,\n          number: \"425-555-4321\"\n       }\n    ]\n    }\n```\n\n## Reading object graphs\n\nThe Json class uses reflection to automatically deserialize objects from JSON. Here is how to deserialize the JSON from the previous examples:\n\n```java\n    Json json = new Json();\n    String text = json.toJson(person);\n    Person person2 = json.fromJson(Person.class, text);\n```\n\nThe type passed to `fromJson` is the type of the root of the object graph. From this, Json can determine the types of all the fields and all other objects encountered, recursively. The \"knownType\" and \"elementType\" of the root can be passed to `toJson`. This is useful if the type of the root object is not known:\n\n```java\n    Json json = new Json();\n    json.setOutputType(OutputType.minimal);\n    String text = json.toJson(person, Object.class);\n    System.out.println(json.prettyPrint(text));\n    Object person2 = json.fromJson(Object.class, text);\n```\n```json\n    {\n    class: com.example.Person,\n    name: Nate,\n    age: 31,\n    numbers: [\n       {\n          name: Home,\n          class: com.example.PhoneNumber,\n          number: \"206-555-1234\"\n       },\n       {\n          name: Work,\n          class: com.example.PhoneNumber,\n          number: \"425-555-4321\"\n       }\n    ]\n    }\n```\n\nTo read the JSON as a DOM of maps, arrays, and values, the `JsonReader` class can be used:\n\n```java\n    Json json = new Json();\n    String text = json.toJson(person, Object.class);\n    JsonValue root = new JsonReader().parse(text);\n```\n\nThe `JsonValue` describes a JSON object, array, string, float, long, boolean, or null.\n\n## Customizing serialization\n\nSerialization can be customized by either having the class to be serialized implement the `Json.Serializable` interface, or by registering a `Json.Serializer` with the `Json` instance. This example writes the phone numbers as an object with a single field:\n\n```java\n    static public class PhoneNumber implements Json.Serializable {\n       private String name;\n       private String number;\n    \n       public void write (Json json) {\n          json.writeValue(name, number);\n       }\n    \n       public void read (Json json, JsonValue jsonMap) {\n          name = jsonMap.child().name();\n          number = jsonMap.child().asString();\n       }\n    }\n    \n    Json json = new Json();\n    json.setElementType(Person.class, \"numbers\", PhoneNumber.class);\n    String text = json.prettyPrint(person);\n    System.out.println(text);\n    Person person2 = json.fromJson(Person.class, text);\n```\n```json\n    {\n    \"name\": \"Nate\",\n    \"age\": 31\n    \"numbers\": [\n       { \n          \"Home\": \"206-555-1234\"\n       },\n       {\n          \"Work\": \"425-555-4321\"\n       }\n    ]\n    }\n```\n\nIn the `JsonSerializable` interface methods, the `Json` instance is given. It has many methods to read and write data to the JSON. When using `JsonSerializable`, the surrounding JSON object is handled automatically in the `write` method. This is why the `read` method always receives a `JsonMap`.\n\n`JsonSerializer` provides more control over what is output, requiring `writeObjectStart` and `writeObjectEnd` to be called to achieve the same effect. A JSON array or a simple value could be output instead of an object. `JsonSerializer` also allows the object creation to be customized.\n\n```java\n    Json json = new Json();\n    json.setSerializer(PhoneNumber.class, new JsonSerializer\u003cPhoneNumber\u003e() {\n       public void write (Json json, PhoneNumber number, Class knownType) {\n          json.writeObjectStart();\n          json.writeValue(number.name, number.number);\n          json.writeObjectEnd();\n       }\n    \n       public PhoneNumber read (Json json, JsonValue jsonData, Class type) {\n          PhoneNumber number = new PhoneNumber();\n          number.setName(jsonData.child().name());\n          number.setNumber(jsonData.child().asString());\n          return number;\n       }\n    });\n    json.setElementType(Person.class, \"numbers\", PhoneNumber.class);\n    String text = json.prettyPrint(person);\n    System.out.println(text);\n    Person person2 = json.fromJson(Person.class, text);\n```\n\n## Event based parsing\n\nThe `JsonReader` class reads JSON and has protected methods that are called as JSON objects, arrays, strings, numbers, and booleans are encountered. By default, these methods build a DOM out of `JsonValue` objects. These methods can be overridden to do your own event based JSON handling.\n\n\nMaven Info\n---------\n```\n\u003cdependencies\u003e\n    ...\n    \u003cdependency\u003e\n      \u003cgroupId\u003ecom.dorkbox\u003c/groupId\u003e\n      \u003cartifactId\u003eJson\u003c/artifactId\u003e\n      \u003cversion\u003e1.9\u003c/version\u003e\n    \u003c/dependency\u003e\n\u003c/dependencies\u003e\n```\n\nGradle Info\n---------\n```\ndependencies {\n    ...\n    implementation(\"com.dorkbox:Json:1.9\")\n}\n```\n\nLicense\n---------\nThis project is © 2023 dorkbox llc, and is distributed under the terms of the Apache v2.0 License. See file \"LICENSE\" for further \nreferences.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdorkbox%2Fjson","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fdorkbox%2Fjson","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdorkbox%2Fjson/lists"}