One of the common task in Java web application, particularly the ones which
deals with RESTful web services are parsing JSON messages. Many times you
need to parse JSON to create a Java object like parsing a JSON message to
create a POJO, for example, an Order or a Book. Representing JSON in Java is easy, it's like a
String value but unfortunately, JDK doesn't provide any standard API to
parse JSON in Java. There were talks to add JSON parsing API in JDK 9 but
that didn't materialize, but you don't need to worry. There are many good
open-source JSON parsing libraries you can use to parse any kind of JSON in
your Java program.
How to parse JSON String to Object in Java?
There are multiple ways to parse JSON String to Object in Java. This process is known as JSON Deserialization because we are converting JSON String to a Java object. In this article, I'll introduce 3 essential JSON parsing libraries: Jackson, Gson, and json-simple. I'll also explain to you how
to download those libraries and how to use them to parse JSON in
Java.
1. Parsing JSON using Jackson in Java
It's pretty easy to parse JSON messages into a Java object using Jackson.
You just need to use the ObjectMapper class, which provides the readValue()
method. This method can convert JSON String to Java object, that's why it
takes JSON as a parameter and the Class instance in which you want to parse
your JSON.
Here is an example to convert our JSON String to an EBook object in Java:
ObjectMapper mapper = new ObjectMapper(); EBook effectiveJava = mapper.readValue(JSON, EBook.class);
Also, the readValue method throws IOException. I have omitted the try-catch
statement for the sake of readability but you need to either throw that
exception or catch it using the try-catch-finally block.
This is probably the single most important JSON library you should know as a
Java developer. It's feature-rich and also quite fast. Usually, you don't
need any other JSON library if you are using Jackson.
Btw, to use the Jackson library, you need to use either jackson-core.jar,
jackson-databind.jar, or jackson-annotations.jar in your classpath.
Alternatively, you can also add the following Maven dependency in your
Eclipse project's pom.xml, if you are using Maven in Eclipse:
<dependency> <groupId>com.fasterxml.jackson.core</groupId> <artifactId>jackson-databind</artifactId> <version>2.2.3</version> </dependency>
And, here is the code:
// example 1 - parsing JSON using Jackson in Java ObjectMapper mapper = new ObjectMapper(); try { EBook effectiveJava = mapper.readValue(JSON, EBook.class); System.out.println("Java object after parsing JSON using Jackson"); System.out.println(effectiveJava); } catch (IOException e) { e.printStackTrace(); }
That's all you need to parse a JSON message in Java using Jackson. Now,
let's see another powerful library to parse JSON in Java.
2. Parsing JSON using Gson in Java
The Gson is my second favorite JSON parsing library. It probably provides
the cleaner code to parse JSON in Java. With no checked exception to handle,
you literally need to follow two lines of code to parse your JSON into a
Java object.
Here I am converting our JSON message into an EBook object:
Gson gson = new Gson(); EBook effectiveJava3rdEdition = gson.fromJson(JSON, EBook.class);
The code is pretty similar to the Jackson parsing code but it's much more
readable. The fromJson() method takes a JSON string and the type of class
you want to convert the JSON string into a Java object.
Btw, you need gson.jar in your classpath to use this library. Alternatively,
you can also add the following maven dependency if you are using Maven in
your project:
<dependency> <groupId>com.google.code.gson</groupId> <artifactId>gson</artifactId> <version>2.3.1</version> </dependency>
And, here is the complete code example you can use to parse JSON messages using the Gson library
// example 2 - parsing JSON using Gson in Java Gson gson = new Gson(); EBook effectiveJava3rdEdition = gson.fromJson(JSON, EBook.class); System.out.println("Java object after parsing JSON using Gson"); System.out.println(effectiveJava3rdEdition);
That's all you will need to parse a JSON message into Java using the Gson library. Now let's see another, third way to parse JSON String to Java object.
3. Parsing JSON using json-simple in Java
The json-simple is a low-weight simple library that doesn't depend on any
other library. If the size of JAR is your concern and you are not bothered
about functionalities or features then you can use json-simple to parse JSON
in Java.
Here is an example of parsing a JSON message into a Java object. We have a
class called JSONParser which is similar to ObjectMapper of Jackson but here
we are parsing into JSONObject rather than a POJO, hence we need to extract
each attribute one by one to create a Java object.
JSONParser parser = new JSONParser(); JSONObject json = (JSONObject) parser.parse(JSON); String title = (String) json.getOrDefault("title", ""); String author = (String) json.getOrDefault("author", ""); int price = ((Long) json.getOrDefault("price", 0)).intValue(); int year = ((Long) json.getOrDefault("year", 2018)).intValue(); int edition = ((Long) json.getOrDefault("edition", 2)).intValue(); int ratings = ((Long) json.getOrDefault("ratings", 0)).intValue();
EBook effecitveJava2ndEdition = new EBook(title, author, price, year, edition, ratings);
This seems a lot of code, comparing Gson and Jackson, hence I personally
prefer Jackson.
Anyway, if you want to use the json-simple library in your project you need to
include json-simple.jar into the classpath. Alternatively, you can also use the following xml snippet to download dependency using maven:
<dependency> <groupId>com.googlecode.json-simple</groupId> <artifactId>json-simple</artifactId> <version>1.1.1</version> </dependency>
Just add this into the pom.xml of your project and Maven will do the rest. Btw,
if you want to know more about JSON, see the Beginning JSON book.
'
Java Program to Parse JSON String to Object in Java - Deserialization Example
Here is our sample example to parse a JSON String in Java using Jackson,
Gson, and json-simple libraries. You can run this program as it is by
copying it into your Eclipse IDE, though you need to add the required JAR files
for all these 3 JSON parsing libraries.
If you use Maven then you can also
add the maven dependency in your pom.xml to run this program. Maven will
then download the required JAR files from the maven central repository.
import java.io.IOException; import org.json.simple.JSONObject; import org.json.simple.parser.JSONParser; import org.json.simple.parser.ParseException; import com.fasterxml.jackson.databind.ObjectMapper; import com.google.gson.Gson; /* * Java Program to iterate over JSONObject and JSONArray of Jackson API */ public class JacksonTest { private static String JSON = "{\r\n" + " \"title\" : \"Effective Java\",\r\n" + " \"author\" : \"Joshua Bloch\",\r\n" + " \"price\" : 42,\r\n" + " \"year\" : 2018,\r\n" + " \"edition\" : 3,\r\n" + " \"ratings\" : 10\r\n" + "}"; public static void main(String args[]){ // example 1 - parsing JSON using Jackson in Java ObjectMapper mapper = new ObjectMapper(); try { EBook effectiveJava = mapper.readValue(JSON, EBook.class); System.out.println("Java object after parsing JSON using Jackson"); System.out.println(effectiveJava); } catch (IOException e) { e.printStackTrace(); } // example 2 - parsing JSON using Gson in Java Gson gson = new Gson(); EBook effectiveJava3rdEdition = gson.fromJson(JSON, EBook.class); System.out.println("Java object after parsing JSON using Gson"); System.out.println(effectiveJava3rdEdition); // example 3 - parsing JSON using JSON-Simple in Java JSONParser parser = new JSONParser(); try { JSONObject json = (JSONObject) parser.parse(JSON); String title = (String) json.getOrDefault("title", ""); String author = (String) json.getOrDefault("author", ""); int price = ((Long) json.getOrDefault("price", 0)).intValue(); int year = ((Long) json.getOrDefault("year", 2018)).intValue(); int edition = ((Long) json.getOrDefault("edition", 2)).intValue(); int ratings = ((Long) json.getOrDefault("ratings", 0)).intValue(); EBook effecitveJava2ndEdition = new EBook(title, author, price, year, edition, ratings); System.out.println("Java object after parsing JSON using json-simple"); System.out.println(effecitveJava2ndEdition); } catch (ParseException e) { e.printStackTrace(); } } } class EBook{ private String title; private String author; private int price; private int year; private int edition; private int ratings; public EBook(){ //no-arg constructor required by JSON parsing library } public EBook(String title, String author, int price, int year, int edition, int ratings) { this.title = title; this.author = author; this.price = price; this.year = year; this.edition = edition; this.ratings = ratings; } public String getTitle() { return title; } public String getAuthor() { return author; } public int getPrice() { return price; } public int getYear() { return year; } public int getEdition() { return edition; } public int getRatings() { return ratings; } public void setTitle(String title) { this.title = title; } public void setAuthor(String author) { this.author = author; } public void setPrice(int price) { this.price = price; } public void setYear(int year) { this.year = year; } public void setEdition(int edition) { this.edition = edition; } public void setRatings(int ratings) { this.ratings = ratings; } @Override public int hashCode() { final int prime = 31; int result = 1; result = prime * result + ((author == null) ? 0 : author.hashCode()); result = prime * result + edition; result = prime * result + price; result = prime * result + ratings; result = prime * result + ((title == null) ? 0 : title.hashCode()); result = prime * result + year; return result; } @Override public boolean equals(Object obj) { if (this == obj) return true; if (obj == null) return false; if (!(obj instanceof EBook)) return false; EBook other = (EBook) obj; if (author == null) { if (other.author != null) return false; } else if (!author.equals(other.author)) return false; if (edition != other.edition) return false; if (price != other.price) return false; if (ratings != other.ratings) return false; if (title == null) { if (other.title != null) return false; } else if (!title.equals(other.title)) return false; if (year != other.year) return false; return true; } @Override public String toString() { return "EBook [title=" + title + ", author=" + author + ", price=" + price + ", year=" + year + ", edition=" + edition + ", ratings=" + ratings + "]"; } } Output: Java object after parsing JSON using Jackson EBook [title=Effective Java, author=Joshua Bloch, price=42, year=2018, edition=3, ratings=10] Java object after parsing JSON using Gson EBook [title=Effective Java, author=Joshua Bloch, price=42, year=2018, edition=3, ratings=10] Java object after parsing JSON using json-simple EBook [title=Effective Java, author=Joshua Bloch, price=42, year=2018, edition=3, ratings=10]
5. Things to remember while parsing JSON in Java
Here is a list of a couple of things you should remember while parsing JSON
in Java using popular JSON parsing libraries like Jackson, Gson, and
JSON-Simple:
1. Always provide a no-argument constructor in your POJO class i.e. the
class you want to parse your JSON into. This no-arg or default constructor
is used by the JSON parsing library to create instances of your class and
without that, they can't function. Jackson will throw the following error if
your POJO doesn't contain a no-argument constructor:
com.fasterxml.jackson.databind.JsonMappingException: No suitable constructor found for type [simple type, class EBook]: can not instantiate from JSON object (need to add/enable type information?) at [Source: java.io.StringReader@5b464ce8; line: 2, column: 2] at com.fasterxml.jackson.databind .JsonMappingException.from(JsonMappingException.java:164) at com.fasterxml.jackson.databind.deser .BeanDeserializerBase.deserializeFromObjectUsingNonDefault(BeanDeserializerBase.java:984) at com.fasterxml.jackson.databind.deser .BeanDeserializer.deserializeFromObject(BeanDeserializer.java:276) at com.fasterxml.jackson.databind.deser .BeanDeserializer.deserialize(BeanDeserializer.java:121) at com.fasterxml.jackson.databind .ObjectMapper._readMapAndClose(ObjectMapper.java:2888) at com.fasterxml.jackson.databind .ObjectMapper.readValue(ObjectMapper.java:2034) at JacksonTest.main(JacksonTest.java:27)
2. Don't put the comma after the last element, I made the same mistake and
then spend a couple of minutes trying to find and fix the problem. It
usually gives the following error:
com.fasterxml.jackson.core.JsonParseException: Unexpected character ('}' (code 125)): was expecting double-quote to start field name at [Source: java.io.StringReader@19dfb72a; line: 8, column: 2] at com.fasterxml.jackson.core.JsonParser._constructError(JsonParser.java:1369) at com.fasterxml.jackson.core.base .ParserMinimalBase._reportError(ParserMinimalBase.java:532) at com.fasterxml.jackson.core.base .ParserMinimalBase._reportUnexpectedChar(ParserMinimalBase.java:453) at com.fasterxml.jackson.core.json .ReaderBasedJsonParser._handleUnusualFieldName(ReaderBasedJsonParser.java:1267) at com.fasterxml.jackson.core.json .ReaderBasedJsonParser._parseFieldName(ReaderBasedJsonParser.java:1162) at com.fasterxml.jackson.core.json .ReaderBasedJsonParser.nextToken(ReaderBasedJsonParser.java:602) at com.fasterxml.jackson.databind.deser .BeanDeserializer.deserializeFromObject(BeanDeserializer.java:288) at com.fasterxml.jackson.databind.deser .BeanDeserializer.deserialize(BeanDeserializer.java:121) at com.fasterxml.jackson.databind .ObjectMapper._readMapAndClose(ObjectMapper.java:2888) at com.fasterxml.jackson.databind.ObjectMapper.readValue(ObjectMapper.java:2034) at JacksonTest.main(JacksonTest.java:27)
Since the error message wasn't very friendly. I mean it didn't say that you
have got an extra comma after the last field, I thought to validate my JSON using
an online JSON validator tool like https://jsonlint.com, which clearly
pointed me to the error in my JSON and after correcting that i.e. removing the
comma after the last element this error disappeared.
3. When you are using the json-simple library to parse JSON in Java, make sure
you cast the numeric object into long instead of int. Trying to directly
store them into an integer variable will throw the following exception:
Exception in thread "main" java.lang.ClassCastException: java.lang.Long cannot be cast to java.lang.Integer at JacksonTest.main(JacksonTest.java:54)
But, if you have integer fields in your class like in our EBook class price,
year, edition, and ratings are all integer, then you need to call the
intValue() method of the Long class converts a Long value to int in Java.
That's all about how to parse JSON in Java. In this article, you have
learned 3 ways to parse JSON String in Java using popular libraries like
Jackson, Gson, and json-simple. Though you can use any of these libraries to
parse your JSON, I strongly recommend you to use Jackson because it is the
most popular library but also its performance is better than Gson and
json-simple for most cases.
Other JSON tutorials in Java you may like
Thanks for reading this article so far. If you like this Java JSON deserialization tutorial then please share it with your friends and colleagues. If you have any questions or feedback then please drop a note.
- How to format JSON String in Java?
- How to parse JSON using Gson?
- 20 JSON Interview Questions with Answers
- How to parse a JSON array in Java?
- How to Iterate over JSONObject in json-simple Java?
- How to return JSON from Spring MVC controller?
- How to download Jackson JAR files in Java
- How to Solve UnrecognizedPropertyException: Unrecognized field, not marked as ignorable -
- How to convert JSON to HashMap in Java?
- 10 Things Java developers should learn
- How to ignore unknown properties while parsing JSON in Java?
Thanks for reading this article so far. If you like this Java JSON deserialization tutorial then please share it with your friends and colleagues. If you have any questions or feedback then please drop a note.
No comments:
Post a Comment