{"id":16689583,"url":"https://github.com/sigpwned/jsonification","last_synced_at":"2026-02-01T01:03:12.365Z","repository":{"id":40725079,"uuid":"42417215","full_name":"sigpwned/jsonification","owner":"sigpwned","description":"Simple JSON library for Java","archived":false,"fork":false,"pushed_at":"2022-04-05T15:28:52.000Z","size":152,"stargazers_count":2,"open_issues_count":1,"forks_count":2,"subscribers_count":2,"default_branch":"master","last_synced_at":"2025-03-22T14:41:35.057Z","etag":null,"topics":["java","json","json-parsing","json-processing"],"latest_commit_sha":null,"homepage":"","language":"Java","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"apache-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/sigpwned.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}},"created_at":"2015-09-13T23:42:17.000Z","updated_at":"2024-06-27T09:27:45.000Z","dependencies_parsed_at":"2022-08-19T07:00:36.433Z","dependency_job_id":null,"html_url":"https://github.com/sigpwned/jsonification","commit_stats":null,"previous_names":[],"tags_count":1,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/sigpwned%2Fjsonification","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/sigpwned%2Fjsonification/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/sigpwned%2Fjsonification/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/sigpwned%2Fjsonification/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/sigpwned","download_url":"https://codeload.github.com/sigpwned/jsonification/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/sigpwned%2Fjsonification/sbom","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":259144583,"owners_count":22811926,"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":["java","json","json-parsing","json-processing"],"created_at":"2024-10-12T15:48:40.041Z","updated_at":"2026-02-01T01:03:07.344Z","avatar_url":"https://github.com/sigpwned.png","language":"Java","readme":"# JSONIFICATION ![Build Status](https://codebuild.us-east-1.amazonaws.com/badges?uuid=eyJlbmNyeXB0ZWREYXRhIjoiZTVCSytLYTh1bzM4eFVSbWhiRTFROWtKQ09uS2RRSm44ZFRjWjBzSnFhU0pJODhTdWR2dlBXeGZoMXhiVEs0VnFrY2g1UE9XZFhXaTdETkhKRjRtbjJ3PSIsIml2UGFyYW1ldGVyU3BlYyI6ImhVWFArdS9DUUI0N2UwZEkiLCJtYXRlcmlhbFNldFNlcmlhbCI6MX0%3D\u0026branch=master) ![Test Coverage](target/jacoco.svg)\n\nJSON is a simple data format. Working with JSON should be simple,\ntoo. Jsonification is a simple, dependency-free JSON processing\nlibrary that tries to make working with JSON in Java simple and\nnatural, no matter what your task or program architecture is.\n\n## Overview\n\nJsonification provides ways to parse and emit JSON incrementally,\nwhich is perfect for working with large JSON documents, or as a tree,\nwhich makes manipulating small JSON documents like API responses a\nsenap. For example, parsing [an example Twitter API\nresponse](https://dev.twitter.com/rest/reference/get/users/show) and\npulling out a few fields is just a few simple lines of code:\n\n    String userJsonResponse=getUserDataFromTwitter(\"twitterdev\");\n    JsonObject o=Json.parse(userJsonResponse).asObject();\n    long id=o.get(\"id\").asScalar().asNumber().longVal(); // 2244994945\n    String screenName=o.get(\"screen_name\").asScalar().asString().stringVal();\n    int followers=o.get(\"followers_count\").asScalar().asNumber().intVal(); // 143916\n    boolean following=o.get(\"following\").asScalar().asBoolean().booleanVal(); // false\n    \nIf you're working with JSON trees, Jsonification also makes working\nwith JSON `null` -- a common difficulty in other libraries -- by\nrepresenting it with a custom value instead of using Java's native\n`null` value. This allows you to manipulate JSON without worrying\nabout `NullPointerException`s. To continue the above example, these\nare all ways you could determine if the user has ever sent a tweet by\nchecking if the user's most recent tweet is `null`:\n\n    if(o.get(\"status\").isNull()) {\n        // The user has never tweeted\n    }\n    \n    if(o.get(\"status\") == Json.NULL) {\n        // The user has never tweeted\n    }\n    \n    if(o.get(\"status\").getType() == JsonValue.Type.NULL) {\n        // The user has never tweeted\n    }\n    \nJsonification is also careful to use its own exceptions instead of\nJava's builtin exceptions to make telling the difference between JSON\nprocessing errors and program logic errors easier. For example, If you\ndid try to read through the \"status\" attribute above and it was\n`null`, Jsonification would throw a `JsonNullException` instead of a\n`NullPointerException`. All Jsonification exceptions inherit from\n`JsonException`, which means you can isolate and handle JSON\nprocessing errors easily.\n\n    String tweet;\n    try {\n        tweet = o.get(\"status\").asObject().get(\"text\").asScalar().asString().stringVal();\n    }\n    catch(JsonNullException e) {\n        // Oops! One of the values we dereferenced above was a JSON null.\n        tweet = null;\n    }\n    catch(JsonException e) {\n        // Oops! Some other JSON processing-related exception has occurred.\n        tweet = null;\n    }\n\n## Reading JSON\n\nJsonification offers three ways to parse JSON data. The underlying\nparser is the same in all cases, so they will all parse JSON in\nexactly the same standards-compliant way. The different approaches\nallow the user to use the code in different styles.\n\n### Streaming Push\n\nIn this mode, Jsonification will \"push\" parse events to a handler\nclass via method calls. This parser only holds in memory the data from\nthe current event being processed, so it's an excellent way to process\nvery large JSON documents or fragments. However, because the user has\nno control or context for the JSON events other than the sequence in\nwhich they are processed, parsing JSON in this way frequently requires\nthe user to use complex processing logic to interpret the JSON\ndata. This approach is great when the JSON being parsed is large but\nsimple.\n\n    try {\n        boolean parsed=Json.parse(reader, new JsonParser.Handler() {\n            @Override\n            public void openObject(String name) {\n            }\n\n            @Override\n            public void closeObject() {\n            }\n\n            @Override\n            public void openArray(String name) {\n            }\n\n            @Override\n            public void closeArray() {\n            }\n\n            @Override\n            public void scalar(String name, boolean value) {\n            }\n\n            @Override\n            public void scalar(String name, long value) {\n            }\n\n            @Override\n            public void scalar(String name, double value) {\n            }\n\n            @Override\n            public void scalar(String name, String value) {\n            }\n\n            @Override\n            public void nil(String name) {\n            }\n        });\n        if(parsed) {\n            // One complete JSON value was successfully parsed from the input\n        }\n        else {\n            // EOF has been reached on the input\n        }\n    }\n    catch(ParseJsonException e) {\n        // There was a JSON syntax error\n    }\n    catch(IOException e) {\n        // An I/O problem occurred\n    }\n\n### Streaming Pull\n\nIn this mode, Jsonification allows the user to \"pull\" parse events on\ndemand via a method call. This parser also only holds in memory the\ndata from the current event being processed, so it's also an excellent\nway to process very large JSON documents or fragments. Because this\napproach allows the user to pull events on demand, it can make JSON\nprocessing much simpler. This approach is effective when the JSON\nbeing parsed is large but the shape of the data is not known ahead of\ntime because it allows the user more freedom to apply common parsing\ntechniques, like recursive descent.\n\nSimply reading JSON events using this approach is straightforward:\n\n    try {\n        try (JsonEventParser p=new JsonEventParser(reader)) {\n            for(JsonEvent e=p.next();e!=null;e=p.next()) {\n                switch(e.getType()) {\n                case OPEN_OBJECT:\n                    break;\n                case CLOSE_OBJECT:\n                    break;\n                case OPEN_ARRAY:\n                    break;\n                case CLOSE_ARRAY:\n                    break;\n                case SCALAR:\n                {\n                    switch(e.getValue().getFlavor()) {\n                    case NUMBER:\n                        break;\n                    case BOOLEAN:\n                        break;\n                    case STRING:\n                        break;\n                    case NULL:\n                        break;\n                    default:\n                        throw new RuntimeException(\"unrecognized JSON scalar value type: \"+e.getValue().getFlavor());\n                    }\n                } break;\n                case NULL:\n                    break;\n                default:\n                    throw new RuntimeException(\"unrecognized JSON event type: \"+e.getType());\n                }\n            }\n            // EOF has been reached on the input\n        }\n    }\n    catch(ParseJsonException e) {\n        // There was a JSON syntax error\n    }\n    catch(IOException e) {\n        // An I/O problem occurred\n    }\n\nThe event parser also offers methods for a more direct idiom for\nparsing JSON that is more convenient when you know the shape of the\ndata you're parsing. Because the parsing is incremental, this approach\nworks even for very large JSON documents. This also allows the user to\ndefine methods or classes that parse a known data type from a stream\non demand, which often simplifies parsing tremendously.\n\n    try {\n        try (JsonEventParser p=new JsonEventParser(reader)) {\n            p.openObject();\n\n            long id=p.scalar(\"id\").getValue().asNumber().longVal();\n\n            String name=p.scalar(\"name\").getValue().asString().stringVal();\n\n            Set\u003cString\u003e tags=new LinkedHashSet\u003c\u003e();\n            p.openArray(\"tags\");\n            while(p.peek().getType() != JsonEvent.Type.CLOSE_ARRAY)\n                tags.add(p.scalar().getValue().asString().stringVal();\n            p.closeArray();\n \n            p.closeObject();\n\n            // Assert that EOF has been reached. Not required.\n            p.eof();\n        }\n    }\n    catch(ParseJsonException e) {\n        // There was a JSON syntax error, or unexpected input was received\n    }\n    catch(IOException e) {\n        // An I/O problem occurred\n    }\n\nThere is a corresponding event-based approach to writing JSON that is\ndescribed below.\n\n### Tree Model\n\nIn this mode, Jsonification will parse a single JSON document or\nfragment into a `JsonValue` object. This approach loads an entire\ndocument into memory, so it should not be used with documents that are\nlarge or of an unknown size, but it's a great way to work with small\nJSON snippets quickly and easily.\n\n    try {\n        JsonValue value=Json.parse(reader);\n        if(value != null) {\n            // One complete JSON value was successfully parsed from the input\n        }\n        else {\n            // EOF has been reached on the input\n        }\n    }\n    catch(ParseJsonException e) {\n        // There was a JSON syntax error\n    }\n    catch(IOException e) {\n        // An I/O problem occurred\n    }\n    \n### Value Model\n\nIn this mode, Jsonification will generate parse events from an\nexisting `JsonValue` as if they were being read from input. This\napproach allows users to construct values and play them back as events\nfor consistency during serialization. Just like any other\n`JsonParser`, this parser can be converted into an event parser.\n\n    try {\n        try (JsonParser p=Json.newValueParser(value)) {\n            boolean parsed=p.parse(new JsonParser.Handler() {\n                @Override\n                public void openObject(String name) {\n                }\n\n                @Override\n                public void closeObject() {\n                }\n    \n                @Override\n                public void openArray(String name) {\n                }\n\n                @Override\n                public void closeArray() {\n                }\n\n                @Override\n                public void scalar(String name, boolean value) {\n                }\n\n                @Override\n                public void scalar(String name, long value) {\n                }\n\n                @Override\n                public void scalar(String name, double value) {\n                }\n\n                @Override\n                public void scalar(String name, String value) {\n                }\n\n                @Override\n                public void nil(String name) {\n                }\n            });\n            if(parsed) {\n                // One complete JSON value was successfully parsed from the\n                // input\n            }\n            else {\n                // EOF has been reached on the input\n            }\n        }\n    }\n    catch(IOException e) {\n        // An error occurred\n    }\n\n## Writing JSON\n\nJsonification offers two ways to emit JSON data. Like the approaches\nJsonification offers to read JSON, the two approaches to writing JSON\nare designed to allow users to manipulate JSON in ways that feel most\nnatural in the context of their own programs.\n\n### Streaming Push\n\nIn this mode, Jsonification allows the users to \"push\" parse events to\nbe written on demand via method call. This generator writes events\ndirectly to the underlying stream, so it's an excellent way to\ngenerate very large JSON documents or fragments without keeping the\nentire document in memory.\n\n    try {\n        try (JsonGenerator g=new JsonGenerator(writer)) {\n            g.openObject();\n\n            g.scalar(\"id\", id);\n\n            g.scalar(\"name\", name);\n\n            g.openArray(\"tags\");\n            for(String tag : tags)\n            g.closeArray();\n \n            g.closeObject();\n        }\n    }\n    catch(GenerateJsonException e) {\n        // The user attempted to generate JSON that would not be syntactically\n        // valid\n    }\n    catch(IOException e) {\n        // An I/O problem occurred\n    }\n\nThere is a corresponding event-based approach to reading JSON that is\ndescribed above.\n\n### Tree Model\n\nIn this mode, Jsonification will generate a JSON document to an\nunderlying stream. This approach requires the entire JSON document to\nexist in memory, so it's not suitable for large documents, but for\nsmall documents or data already loaded into memory, it's a great way\nto work with JSON.\n\n    try {\n        try (JsonTreeGenerator g=new JsonTreeGenerator(writer)) {\n            g.emit(value);\n        }\n    }\n    catch(IOException e) {\n        // An I/O problem occurred\n    }\n\n## Manipulating JSON Trees\n\nJsonification's `JsonValue` class was carefully designed to make\nmanipulating JSON simple and natural. Custom `JsonExceptions` are used\n(as opposed to builtin exceptions like `NullPointerException` or\n`ClassCastException`) to make it easier for the user to recognize and\nfix issues related to JSON processing (as opposed to errors in other\nprogram logic) quickly.\n\nFor example, if you were working directly with the [Twitter REST\nAPI](https://dev.twitter.com/rest/public) and had just received [an\nAPI response containing a user\nobject](https://dev.twitter.com/rest/reference/get/users/show), then\nthis snippet would allow you to pull out specific fields quickly:\n\n    String userJsonResponse=getUserDataFromTwitter(\"twitterdev\");\n    JsonObject o=Json.parse(userJsonResponse).asObject();\n    long id=o.get(\"id\").asScalar().asNumber().longVal(); // 2244994945\n    String screenName=o.get(\"screen_name\").asScalar().asString().stringVal();\n    int followers=o.get(\"followers_count\").asScalar().asNumber().intVal(); // 143916\n    boolean following=o.get(\"following\").asScalar().asBoolean().booleanVal(); // false\n    \n## Maven\n\nThe latest version of Jsonification is available from Maven Central at\nthe following coordinates:\n\n    \u003cdependency\u003e\n        \u003cgroupId\u003ecom.sigpwned\u003c/groupId\u003e\n        \u003cartifactId\u003ejsonification\u003c/artifactId\u003e\n        \u003cversion\u003e3.0.5\u003c/version\u003e\n    \u003c/dependency\u003e\n","funding_links":[],"categories":[],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fsigpwned%2Fjsonification","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fsigpwned%2Fjsonification","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fsigpwned%2Fjsonification/lists"}