How to parse json java
How to parse json java
How to parse JSON in Java
JSON (JavaScript Object Notation) is a lightweight, text-based, language-independent data exchange format that is easy for humans and machines to read and write. JSON can represent two structured types: objects and arrays. An object is an unordered collection of zero or more name/value pairs. An array is an ordered sequence of zero or more values. The values can be strings, numbers, booleans, null, and these two structured types.
Below is a simple example from Wikipedia that shows JSON representation of an object that describes a person. The object has string values for first name and last name, a number value for age, an object value representing the person’s address, and an array value of phone number objects.
JSON Processing in Java : The Java API for JSON Processing JSON.simple is a simple Java library that allow parse, generate, transform, and query JSON.
Getting Started : You need to download the json-simple-1.1 jar and put it in your CLASSPATH before compiling and running the below example codes.
Json-Simple API : It provides object models for JSON object and array structures. These JSON structures are represented as object models using types JSONObject and JSONArray. JSONObject provides a Map view to access the unordered collection of zero or more name/value pairs from the model. Similarly, JSONArray provides a List view to access the ordered sequence of zero or more values from the model.
How to Parse JSON in Java
Amir Ghahrai
In this tutorial we will look at how to parse JSON in Java using different libraries.
JSON stands for JavaScript Object Notation, and it is based on a subset of JavaScript.
As a data-exchange format, it is widely used in web programming. Here we show how to parse JSON in Java using the org.json library.
A JSON object is an unordered set of key/value pairs. A JSON array is an ordered collection of values. The values themselves could be objects or arrays.
Parse JSON Using org.json
To use org.json to parse JSON in Java, you need to add the library as a dependency. This can be fetched from Maven repository
First, we need to convert the JSON string into a JSON Object, using JSONObject class.
Also, note that “pageInfo” is a JSON Object, so we use the getJSONObject method.
Likewise, “posts” is a JSON Array, so we need to use the getJSONArray method.
Parse JSON Using Gson
In order to use Gson to parse JSON in Java, you need to add the library as a dependency. You can get the latest version from Maven repository
The below example shows how to Parse the above JSON with Gson.
Parse JSON Using JsonPATH
The above two examples require a full deserialization of the JSON into a Java object before accessing the value in the property of interest. Another alternative, which does not go this route is to use JsonPATH which is like XPath for JSON and allows traversing of JSON objects.
Like before, you need to add JsonPATH as a dependency, which can be fetched from Maven repository
For example, to parse the above JSON we can use:
Шпаргалка Java программиста 8. Библиотеки для работы с Json (Gson, Fastjson, LoganSquare, Jackson, JsonPath и другие)
В одной из моих прошлых статей я рассказывал о своем opensorce pet проекте useful-java-links, идея которого собрать как можно больше ссылок на полезные Java библиотеки и фреймворки. У него так же есть подпроект Hello World project идея которого для каждой библиотеки собрать несколько простых примеров её использования.
Проблема программистов в Java мире в том что кроме стандартной библиотеки JDK есть огромное других полезных библиотек, причем переход от одной библиотеки к другой может вызывать проблемы из-за неполной документации, отсутствия простых примеров или даже сложности понять какие зависимости нужно добавить в maven чтобы все запустилось. А на новой работе вполне могут использовать вместо твоей любимой библиотеки ту которую ты не знаешь. Идея моего проекта облегчить изучение и выбор разных библиотек.
Итак, давайте посмотрим какие известные библиотеки есть для работы с JSON в Java…
8. Работа с Json
JSON парсеры
Аналог XPath для JSON
Генерация Java классов из JSON или JSON схемы и JSON валидация
Итак, у нас восемь библиотек для сериализации и десериализации в json, две библиотеки для генерации Java классов по схеме или json файлу, одна библиотека для валидации схемы и два аналога XPath, но для json. Давайте рассмотрим каждую из них.
1. JSON парсеры
Существует три основных способа сериализации и десериализации среди указанных библиотек (от самого простого к самому сложному) и один дополнительный:
Давайте рассмотрим с чем их едят:
Data bind самый популярный и простой способ, вы просто указываете класс, который нужно преобразовать в json, может быть часть полей отмечаете аннотациями (а зачастую даже это необязательно), а библиотека сама превращает этот класс и всю его иерархию классов в json. Аналогом при работе с xml будет JAXB (Java Architecture for XML Binding)
Плюсы: наиболее простой из всех, по сути главное реализовать только Java классы, более того можно просто сгенерировать Java классы из json’a или json схемы.
Минусы: скорость и память. Большинство библиотек использует рефлексию и т.п. методы работы с Java классами (хотя не все), что очевидно не очень быстро. К тому же, весь json файл сразу превращается в Java объекты, что может просто исчерпать всю доступную память, если вы попытаетесь обработать очень большой json.
Вывод: если нет проблем с производительностью, памятью и вы не собираетесь обрабатывать многогигабайтные json’ы скорее всего самый лучший способ.
Tree Model — данный парсер представляет json в виде Java классов таких как Node или JsonElement c иерархической структурой, а уже сам программист их обходит и получает из них информацию. Данный способ похож на DOM парсеры в xml.
Плюсы: обычно быстрее первого способа и проще третьего,
Минусы: уступает Data bind по простоте, плюс ряд библиотек способен генерить классы при Data bind, а не использовать рефлексию, в этом случае то что Tree Model будет быстрее не очевидно, к тому же не решается проблема огромных файлов и ограничения памяти.
Streaming API — самый низкоуровневый способ, по сути программист сам вручную разбирает токены json’a. Зато никаких ограничений по памяти и в теории максимальная производительность.
Плюсы: производительность и минимальное потребление памяти,
Минусы: сложность использования,
1.1 Обзор библиотек
Способ | Fastjson | Gson | LoganSquare | JSON java | Moshi | Ig json parser | Jackson | Genson | JsonPath |
---|---|---|---|---|---|---|---|---|---|
1. Data bind | Да | Да | Да | — | Да | Да | Да | Да | — |
2. Tree Model | — | Да | — | Да | — | — | Да | — | — |
3. Streaming API | — | Да | — | — | — | — | Да | — | — |
4. Аналоги XPath | Да | — | — | — | — | — | — | — | Да |
5. Генерация классов для Data bind* | — | — | Да | — | — | Да | — | — | — |
6. Github’s star | 4851 | 4120 | 2188 | 1937 | 1732 | 921 | 881 | 108 | 849 |
7. Работает со static inner class** | Да | Да | Нет | — | Да | Нет | Да | Да | — |
8. Обязательность аннотаций*** | Нет | Нет | Да | — | Нет | Да | Нет | Нет | — |
По ссылкам на Да можно найти примеры использования.
* — Генерация классов для Data bind позволяет сгенерировать классы на стадии компиляции, что в теории должно давать значительный прирост производительности библиотеки,
** — Работает со static inner class имеет смысл только для случая Data bind, возможно ли сериализация и десериализация для случая статических внутренних классов (не статические внутренние классы сериализовать не рекомендуется),
*** — тоже только для случая Data bind можно ли не использовать аннотации или их использование крайне рекомендуется,
1.2 Простейшие примеры использование Data bind
Для демонстрации работы библиотек будем использовать следующий json:
И следующие Java классы (в разных примерах могут слегка отличаться наличием аннотаций, если они обязательны):
Как можно увидеть, Java классы всего лишь состоять из двух классов Human и Place, в которых храниться сообщение Hi World. Json тоже содержит эти два вложенных объекта.
Примеры использования (Data bind): Способ | Fastjson | Gson | LoganSquare | Moshi | Ig json parser | Jackson | Genson |
---|---|---|---|---|---|---|---|
Инициализация | — | Gson gson = new Gson() | — | Moshi moshi = new Moshi. Builder().build(); JsonAdapter jsonAdapter = moshi.adapter(Human.class) | — | ObjectMapper mapper = new ObjectMapper() | Genson genson = new Genson() |
Из Java в json | JSON.toJSONString(human) | gson.toJson(human) | LoganSquare.serialize(human) | jsonAdapter.toJson(human) | Human__JsonHelper.serializeToJson(human) | mapper.writeValueAsString(human) | genson.serialize(human) |
Из json в Java | JSON.parseObject(jsonString, Human.class) | gson.fromJson(jsonString, Human.class) | LoganSquare.parse(jsonString, Human.class) | jsonAdapter.fromJson(jsonString) | Human__JsonHelper.parseFromJson(jsonString) | mapper.readValue(jsonString, Human.class) | genson.deserialize(jsonString, Human.class) |
Human__JsonHelper — это класс который Ig json parser сгенерировал на этапе компиляции, у LoganSquare так же есть генерации на этапе компиляции, но там классы подключаются «под капотом» внутри LoganSquare.
Java JSON Parsers or How to Parse JSON in Java
This article is an overview of Java JSON libraries.
You’ll learn how to parse (decode) JSON in Java – string to object representation.
I’ll explain 2 approaches of parsing JSON in Java and what is a best Java JSON library for each case.
But first of all, let’s define what is a JSON and why do you need it.
JSON is a text-based data exchange format.
It defines only two data structures: objects and arrays.
An object is a set of name-value pairs, and an array is a list of values.
JSON defines seven value types: string, number, object, array, true, false, and null.
It was introduced in JavaScript world as a replacement for the XML format, but now it is widely spread.
JSON is often used as a common format to serialize and deserialize data in applications that communicate with each other over the Internet.
So it is more compact and lightweight alternative to XML and de-facto standard for REST API.
JSON Parsers in Java
There are two main approaches to generate and parse JSON in Java:
Object model:
Streaming model:
Usually, JSON Java libraries provide a quite simple processing flow:
Java API for JSON Processing
The Java API for JSON Processing (JSON-P) is described in JSR 353.
The implementation was introduced in Java EE 7.
Of course, you can use this API in Java SE environment, but in this case, you need to add to your application classpath corresponding library, that implement JSON-P API.
You can download it here:
Adding JSON-P API library in Maven environment is easy and absolutely straightforward, as usual:
Let’s create small example how to create JSON file and parse it with help of JSON-P library:
First, we create a map with configuration settings and generate JsonBuilderFactory factory, it will provide numerous builders, such as createObjectBuilder and createArrayBuilder.
Thee main JSON-P API entry point is singleton JSON class.
Next, with help of factory, we generate a JSON representation of an object, which consists all JSON types: string, number, object, array, true, false, and null.
After that, JsonObject can be used for writing with help of JsonWriter, which is once again provided by WriterFactory:
For simplicity, we are using System.out output as a target in this example.
Looks quite easy.
But be careful with BigDecimal class, use scale() method to restrict a number of digits.
As it was told before, we can use two different approaches to read values in JSON format: Streaming and Object model. JSON-P supports both of them.
Let’s try to read values we stored with help of Object model approach.
As a source we are using generated JSON we already have.
First, we need JsonWriter:
Since we have no settings for a reader, we don’t need to use a factory.
So, let’s read data from JsonReader and print it to system output:
Once again, looks simple, but pay attention to the default value, defined in methods call as the second parameter.
As you can see, we read the whole object from a reader and created JSON document’s representation JsonObject.
It gives an ability to read all supported by JSON format types, and from these pieces, we could restore quite complicated objects.
In a case when we have a huge file in JSON format, and we interesting only in small part of data, this approach is not effective.
So, Streaming API comes to the stage.
There is an example of using Streaming API:
Once again, we need a reader with JSON content and JSON class, which provide us instance of JsonParser:
We could iterate through JSON content and react to events:
there are 10 types of events:
so, for simple types such as strings and numbers, all is straightforward:
for arrays and objects situation is more complicated, lets read all string values in an array:
look at the output of example:
It returns ALL string values we have in array, including string values of object’s fields. So you should be careful, and check twice that you filtered out unnecessary data.
There is a problem in restoring objects from JSON: it is a boring, verbose and error-prone procedure. Next, we will find someone who helps us!
Jackson library
Jackson framework is famous as lightweight and fast implementation.
It provides both Streaming API and Tree Model approach to read JSON data, and it provides conversation from JSON to/from Plain Old Java Object (POJO).
For Data binding, it uses annotations and getter/setter methods.
For using Jackson library you need 3 jar files:
jackson-core.jar, jackson-annotations, jackson-databind
You can find them here: https://github.com/FasterXML/ All you need is to add them to your app classpath.
Serialize objects
Suppose, we decided to get rich and become a drug car dealer.
So, one of a task we could face is providing to ours web-client info about the car in JSON format.
Let’s create Car class, which represents a car entity, and create a string with JSON representation of Car object:
Its a magic, isn’t it?
Let’s have a look at Car, Engine and Tyre class.
Every class has getter methods for its values.
They look redundant, but if we comment at least one of them, Car.getTyres() for example, we will get:
As shown, Tyres info is gone.
Actually, Jackson framework uses getter methods of an object as one of implicit instruction how to create its JSON representation, or, in other words, to serialize it.
Suppose, we don’t need to provide Tyres field of Car object, but we need a getter for Tyres field. Jackson framework supports a flexible mechanism to customize object’s JSON representation.
So, let’s restore Car.getTyres() method, but add annotation @JsonIgnoreProperties to Car class:
The same result we can achieve by field annotation @JsonIgnore:
With help of @JsonIgnoreType annotation, we even could forbid whole class to be serialized, for example, we can mark Engine class:
in this case, Engine info will be omitted.
There are couple notes:
First, if we mark Tyres class by @JsonIgnoreType, tyres field will be present in JSON since its type is an array: Tyres[].
Second, if we have no access to class sources, and have no ability to mark it with @JsonIgnoreType we can use Jackson dark magic mixins.
For example, lets exclude Tyres[].class from serialisation:
At first, let’s create a mixin class:
add it to JSON mapper:
Jackson framework gives us really fine grade control on serializing objects.
For example, we want to filter out some data before serializing based on its value.
Suppose, we are going to serialize two instances of Cars class newCar and oldCar, and we want to serialize mileage field only if it less than 10000 miles.
If not, we just omit this info, a client should get the whole picture about a not-so-new car in increment…
As a first step, we have to create a class, that implements PropertyFilter interface.
It is convenient to use SimpleBeanPropertyFilter class, it implements PropertyFilter:
Next, we will mark Car class, that it is affected by the filter with name “mileageFilter”:
and we have to attach a created filter to FiterProvider:
so, there is full example source:
Its a magic, I told you!
Parse and bind
Another very common task you can face during implementing web application is reading JSON string and parse it to object (to deserialize it).
Jackson provides an API that looks similar to JSON-P framework.
You can use Tree Model approach. in this case, we can use Jackson Framework for creating a tree of JsonNode objects which represent JSON entities.
The framework provides an ability to traverse the tree and get values of nodes.
For example, let’s restore some values from the serialized instance of Car class:
As you can see, we can traverse tree step by step or search for JsonNode object by specific criteria.
Actually, there are tons of useful methods for searching and getting nodes value, but it is senseless to rewrite Jackson documentation here.
It is not a great surprise that restoring the Car class could be really boring and time-consuming.
So I have a good news for you – Jackson framework can do it for you itself (with your help, of course).
Let’s create a Car object and serialize it to string, as we already did. Next, we will try to de-serialize it.
ObjectMapper class has a very convenient method, it looks like something we need:
Let’s try to run it… Err… something went wrong.
It seems framework needs some our help for deserializing Car object properly.
First, we need to provide a default constructor for all classes we are going to de-serialize.
Next, we need to provide info for framework how to parse object’s properties.
The common way is getter methods.
Jackson is smart enough to resolve properties name and type from getter method.
But we should be very careful with naming convention: for example, Car’s field isNavigationSystem is not so good, it confuses Jackson, so let’s rename it:
and at last, for debugging purposes only, let’s add toString() methods to Car, Tyre and Engine classes, there is final listing:
Jackson Framework provides an ability to customize deserialization (reading JSON into Java Objects) on a per-call basis by a set of DeserializationFeatures for ObjectReader.
You can also change defaults for ObjectMapper, to be used as the base for all ObjectReader instances, using enable(feature), disable(feature) and configure(feature, state) methods.
There are plenty of features, you can check their description in Jackson Framework documentation
Conclusion
Summing it up, you could see Java provides to programmer very robust and powerful tools for processing data in JSON format.
You can use different approaches for parsing data depend on your needs and save a lot of time by implicit (but configurable) data binding and pay not too much attention to this task.
How to write a basic JSON parsing class
Could some one guide how to write a class which would take a JSON data and would try to parse it into a simple buffered list from which we could read the data back?
..will be parsed into a table of key value pairs
How to write a parse method which would help to create a faster and simpler?
Kindly do not suggest any existing library. Provide a concept for parsing JSON.
4 Answers 4
Trending sort
Trending sort is based off of the default sorting method — by highest score — but it boosts votes that have happened recently, helping to surface more up-to-date answers.
It falls back to sorting by highest score if no posts are trending.
Switch to Trending sort
This answer assumes that you really want to write a parser and are prepared to put in the effort required.
You MUST start with the formal specification of JSON. I have found http://www.ietf.org/rfc/rfc4627.txt. This defines the language precisely. You MUST implement everything in the spec and write tests for it. Your parser MUST cater for incorrect JSON (like yours) and throw Exceptions.
You MUST write code that conforms. Here are some phrases from the spec. If you don’t understand them you will have to research carefully and make sure you understand:
«JSON text SHALL be encoded in Unicode. The default encoding is UTF-8.»
«A JSON parser MUST accept all texts that conform to the JSON grammar.»
«Encoding considerations: 8bit if UTF-8; binary if UTF-16 or UTF-32
«Any character may be escaped. If the character is in the Basic
Multilingual Plane (U+0000 through U+FFFF), then it may be
represented as a six-character sequence: a reverse solidus, followed
by the lowercase letter u, followed by four hexadecimal digits that
encode the character’s code point. The hexadecimal letters A though
F can be upper or lowercase. So, for example, a string containing
only a single reverse solidus character may be represented as
«\u005C». «
If you understand these and still want to write a parser, then review some other parsers, and see if any of them have conformance tests. Borrow these for your own application.
If you are still keen you should strongly consider using a parser generator. Examples are JAVACC, CUP and my preferred tool, ANTLR. ANTLR is very powerful but can be difficult to start with. See also the suggestion of Parboiled, which I would now recommend. JSON is relatively simple and it would be a useful exercise. Most parser-generators generate a complete parser which can create executable code or generate the parse tree of your JSON.
There is a JSON parser-generator using ANTLR at http://www.antlr.org/wiki/display/ANTLR3/JSON+Interpreter if you are allowed to peek at it. I have also just discovered a Parboiled parser-generator for JSON. If your main reason for writing a parser is learning how to do it, this is probably a good starting point.
If you are not allowed (or don’t want to) use a parser-generator then you will have to create your own parser. This generally comes in two parts:
a lexer/tokenizer. This recognizes the basic primitives defined in the language spec. In this case it would have to recognize curly-brackets, quotes, etc. It would probably also build the representation of numbers.
an AbstractSyntaxTree (http://en.wikipedia.org/wiki/Abstract_syntax_tree, AST) generator. Here you write code to assemble a tree representing the abstraction of your JSON (e.g. whitespace and curlies have been discarded).
When you have the AST it should be easy to iterate over the nodes and create your desired output.
But writing parser-generators, even for a simple language like JSON, is a lot-of-work.