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. JSON is often used in Ajax applications, configurations, databases, and RESTful web services. The Java API for JSON Processing provides portable APIs to parse, generate, transform, and query JSON.
Using Jackson Object Mapper
Section titled “Using Jackson Object Mapper”Pojo Model
public class Model { private String firstName; private String lastName; private int age; /* Getters and setters not shown for brevity */}Example: String to Object
Model outputObject = objectMapper.readValue( "{\"firstName\":\"John\",\"lastName\":\"Doe\",\"age\":23}", Model.class);System.out.println(outputObject.getFirstName());//result: JohnExample: Object to String
String jsonString = objectMapper.writeValueAsString(inputObject));//result: {"firstName":"John","lastName":"Doe","age":23}Details
Section titled “Details”Import statement needed:
import com.fasterxml.jackson.databind.ObjectMapper;Maven dependency: jackson-databind
ObjectMapper instance
Section titled “ObjectMapper instance”//creating oneObjectMapper objectMapper = new ObjectMapper();ObjectMapperis threadsafe- recommended: have a shared, static instance
Deserialization:
Section titled “Deserialization:”<T> T readValue(String content, Class<T> valueType)valueTypeneeds to be specified — the return will be of this type
-
- `IOException` - in case of a low-level I/O problem
- `JsonParseException` - if underlying input contains invalid content
- `JsonMappingException` - if the input JSON structure does not match object structure
- Throws
-
- `JsonProcessingException` in case of an error
- Note: prior to version 2.1, throws clause included IOException; 2.1 removed it.
TypeReferenceshould be instantiated using anonymous class- You should provide generic explicity
JSON To Object (Gson Library)
Section titled “JSON To Object (Gson Library)”Lets assume you have a class called
Personwith justnameprivate class Person {public String name;public Person(String name) {this.name = name;}}Code:
Gson gson = new Gson();String json = "{\"name\": \"John\"}";Person person = gson.fromJson(json, Person.class);System.out.println(person.name); //JohnYou must have gson library in your classpath.
JSONObject.NULL
Section titled “JSONObject.NULL”If you need to add a property with a
nullvalue, you should use the predefined static finalJSONObject.NULLand not the standard Javanullreference.JSONObject.NULLis a sentinel value used to explicitly define a property with an empty value.JSONObject obj = new JSONObject();obj.put("some", JSONObject.NULL); //Creates: {"some":null}System.out.println(obj.get("some"));//prints: nullNote
JSONObject.NULL.equals(null); //returns trueWhich is a clear violation of
Java.equals()contract:For any non-null reference value x, x.equals(null) should return false
JSON Builder - chaining methods
Section titled “JSON Builder - chaining methods”You can use method chaining while working with
JSONObjectandJSONArray.JSONObject example
JSONObject obj = new JSONObject();//Initialize an empty JSON object//Before: {}obj.put("name","Nikita").put("age","30").put("isMarried","true");//After: {"name":"Nikita","age":30,"isMarried":true}JSONArray
JSONArray arr = new JSONArray();//Initialize an empty array//Before: []arr.put("Stack").put("Over").put("Flow");//After: ["Stack","Over","Flow"]Object To JSON (Gson Library)
Section titled “Object To JSON (Gson Library)”Lets assume you have a class called
Personwith justnameprivate class Person {public String name;public Person(String name) {this.name = name;}}Code:
Gson g = new Gson();Person person = new Person("John");System.out.println(g.toJson(person)); // {"name":"John"}Of course the Gson jar must be on the classpath.
JSON Iteration
Section titled “JSON Iteration”Iterate over
JSONObjectpropertiesJSONObject obj = new JSONObject("{\"isMarried\":\"true\", \"name\":\"Nikita\", \"age\":\"30\"}");Iterator<String> keys = obj.keys();//all keys: isMarried, name & agewhile (keys.hasNext()) { //as long as there is another keyString key = keys.next(); //get next keyObject value = obj.get(key); //get next value by keySystem.out.println(key + " : " + value);//print key : value}Iterate over
JSONArrayvaluesJSONArray arr = new JSONArray(); //Initialize an empty array//push (append) some values in:arr.put("Stack");arr.put("Over");arr.put("Flow");for (int i = 0; i < arr.length(); i++) {//iterate over all valuesObject value = arr.get(i); //get valueSystem.out.println(value); //print each value}optXXX vs getXXX methods
Section titled “optXXX vs getXXX methods”JSONObjectandJSONArrayhave a few methods that are very useful while dealing with a possibility that a value your are trying to get does not exist or is of another type.JSONObject obj = new JSONObject();obj.putString("foo", "bar");// For existing properties of the correct type, there is no differenceobj.getString("foo"); // returns "bar"obj.optString("foo"); // returns "bar"obj.optString("foo", "tux"); // returns "bar"// However, if a value cannot be coerced to the required type, the behavior differsobj.getInt("foo"); // throws JSONExceptionobj.optInt("foo"); // returns 0obj.optInt("foo", 123); // returns 123// Same if a property does not existobj.getString("undefined"); // throws JSONExceptionobj.optString("undefined"); // returns ""obj.optString("undefined", "tux"); // returns "tux"The same rules apply to the
getXXX/optXXXmethods ofJSONArray.Encoding data as JSON
Section titled “Encoding data as JSON”If you need to create a
JSONObjectand put data in it, consider the following example:// Create a new javax.json.JSONObject instance.JSONObject first = new JSONObject();first.put("foo", "bar");first.put("temperature", 21.5);first.put("year", 2016);// Add a second object.JSONObject second = new JSONObject();second.put("Hello", "world");first.put("message", second);// Create a new JSONArray with some valuesJSONArray someMonths = new JSONArray(new String[] { "January", "February" });someMonths.put("March");// Add another month as the fifth element, leaving the 4th element unset.someMonths.put(4, "May");// Add the array to our objectobject.put("months", someMonths);// EncodeString json = object.toString();// An exercise for the reader: Add pretty-printing!/* {"foo":"bar","temperature":21.5,"year":2016,"message":{"Hello":"world"},"months":["January","February","March",null,"May"]}*/Decoding JSON data
Section titled “Decoding JSON data”If you need to get data from a
JSONObject, consider the following example:String json = "{\"foo\":\"bar\",\"temperature\":21.5,\"year\":2016,\"message\":{\"Hello\":\"world\"},\"months\":[\"January\",\"February\",\"March\",null,\"May\"]}";// Decode the JSON-encoded stringJSONObject object = new JSONObject(json);// Retrieve some valuesString foo = object.getString("foo");double temperature = object.getDouble("temperature");int year = object.getInt("year");// Retrieve another objectJSONObject secondary = object.getJSONObject("message");String world = secondary.getString("Hello");// Retrieve an arrayJSONArray someMonths = object.getJSONArray("months");// Get some values from the arrayint nMonths = someMonths.length();String february = someMonths.getString(1);Extract single element from JSON
Section titled “Extract single element from JSON”String json = "{\"name\": \"John\", \"age\":21}";JsonObject jsonObject = new JsonParser().parse(json).getAsJsonObject();System.out.println(jsonObject.get("name").getAsString()); //JohnSystem.out.println(jsonObject.get("age").getAsInt()); //21JsonArray to Java List (Gson Library)
Section titled “JsonArray to Java List (Gson Library)”Here is a simple JsonArray which you would like to convert to a Java
ArrayList:{"list": ["Test_String_1","Test_String_2"]}Now pass the
JsonArray‘list’ to the following method which returns a corresponding JavaArrayList:public ArrayList<String> getListString(String jsonList){Type listType = new TypeToken<List<String>>() {}.getType();//make sure the name 'list' matches the name of 'JsonArray' in your 'Json'.ArrayList<String> list = new Gson().fromJson(jsonList, listType);return list;}You should add the following maven dependency to your
POM.xmlfile:<!-- https://mvnrepository.com/artifact/com.google.code.gson/gson --><dependency><groupId>com.google.code.gson</groupId><artifactId>gson</artifactId><version>2.7</version></dependency>Or you should have the jar
com.google.code.gson:gson:jar:<version>in your classpath.Deserialize JSON collection to collection of Objects using Jackson
Section titled “Deserialize JSON collection to collection of Objects using Jackson”Suppose you have a pojo class
Personpublic class Person {public String name;public Person(String name) {this.name = name;}}And you want to parse it into a JSON array or a map of Person objects. Due to type erasure you cannot construct classes of
List<Person>andMap<String, Person>at runtime directly (and thus use them to deserialize JSON). To overcome this limitation jackson provides two approaches -TypeFactoryandTypeReference.TypeFactory
The approach taken here is to use a factory (and its static utility function) to build your type for you. The parameters it takes are the collection you want to use (list, set, etc.) and the class you want to store in that collection.
TypeReference
The type reference approach seems simpler because it saves you a bit of typing and looks cleaner. TypeReference accepts a type parameter, where you pass the desired type
List<Person>. You simply instantiate this TypeReference object and use it as your type container.Now let’s look at how to actually deserialize your JSON into a Java object. If your JSON is formatted as an array, you can deserialize it as a List. If there is a more complex nested structure, you will want to deserialize to a Map. We will look at examples of both.
Deserializing JSON array
Section titled “Deserializing JSON array”String jsonString = "[{\"name\": \"Alice\"}, {\"name\": \"Bob\"}]"TypeFactory approach
Section titled “TypeFactory approach”CollectionType listType =factory.constructCollectionType(List.class, Person.class);List<Preson> list = mapper.readValue(jsonString, listType);TypeReference approach
Section titled “TypeReference approach”TypeReference<Person> listType = new TypeReference<List<Person>>() {};List<Person> list = mapper.readValue(jsonString, listType);Deserializing JSON map
Section titled “Deserializing JSON map”String jsonString = "{\"0\": {\"name\": \"Alice\"}, \"1\": {\"name\": \"Bob\"}}"TypeFactory approach
Section titled “TypeFactory approach”CollectionType mapType =factory.constructMapLikeType(Map.class, String.class, Person.class);List<Person> list = mapper.readValue(jsonString, mapType);TypeReference approach
Section titled “TypeReference approach”TypeReference<Person> mapType = new TypeReference<Map<String, Person>>() {};Map<String, Person> list = mapper.readValue(jsonString, mapType);Details
Section titled “Details”Import statement used:
import com.fasterxml.jackson.core.type.TypeReference;import com.fasterxml.jackson.databind.ObjectMapper;import com.fasterxml.jackson.databind.type.CollectionType;Instances used:
ObjectMapper mapper = new ObjectMapper();TypeFactory factory = mapper.getTypeFactory();While
TypeReferenceapproach may look better it has several drawbacks:Failing to do so may lead to loss of generic type argument which will lead to deserialization failure.
Remarks
Section titled “Remarks”This example focuses on parsing and creating JSON in Java using various libraries such as the Google Gson library, Jackson Object Mapper, and others..
Examples using other libraries could be found here: How to parse JSON in Java
Usage example (jsonString is the input string):
Model fromJson = objectMapper.readValue(jsonString, Model.class);Method for serialization:
Section titled “Method for serialization:”String writeValueAsString(Object value)