How to store values using Jackson JSON to Java - java

I am having a really hard time understanding how to place a mapped valued into an array and how to iterate that array.
test.json
[
{
"Name": "Bob",
"Nationality": "",
"City": "Chicago",
"Phone" : "451232424234"
},
......continues with more objects
]
testTemplate.java
//imports
#JSONInclude(Json.Include.Non_NULL)
#JsonPropertyOrder({"Name,"Nationality","City","Phone"})
Public class testTemplate {
#JsonProperty("Name")
private String userName;
#JsonProperty("Nationality")
private String nation;
#JsonProperty("City")
private String city;
#JsonProperty("Phone")
private String phone;
#JsonProperty("Name")
public String getName (String userName) {
this.userName = userName;
}
#JsonProperty("Nationality")
public String nation (String nation) {
this.nation = nation;
}
#JsonProperty("City")
public String city (String city) {
this.city = city;
}
#JsonProperty("Phone")
public String phone (String phone) {
this.phone = phone;
}
public String toString() {
return ToStringBuilder.reflectionToString(this);
}
testParse.java
Public Class testParse {
List<testParse> test;
ObjectMapper mapper;
protected void setUp() throws IOException {
mapper = new ObjectMapper();
mapper.enable(SerializationFeature.INDENT_OUTPUT();
test = mapper.readValue(this.getClass().getResourcesAsStream("test.json"),
mapper.getTypeFactory().constructCollectionType(List.class, testParse.class));
I need to help first clarifying exactly what the code is doing, and how to put JSON properties (Name, Nationality,City,Phone) into Java.
My understanding is the testTemplate file create the strings in which the properties will be held, then the testParse file has the mapper feature (from Jackson) that reads through the json and puts all into "test" (as an array?)
My goal is in testParse, where if everything thing is in "test", then I read through that, and start to pull it out and place it into a folderList.
public static Map<String, String> userName throws IOException {
Map<String, String> folderList = new TreeMap<>();
//Don't know how, but iterate through "test"
LineIterator it = new LineIterator(//the method used to read the json file);
try {
while(it.hasNext()) {
String line = it.nextLine();
folderList.put(userName,nation) //can I also put city and phone at once as well or should I create another put: folderList.put(userName, city)
return folderList;
How does one do this? Is there a better way to put the properties of json into the folderList after using the jackson mapper?

Actually, testTemplate don't generate anything, what Jackson have done here is just get data from "test.json" as String, then using Reflection read the format of testTemplate.java. Based on template it've just have + setting you add to ObjectMapper object, Jackson will convert test.json to array of object Java.
P/S: you don't need to add annotation in both attributes and get function of POJO class, just do it in get function or attributes only, it's enough for Jackson.

Related

How to sort and create hash string using LinkedHashMap?

I am developing an application within that I have to create the SHA256 hash for the incoming data. To make that I have to follow the specific sorting order for each property. Hence, I have created a class TemplateNodeMap which extends LinkedHashMap, within that I have specified the order that I need to follow.
Now, I would like to read each property in the incoming JSON data, add a specific field, and create the Hash string. I am a bit confused about adding the data and creating the string. I am worried if I am following the optimal procedure or not as I need to follow the process for a large amount of data.
Can someone please let me know if this is the right approach?
Following is the incoming JSON (Since JSON can have any order I need to obtain properties according to my required Hash String order):
{
"age": 30,
"name": "Batman",
"address": {
"city": "Gotham",
"street": {
"name": "Gotham 123"
}
}
}
Following is my TemplateNodeMap class:
package io.hash;
import java.util.LinkedHashMap;
public class TemplateNodeMap extends LinkedHashMap {
public TemplateNodeMap() {
put("name", null);
put("age", null);
put("address", new LinkedHashMap<>() {{
put("street", new LinkedHashMap<>() {{
put("name", null);
}});
put("city", null);
}});
}
}
Following is my ApplicationMain class which is reading and loading the data to TemplateNodeMap:
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.node.ObjectNode;
import java.io.IOException;
import java.io.InputStream;
public class ApplicationMain {
public static void main(String[] args) throws IOException {
final ObjectMapper objectMapper = new ObjectMapper();
final InputStream jsonStream = ApplicationMain.class.getResourceAsStream("/InputJSON.json");
final ObjectNode inputTemplate = objectMapper.readValue(jsonStream, ObjectNode.class);
System.out.println(objectMapper.writerWithDefaultPrettyPrinter().writeValueAsString(inputTemplate));
final TemplateNodeMap templateNodeMap = new TemplateNodeMap();
templateNodeMap.put("name", inputTemplate.get("name"));
templateNodeMap.put("age", inputTemplate.get("age"));
//Unable to understand how to insert the complex object values into LinkedHashMap and follow the order
}
}
I am not understanding how to add the complex object to LinkedHashMap and create a string out of it.
Not all fields are mandatory so I would like to omit the null values during the creation of Hash String.
Can someone please suggest to me how to achieve this and if this is the right approach to creating a Hash String based on the required order?
There are two jackson annotations that can help you to serialize the jackson properties in a custom order excluding the non null values:
JsonPropertyOrder annotation that can be used to define ordering (possibly partial) to use when serializing object properties.
JsonInclude annotation used to indicate when value of the annotated property, or all properties of the annotated class, is to be serialized.
You can then deserialize your json to the pojo java classes and then serialize them obtaining a new json with the expected order of the properties and without null properties:
#Data
#JsonPropertyOrder(value = {"name", "age", "address"})
#JsonInclude(JsonInclude.Include.NON_NULL)
public class Person {
private int age;
private String name;
private Address address;
}
#Data
#JsonPropertyOrder(value = {"street", "city"})
#JsonInclude(JsonInclude.Include.NON_NULL)
public class Address {
private String city;
private Street street;
}
#Data
#JsonInclude(JsonInclude.Include.NON_NULL)
public class Street {
private String name;
}
//you can delete for example the name property from your json
Person person = mapper.readValue(json, Person.class);
String output = mapper.writerWithDefaultPrettyPrinter().writeValueAsString(person);
//ok, the name property will not appear in the output because it's null
System.out.println(output);
Requirements:
"I am developing an application within that I have to create the SHA256 hash for the incoming data."
"To make that I have to follow the specific sorting order for each property."
Proposal:
Create data classes for your incoming data, order their attributes as you like
Transform data class into a 'standard' JSON representation using prettyprint
Calculate hash over 'standard' JSON representation
For completeness a manual parsing of the linked hashmap is included
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.node.ObjectNode;
import java.io.*;
import java.nio.*;
import java.nio.charset.StandardCharsets;
import java.security.*;
import java.util.*;
class Person {
int age; String name; Address address; // Attribute order effects output order!
public Person(){}
public Person(int age, String name, Address address) {
this.age = age; this.address = address; this.name = name;
}
public void setAge(int age){this.age = age;}
public int getAge(){return age;}
public void setName(String name){this.name = name;}
public String getName(){return name;}
public void setAddress(Address address){this.address = address;}
public Address getAddress(){return address;}
}
class Address {
String city;
Street street;
public Address(){}
public Address(String city, Street street){this.city = city; this.street = street;}
public void setCity(String city){this.city = city;}
public String getCity(){return city;}
public void setStreet(Street street){this.street = street;}
public Street getStreet(){return street;}
}
class Street {
String name;
public Street(){}
public Street(String name) {this.name = name;}
public String getName(){return name;}
public void setName(String name) {this.name = name;}
}
public class ApplicationMain {
static String inputJson = "{\"age\": 30,\"name\": \"Batman\",\"address\": {\"city\": \"Gotham\",\"street\": {\"name\": \"Gotham 123\"}}}";
public static void main(String[] args) throws IOException, NoSuchAlgorithmException {
final ObjectMapper objectMapper = new ObjectMapper();
try {
// use Paths.get("InputJSON.json").toFile() as alternative to the string
Map<?, ?> map = objectMapper.readValue(inputJson, Map.class);
System.out.println("The linked hashmap to process for sorting:");
System.out.println(map);
System.out.println("Individual elements:");
System.out.println("name: " + map.get("name"));
System.out.println("age: " + map.get("age"));
System.out.println("address:");
Map<?, ?> addressMap = (Map<?, ?>)map.get("address");
System.out.println(" city: " + addressMap.get("city"));
System.out.println(" street:");
System.out.println(" name: " + ((Map<?, ?>)addressMap.get("street")).get("name"));
} catch (Exception ex) {
ex.printStackTrace();
}
Person person = objectMapper.readValue(inputJson, Person.class);
System.out.println("Original JSON:\n" + inputJson);
String prettyJson = objectMapper.writerWithDefaultPrettyPrinter().writeValueAsString(person);
System.out.println("Standardized JSON:\n" + prettyJson);
byte[] hash = MessageDigest.getInstance("SHA-256").digest(prettyJson.getBytes(StandardCharsets.UTF_8));
for ( byte b : hash) {
System.out.printf("%02x", b);
}
System.out.println();
}
}
$ java -cp .:jackson-databind-2.13.3.jar:jackson-core-2.13.3.jar:jackson-annotations-2.13.3.jar ApplicationMain
The linked hashmap to process for sorting:
{age=30, name=Batman, address={city=Gotham, street={name=Gotham 123}}}
Individual elements:
name: Batman
age: 30
address:
city: Gotham
street:
name: Gotham 123
Original JSON:
{"age": 30,"name": "Batman","address": {"city": "Gotham","street": {"name": "Gotham 123"}}}
Standardized JSON:
{
"age" : 30,
"name" : "Batman",
"address" : {
"city" : "Gotham",
"street" : {
"name" : "Gotham 123"
}
}
}
5f962abf0cdc5150eb2614c629592d889d59b82499b13dd1b8d12e421bb0440a
$
You can check the hash value at https://dencode.com/hash
(The link already contains the JSON data. If you paste text there, verify that the correct line ending type is selected.)

Converting json string to generic Map using Jackson

I am getting the following object from a different service and I need to parse it into a POJO I have in my service. The incoming object looks like:
AddressMessage.java
public class AddressMessage {
#NotEmpty
#JsonProperty("id")
private String id;
#NotEmpty
#JsonProperty("address")
private String address;
public String getId() {
return this.id;
}
public String getAddress() {
return this.address;
}
#SuppressWarnings("unchecked")
#JsonProperty("data")
public void unpackNested(Map<String, Object> rawMessage) {
Map<String, String> data = (Map<String, String>) rawMessage.get("data");
this.id = (String) data.get("id");
this.address = (String) data.get("address");
}
}
and the incoming data looks like:
{“data”: { “id” : “sampleId”, “address”: “sampleAddress” }}
I've tried parsing the incoming json string to a plain Object but that didn't work:
private void publishMessage(String rawMessage, AMQP.BasicProperties props) throws IOException {
Object json = objectMapper.readValue(rawMessage, Object.class);
log.debug(objectMapper.writeValueAsString(json));
I also tried taking in the raw message and mapping it directly to the class using the object mapper like this:
private void publishMessage(String rawMessage, AMQP.BasicProperties props) throws IOException {
AddressMessage addressMessage = objectMapper.readValue(rawMessage,
AddressMessage.class);
}
Exception for above code:
Unexpected character ('“' (code 8220 / 0x201c)): was expecting double-quote to start field name
I want to pull the "id" and "address" properties out of the object but I keep running into exception due to parsing errors. Some guidance will be greatly appreciated, thanks!
Addition: I am not currently using the "unpackNested" method but thought i'd throw it in there in case it sparks any idea
You can use the #JsonCreator annotation on a constructor like this:
#JsonCreator
public AddressMessage(#JsonProperty("data") Map<String, Object> rawJson) {
this.id = rawJson.get("id").toString();
this.address = rawJson.get("address").toString();
}
This tells Jackson to use that constructor when deserializing.

How to deserialize Json with Java from Url [duplicate]

I want to be able to access properties from a JSON string within my Java action method. The string is available by simply saying myJsonString = object.getJson(). Below is an example of what the string can look like:
{
'title': 'ComputingandInformationsystems',
'id': 1,
'children': 'true',
'groups': [{
'title': 'LeveloneCIS',
'id': 2,
'children': 'true',
'groups': [{
'title': 'IntroToComputingandInternet',
'id': 3,
'children': 'false',
'groups': []
}]
}]
}
In this string every JSON object contains an array of other JSON objects. The intention is to extract a list of IDs where any given object possessing a group property that contains other JSON objects. I looked at Google's Gson as a potential JSON plugin. Can anyone offer some form of guidance as to how I can generate Java from this JSON string?
I looked at Google's Gson as a potential JSON plugin. Can anyone offer some form of guidance as to how I can generate Java from this JSON string?
Google Gson supports generics and nested beans. The [] in JSON represents an array and should map to a Java collection such as List or just a plain Java array. The {} in JSON represents an object and should map to a Java Map or just some JavaBean class.
You have a JSON object with several properties of which the groups property represents an array of nested objects of the very same type. This can be parsed with Gson the following way:
package com.stackoverflow.q1688099;
import java.util.List;
import com.google.gson.Gson;
public class Test {
public static void main(String... args) throws Exception {
String json =
"{"
+ "'title': 'Computing and Information systems',"
+ "'id' : 1,"
+ "'children' : 'true',"
+ "'groups' : [{"
+ "'title' : 'Level one CIS',"
+ "'id' : 2,"
+ "'children' : 'true',"
+ "'groups' : [{"
+ "'title' : 'Intro To Computing and Internet',"
+ "'id' : 3,"
+ "'children': 'false',"
+ "'groups':[]"
+ "}]"
+ "}]"
+ "}";
// Now do the magic.
Data data = new Gson().fromJson(json, Data.class);
// Show it.
System.out.println(data);
}
}
class Data {
private String title;
private Long id;
private Boolean children;
private List<Data> groups;
public String getTitle() { return title; }
public Long getId() { return id; }
public Boolean getChildren() { return children; }
public List<Data> getGroups() { return groups; }
public void setTitle(String title) { this.title = title; }
public void setId(Long id) { this.id = id; }
public void setChildren(Boolean children) { this.children = children; }
public void setGroups(List<Data> groups) { this.groups = groups; }
public String toString() {
return String.format("title:%s,id:%d,children:%s,groups:%s", title, id, children, groups);
}
}
Fairly simple, isn't it? Just have a suitable JavaBean and call Gson#fromJson().
See also:
Json.org - Introduction to JSON
Gson User Guide - Introduction to Gson
Bewaaaaare of Gson! It's very cool, very great, but the second you want to do anything other than simple objects, you could easily need to start building your own serializers (which isn't that hard).
Also, if you have an array of Objects, and you deserialize some json into that array of Objects, the true types are LOST! The full objects won't even be copied! Use XStream.. Which, if using the jsondriver and setting the proper settings, will encode ugly types into the actual json, so that you don't loose anything. A small price to pay (ugly json) for true serialization.
Note that Jackson fixes these issues, and is faster than GSON.
Oddly, the only decent JSON processor mentioned so far has been GSON.
Here are more good choices:
Jackson (Github) -- powerful data binding (JSON to/from POJOs), streaming (ultra fast), tree model (convenient for untyped access)
Flex-JSON -- highly configurable serialization
EDIT (Aug/2013):
One more to consider:
Genson -- functionality similar to Jackson, aimed to be easier to configure by developer
Or with Jackson:
String json = "...";
ObjectMapper m = new ObjectMapper();
Set<Product> products = m.readValue(json, new TypeReference<Set<Product>>() {});
Easy and working java code to convert JSONObject to Java Object
Employee.java
import java.util.HashMap;
import java.util.Map;
import javax.annotation.Generated;
import com.fasterxml.jackson.annotation.JsonAnyGetter;
import com.fasterxml.jackson.annotation.JsonAnySetter;
import com.fasterxml.jackson.annotation.JsonIgnore;
import com.fasterxml.jackson.annotation.JsonInclude;
import com.fasterxml.jackson.annotation.JsonProperty;
import com.fasterxml.jackson.annotation.JsonPropertyOrder;
#JsonInclude(JsonInclude.Include.NON_NULL)
#Generated("org.jsonschema2pojo")
#JsonPropertyOrder({
"id",
"firstName",
"lastName"
})
public class Employee {
#JsonProperty("id")
private Integer id;
#JsonProperty("firstName")
private String firstName;
#JsonProperty("lastName")
private String lastName;
#JsonIgnore
private Map<String, Object> additionalProperties = new HashMap<String, Object>();
/**
*
* #return
* The id
*/
#JsonProperty("id")
public Integer getId() {
return id;
}
/**
*
* #param id
* The id
*/
#JsonProperty("id")
public void setId(Integer id) {
this.id = id;
}
/**
*
* #return
* The firstName
*/
#JsonProperty("firstName")
public String getFirstName() {
return firstName;
}
/**
*
* #param firstName
* The firstName
*/
#JsonProperty("firstName")
public void setFirstName(String firstName) {
this.firstName = firstName;
}
/**
*
* #return
* The lastName
*/
#JsonProperty("lastName")
public String getLastName() {
return lastName;
}
/**
*
* #param lastName
* The lastName
*/
#JsonProperty("lastName")
public void setLastName(String lastName) {
this.lastName = lastName;
}
#JsonAnyGetter
public Map<String, Object> getAdditionalProperties() {
return this.additionalProperties;
}
#JsonAnySetter
public void setAdditionalProperty(String name, Object value) {
this.additionalProperties.put(name, value);
}
}
LoadFromJSON.java
import org.codehaus.jettison.json.JSONObject;
import com.fasterxml.jackson.databind.ObjectMapper;
public class LoadFromJSON {
public static void main(String args[]) throws Exception {
JSONObject json = new JSONObject();
json.put("id", 2);
json.put("firstName", "hello");
json.put("lastName", "world");
byte[] jsonData = json.toString().getBytes();
ObjectMapper mapper = new ObjectMapper();
Employee employee = mapper.readValue(jsonData, Employee.class);
System.out.print(employee.getLastName());
}
}
If, by any change, you are in an application which already uses http://restfb.com/ then you can do:
import com.restfb.json.JsonObject;
...
JsonObject json = new JsonObject(jsonString);
json.get("title");
etc.
HashMap keyArrayList = new HashMap();
Iterator itr = yourJson.keys();
while (itr.hasNext())
{
String key = (String) itr.next();
keyArrayList.put(key, yourJson.get(key).toString());
}
Depending on the input JSON format(string/file) create a jSONString. Sample Message class object corresponding to JSON can be obtained as below:
Message msgFromJSON = new ObjectMapper().readValue(jSONString, Message.class);
If you use any kind of special maps with keys or values also of special maps, you will find it's not contemplated by the implementation of google.
What's wrong with the standard stuff?
JSONObject jsonObject = new JSONObject(someJsonString);
JSONArray jsonArray = jsonObject.getJSONArray("someJsonArray");
String value = jsonArray.optJSONObject(i).getString("someJsonValue");
Pass your JSON file in this way, it will return the object.
File file = new File("D:\\Coding\\tickets\\temp.json");
ObjectMapper om = new ObjectMapper();
Profile profile = om.readValue(file, new TypeReference<Profile>() {});
Give boon a try:
https://github.com/RichardHightower/boon
It is wicked fast:
https://github.com/RichardHightower/json-parsers-benchmark
Don't take my word for it... check out the gatling benchmark.
https://github.com/gatling/json-parsers-benchmark
(Up to 4x is some cases, and out of the 100s of test. It also has a index overlay mode that is even faster. It is young but already has some users.)
It can parse JSON to Maps and Lists faster than any other lib can parse to a JSON DOM and that is without Index Overlay mode. With Boon Index Overlay mode, it is even faster.
It also has a very fast JSON lax mode and a PLIST parser mode. :) (and has a super low memory, direct from bytes mode with UTF-8 encoding on the fly).
It also has the fastest JSON to JavaBean mode too.
It is new, but if speed and simple API is what you are looking for, I don't think there is a faster or more minimalist API.
The easiest way is that you can use this softconvertvalue method which is a custom method in which you can convert jsonData into your specific Dto class.
Dto response = softConvertValue(jsonData, Dto.class);
public static <T> T softConvertValue(Object fromValue, Class<T> toValueType)
{
ObjectMapper objMapper = new ObjectMapper();
return objMapper
.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false)
.convertValue(fromValue, toValueType);
}
<!-- GSON -->
<dependency>
<groupId>com.google.code.gson</groupId>
<artifactId>gson</artifactId>
<version>2.8.7</version>
</dependency>
#Test
void readListJsonFromFileTest() throws IOException {
Type type = new TypeToken<List<SimplePojo>>(){}.getType();
String fromJsonFile = readFromJsonFile("json/simplePojoJsonList.json");
List<SimplePojo> pojoList = gson.fromJson(fromJsonFile, type);
Assertions.assertNotNull(pojoList);
}
#Test
void readJsonFromFileTest() throws IOException {
Type type = new TypeToken<SimplePojo>(){}.getType();
String fromJsonFile = readFromJsonFile("json/simplePojoJson.json");
SimplePojo simplePojo = gson.fromJson(fromJsonFile, type);
Assertions.assertNotNull(simplePojo);
}
String readFromJsonFile(String pathToJson) throws IOException {
InputStream resource = new ClassPathResource(pathToJson).getInputStream();
String json = StreamUtils.copyToString(resource, StandardCharsets.UTF_8);
return json;
}

How to use Jackson Annotation to do a mapping

Simply I have a POJO like this:
#JsonInclude(value=Include.NON_EMPTY)
public class Contact {
#JsonProperty("email")
private String email;
#JsonProperty("firstName")
private String firstname;
#JsonIgnore
private String subscriptions[];
...
}
When I create the JSON object using the JsonFactory and ObjectMapper, it would be something like:
{"email":"test#test.com","firstName":"testName"}
Now, the question is how can I generate something like the following without manual mapping.
{"properties": [
{"property": "email", "value": "test#test.com"},
{"property": "firstName", "value": "testName"}
]}
Note that, I know how to do manual mapping. Also, I need to use some features like Include.NON_EMPTY.
You can implement two steps processing as follows.
Firstly, you convert your bean instance to a JsonNode instance using ObjectMapper. This guaranties applying all the Jackson annotations and customization. Secondly, you manually map the JsonNode fields to your "property-object" model.
Here is an example:
public class JacksonSerializer {
public static class Contact {
final public String email;
final public String firstname;
#JsonIgnore
public String ignoreMe = "abc";
public Contact(String email, String firstname) {
this.email = email;
this.firstname = firstname;
}
}
public static class Property {
final public String property;
final public Object value;
public Property(String property, Object value) {
this.property = property;
this.value = value;
}
}
public static class Container {
final public List<Property> properties;
public Container(List<Property> properties) {
this.properties = properties;
}
}
public static void main(String[] args) throws JsonProcessingException {
Contact contact = new Contact("abc#gmail.com", "John");
ObjectMapper mapper = new ObjectMapper();
JsonNode node = mapper.convertValue(contact, JsonNode.class);
Iterator<String> fieldNames = node.fieldNames();
List<Property> list = new ArrayList<>();
while (fieldNames.hasNext()) {
String fieldName = fieldNames.next();
list.add(new Property(fieldName, node.get(fieldName)));
}
System.out.println(mapper.writerWithDefaultPrettyPrinter().writeValueAsString(new Container(list)));
}
}
Output:
{ "properties" : [ {
"property" : "email",
"value" : "abc#gmail.com"
}, {
"property" : "firstname",
"value" : "John"
} ] }
With a little effort you can re-factor the example to a custom serializer which can be plugged as documented here.

Comnverting Json into Java object [duplicate]

I want to be able to access properties from a JSON string within my Java action method. The string is available by simply saying myJsonString = object.getJson(). Below is an example of what the string can look like:
{
'title': 'ComputingandInformationsystems',
'id': 1,
'children': 'true',
'groups': [{
'title': 'LeveloneCIS',
'id': 2,
'children': 'true',
'groups': [{
'title': 'IntroToComputingandInternet',
'id': 3,
'children': 'false',
'groups': []
}]
}]
}
In this string every JSON object contains an array of other JSON objects. The intention is to extract a list of IDs where any given object possessing a group property that contains other JSON objects. I looked at Google's Gson as a potential JSON plugin. Can anyone offer some form of guidance as to how I can generate Java from this JSON string?
I looked at Google's Gson as a potential JSON plugin. Can anyone offer some form of guidance as to how I can generate Java from this JSON string?
Google Gson supports generics and nested beans. The [] in JSON represents an array and should map to a Java collection such as List or just a plain Java array. The {} in JSON represents an object and should map to a Java Map or just some JavaBean class.
You have a JSON object with several properties of which the groups property represents an array of nested objects of the very same type. This can be parsed with Gson the following way:
package com.stackoverflow.q1688099;
import java.util.List;
import com.google.gson.Gson;
public class Test {
public static void main(String... args) throws Exception {
String json =
"{"
+ "'title': 'Computing and Information systems',"
+ "'id' : 1,"
+ "'children' : 'true',"
+ "'groups' : [{"
+ "'title' : 'Level one CIS',"
+ "'id' : 2,"
+ "'children' : 'true',"
+ "'groups' : [{"
+ "'title' : 'Intro To Computing and Internet',"
+ "'id' : 3,"
+ "'children': 'false',"
+ "'groups':[]"
+ "}]"
+ "}]"
+ "}";
// Now do the magic.
Data data = new Gson().fromJson(json, Data.class);
// Show it.
System.out.println(data);
}
}
class Data {
private String title;
private Long id;
private Boolean children;
private List<Data> groups;
public String getTitle() { return title; }
public Long getId() { return id; }
public Boolean getChildren() { return children; }
public List<Data> getGroups() { return groups; }
public void setTitle(String title) { this.title = title; }
public void setId(Long id) { this.id = id; }
public void setChildren(Boolean children) { this.children = children; }
public void setGroups(List<Data> groups) { this.groups = groups; }
public String toString() {
return String.format("title:%s,id:%d,children:%s,groups:%s", title, id, children, groups);
}
}
Fairly simple, isn't it? Just have a suitable JavaBean and call Gson#fromJson().
See also:
Json.org - Introduction to JSON
Gson User Guide - Introduction to Gson
Bewaaaaare of Gson! It's very cool, very great, but the second you want to do anything other than simple objects, you could easily need to start building your own serializers (which isn't that hard).
Also, if you have an array of Objects, and you deserialize some json into that array of Objects, the true types are LOST! The full objects won't even be copied! Use XStream.. Which, if using the jsondriver and setting the proper settings, will encode ugly types into the actual json, so that you don't loose anything. A small price to pay (ugly json) for true serialization.
Note that Jackson fixes these issues, and is faster than GSON.
Oddly, the only decent JSON processor mentioned so far has been GSON.
Here are more good choices:
Jackson (Github) -- powerful data binding (JSON to/from POJOs), streaming (ultra fast), tree model (convenient for untyped access)
Flex-JSON -- highly configurable serialization
EDIT (Aug/2013):
One more to consider:
Genson -- functionality similar to Jackson, aimed to be easier to configure by developer
Or with Jackson:
String json = "...";
ObjectMapper m = new ObjectMapper();
Set<Product> products = m.readValue(json, new TypeReference<Set<Product>>() {});
Easy and working java code to convert JSONObject to Java Object
Employee.java
import java.util.HashMap;
import java.util.Map;
import javax.annotation.Generated;
import com.fasterxml.jackson.annotation.JsonAnyGetter;
import com.fasterxml.jackson.annotation.JsonAnySetter;
import com.fasterxml.jackson.annotation.JsonIgnore;
import com.fasterxml.jackson.annotation.JsonInclude;
import com.fasterxml.jackson.annotation.JsonProperty;
import com.fasterxml.jackson.annotation.JsonPropertyOrder;
#JsonInclude(JsonInclude.Include.NON_NULL)
#Generated("org.jsonschema2pojo")
#JsonPropertyOrder({
"id",
"firstName",
"lastName"
})
public class Employee {
#JsonProperty("id")
private Integer id;
#JsonProperty("firstName")
private String firstName;
#JsonProperty("lastName")
private String lastName;
#JsonIgnore
private Map<String, Object> additionalProperties = new HashMap<String, Object>();
/**
*
* #return
* The id
*/
#JsonProperty("id")
public Integer getId() {
return id;
}
/**
*
* #param id
* The id
*/
#JsonProperty("id")
public void setId(Integer id) {
this.id = id;
}
/**
*
* #return
* The firstName
*/
#JsonProperty("firstName")
public String getFirstName() {
return firstName;
}
/**
*
* #param firstName
* The firstName
*/
#JsonProperty("firstName")
public void setFirstName(String firstName) {
this.firstName = firstName;
}
/**
*
* #return
* The lastName
*/
#JsonProperty("lastName")
public String getLastName() {
return lastName;
}
/**
*
* #param lastName
* The lastName
*/
#JsonProperty("lastName")
public void setLastName(String lastName) {
this.lastName = lastName;
}
#JsonAnyGetter
public Map<String, Object> getAdditionalProperties() {
return this.additionalProperties;
}
#JsonAnySetter
public void setAdditionalProperty(String name, Object value) {
this.additionalProperties.put(name, value);
}
}
LoadFromJSON.java
import org.codehaus.jettison.json.JSONObject;
import com.fasterxml.jackson.databind.ObjectMapper;
public class LoadFromJSON {
public static void main(String args[]) throws Exception {
JSONObject json = new JSONObject();
json.put("id", 2);
json.put("firstName", "hello");
json.put("lastName", "world");
byte[] jsonData = json.toString().getBytes();
ObjectMapper mapper = new ObjectMapper();
Employee employee = mapper.readValue(jsonData, Employee.class);
System.out.print(employee.getLastName());
}
}
If, by any change, you are in an application which already uses http://restfb.com/ then you can do:
import com.restfb.json.JsonObject;
...
JsonObject json = new JsonObject(jsonString);
json.get("title");
etc.
HashMap keyArrayList = new HashMap();
Iterator itr = yourJson.keys();
while (itr.hasNext())
{
String key = (String) itr.next();
keyArrayList.put(key, yourJson.get(key).toString());
}
Depending on the input JSON format(string/file) create a jSONString. Sample Message class object corresponding to JSON can be obtained as below:
Message msgFromJSON = new ObjectMapper().readValue(jSONString, Message.class);
If you use any kind of special maps with keys or values also of special maps, you will find it's not contemplated by the implementation of google.
What's wrong with the standard stuff?
JSONObject jsonObject = new JSONObject(someJsonString);
JSONArray jsonArray = jsonObject.getJSONArray("someJsonArray");
String value = jsonArray.optJSONObject(i).getString("someJsonValue");
Pass your JSON file in this way, it will return the object.
File file = new File("D:\\Coding\\tickets\\temp.json");
ObjectMapper om = new ObjectMapper();
Profile profile = om.readValue(file, new TypeReference<Profile>() {});
Give boon a try:
https://github.com/RichardHightower/boon
It is wicked fast:
https://github.com/RichardHightower/json-parsers-benchmark
Don't take my word for it... check out the gatling benchmark.
https://github.com/gatling/json-parsers-benchmark
(Up to 4x is some cases, and out of the 100s of test. It also has a index overlay mode that is even faster. It is young but already has some users.)
It can parse JSON to Maps and Lists faster than any other lib can parse to a JSON DOM and that is without Index Overlay mode. With Boon Index Overlay mode, it is even faster.
It also has a very fast JSON lax mode and a PLIST parser mode. :) (and has a super low memory, direct from bytes mode with UTF-8 encoding on the fly).
It also has the fastest JSON to JavaBean mode too.
It is new, but if speed and simple API is what you are looking for, I don't think there is a faster or more minimalist API.
The easiest way is that you can use this softconvertvalue method which is a custom method in which you can convert jsonData into your specific Dto class.
Dto response = softConvertValue(jsonData, Dto.class);
public static <T> T softConvertValue(Object fromValue, Class<T> toValueType)
{
ObjectMapper objMapper = new ObjectMapper();
return objMapper
.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false)
.convertValue(fromValue, toValueType);
}
<!-- GSON -->
<dependency>
<groupId>com.google.code.gson</groupId>
<artifactId>gson</artifactId>
<version>2.8.7</version>
</dependency>
#Test
void readListJsonFromFileTest() throws IOException {
Type type = new TypeToken<List<SimplePojo>>(){}.getType();
String fromJsonFile = readFromJsonFile("json/simplePojoJsonList.json");
List<SimplePojo> pojoList = gson.fromJson(fromJsonFile, type);
Assertions.assertNotNull(pojoList);
}
#Test
void readJsonFromFileTest() throws IOException {
Type type = new TypeToken<SimplePojo>(){}.getType();
String fromJsonFile = readFromJsonFile("json/simplePojoJson.json");
SimplePojo simplePojo = gson.fromJson(fromJsonFile, type);
Assertions.assertNotNull(simplePojo);
}
String readFromJsonFile(String pathToJson) throws IOException {
InputStream resource = new ClassPathResource(pathToJson).getInputStream();
String json = StreamUtils.copyToString(resource, StandardCharsets.UTF_8);
return json;
}

Categories