Jackson Vs. Gson
I did this research the last week and I ended up with the same 2 libraries. As I'm using Spring 3 (that adopts Jackson in its default Json view 'JacksonJsonView') it was more natural for me to do the same. The 2 lib are pretty much the same... at the end they simply map to a json file! :)
Anyway as you said Jackson has a + in performance and that's very important for me. The project is also quite active as you can see from their web page and that's a very good sign as well.
Jackson vs Gson for simple deserialisation
With Jackson 1.4+ you can use the class-level @JsonIgnoreProperties
annotation to silently ignore unknown fields, with ignoreUnknown
set to true.
@JsonIgnoreProperties(ignoreUnknown = true)
public class TwitterUser {
// snip...
}
- http://wiki.fasterxml.com/JacksonAnnotations
- http://wiki.fasterxml.com/JacksonHowToIgnoreUnknown
Jsonpath with Jackson or Gson
The Jayway JsonPath library has support for reading values using a JSON path.
For example:
String json = "...";
Map<String, Object> book = JsonPath.read(json, "$.store.book[0]");
System.out.println(book); // prints {category=reference, author=Nigel Rees, title=Sayings of the Century, price=8.95}
Double price = JsonPath.read(json, "$.store.bicycle.price");
System.out.println(price); // prints 19.95
You can also map JSON objects directly to classes, like in GSON or Jackson:
Book book = JsonPath.parse(json).read("$.store.book[0]", Book.class);
System.out.println(book); // prints Book{category='reference', author='Nigel Rees', title='Sayings of the Century', price=8.95}
If you would like to specifically use GSON or Jackson to do the deserialization (the default is to use json-smart), you can also configure this:
Configuration.setDefaults(new Configuration.Defaults() {
private final JsonProvider jsonProvider = new JacksonJsonProvider();
private final MappingProvider mappingProvider = new JacksonMappingProvider();
@Override
public JsonProvider jsonProvider() {
return jsonProvider;
}
@Override
public MappingProvider mappingProvider() {
return mappingProvider;
}
@Override
public Set<Option> options() {
return EnumSet.noneOf(Option.class);
}
});
See the documentation for more details.
Converting byte[] to json and vice versa without jackson or gson
If it would be so easy, then Jackson
or Gson
was never be born.
I am affraid, that you have to declared deserializer for all of your objects manualy. This is not a rocket science, but it takes time to do it. This is an example:
public static void main(String[] args) {
Data data = new Data(11, 12);
String json = toJson(data);
System.out.println(json);
byte[] bytes = json.getBytes(StandardCharsets.UTF_8);
Data res = toDataObj(bytes);
System.out.println(res.a);
System.out.println(res.b);
}
public static String toJson(Data data) {
JSONObject jsonObj = new JSONObject();
jsonObj.put("a", data.a);
jsonObj.put("b", data.b);
return jsonObj.toString();
}
public static Data toDataObj(byte[] bytesClass) {
JSONObject jsonObject = new JSONObject(new String(bytesClass, StandardCharsets.UTF_8));
Data data = new Data(0, 0);
data.a = jsonObject.getInt("a");
data.b = jsonObject.getInt("b");
return data;
}
public static class Data {
int a;
int b;
public Data(int a, int b) {
this.a = a;
this.b = b;
}
}
Here you can get more info:
- How to create JSON Object using String?
- How to parse JSON in Java
Json parsing using jackson or Gson
please add object for global object
Class ResultJson{
String last_sync_dt;
ArrayList<MeetingInfo> meetings_info;
}
and MeetingInfo will be
public class MeetingInfo {
private String date;
private String meeting_id;
private String subject;
private CustomerInfo customerInfo;
public void setDate(String date) {
this.date = date;
}
public void setMeeting_id(String meeting_id) {
this.meeting_id = meeting_id;
}
public void setSubject(String subject) {
this.subject = subject;
}
public void setCustomer(CustomerInfo customer) {
customerInfo = customer;
}
}
Customer info class
public class CustomerInfo {
private String customer_id;
private String customer_name;
public void setCustomerId(String customer_id) {
this.customer_id = customer_id;
}
public void setCustomerName(String customer_name) {
this.customer_name = customer_name;
}
}
Meeting deserializer
public class MeetingInfoAutho implements JsonDeserializer<MeetingInfo>{
@Override
public MeetingInfo deserialize(JsonElement jsonElement, Type type, JsonDeserializationContext jsonDeserializationContext) throws JsonParseException {
JsonObject jObject = jsonElement.getAsJsonObject();
MeetingInfo info = new MeetingInfo();
CustomerInfo customer = new CustomerInfo();
customer.setCustomerId(jObject.get("customer_id").getAsString());
customer.setCustomerName(jObject.get("customer_name").getAsString());
info.setDate(jObject.get("date").getAsString());
info.setMeeting_id(jObject.get("meeting_id").getAsString());
info.setSubject(jObject.get("subject").getAsString());
info.setCustomer(customer);
Log.e("info", jObject.toString());
return info;
}
}
and final call to json string to object
GsonBuilder gsonBuilder = new GsonBuilder();
gsonBuilder.registerTypeAdapter(MeetingInfo.class, new MeetingInfoAutho());
Gson gson = gsonBuilder.create();
ResultJson resultObject = gson.fromJson(jsonStr, ResultJson.class);
You should create MeetingInfoAutho which implements JsonDeserializer. Please find some examples about JsonDeserializer GSON for more info.
This will give exact result.
How to compare JSON documents and return the differences with Jackson or Gson?
Reading the JSON documents as Map
s and comparing them
You could read both JSON documents as Map<K, V>
. See the below examples for Jackson and Gson:
ObjectMapper mapper = new ObjectMapper();
TypeReference<HashMap<String, Object>> type =
new TypeReference<HashMap<String, Object>>() {};
Map<String, Object> leftMap = mapper.readValue(leftJson, type);
Map<String, Object> rightMap = mapper.readValue(rightJson, type);
Gson gson = new Gson();
Type type = new TypeToken<Map<String, Object>>(){}.getType();
Map<String, Object> leftMap = gson.fromJson(leftJson, type);
Map<String, Object> rightMap = gson.fromJson(rightJson, type);
Then use Guava's Maps.difference(Map<K, V>, Map<K, V>)
to compare them. It returns a MapDifference<K, V>
instance:
MapDifference<String, Object> difference = Maps.difference(leftMap, rightMap);
If you are not happy with the result, you can consider flattening the maps and then compare them. It will provide better comparison results especially for nested objects and arrays.
Creating flat Map
s for the comparison
To flat the map, you can use:
public final class FlatMapUtil {
private FlatMapUtil() {
throw new AssertionError("No instances for you!");
}
public static Map<String, Object> flatten(Map<String, Object> map) {
return map.entrySet().stream()
.flatMap(FlatMapUtil::flatten)
.collect(LinkedHashMap::new, (m, e) -> m.put("/" + e.getKey(), e.getValue()), LinkedHashMap::putAll);
}
private static Stream<Map.Entry<String, Object>> flatten(Map.Entry<String, Object> entry) {
if (entry == null) {
return Stream.empty();
}
if (entry.getValue() instanceof Map<?, ?>) {
return ((Map<?, ?>) entry.getValue()).entrySet().stream()
.flatMap(e -> flatten(new AbstractMap.SimpleEntry<>(entry.getKey() + "/" + e.getKey(), e.getValue())));
}
if (entry.getValue() instanceof List<?>) {
List<?> list = (List<?>) entry.getValue();
return IntStream.range(0, list.size())
.mapToObj(i -> new AbstractMap.SimpleEntry<String, Object>(entry.getKey() + "/" + i, list.get(i)))
.flatMap(FlatMapUtil::flatten);
}
return Stream.of(entry);
}
}
It uses the JSON Pointer notation defined in the RFC 6901 for the keys, so you can easily locate the values.
Example
Consider the following JSON documents:
{
"name": {
"first": "John",
"last": "Doe"
},
"address": null,
"birthday": "1980-01-01",
"company": "Acme",
"occupation": "Software engineer",
"phones": [
{
"number": "000000000",
"type": "home"
},
{
"number": "999999999",
"type": "mobile"
}
]
}
{
"name": {
"first": "Jane",
"last": "Doe",
"nickname": "Jenny"
},
"birthday": "1990-01-01",
"occupation": null,
"phones": [
{
"number": "111111111",
"type": "mobile"
}
],
"favorite": true,
"groups": [
"close-friends",
"gym"
]
}
And the following code to compare them and show the differences:
Map<String, Object> leftFlatMap = FlatMapUtil.flatten(leftMap);
Map<String, Object> rightFlatMap = FlatMapUtil.flatten(rightMap);
MapDifference<String, Object> difference = Maps.difference(leftFlatMap, rightFlatMap);
System.out.println("Entries only on the left\n--------------------------");
difference.entriesOnlyOnLeft()
.forEach((key, value) -> System.out.println(key + ": " + value));
System.out.println("\n\nEntries only on the right\n--------------------------");
difference.entriesOnlyOnRight()
.forEach((key, value) -> System.out.println(key + ": " + value));
System.out.println("\n\nEntries differing\n--------------------------");
difference.entriesDiffering()
.forEach((key, value) -> System.out.println(key + ": " + value));
It will produce the following output:
Entries only on the left
--------------------------
/address: null
/phones/1/number: 999999999
/phones/1/type: mobile
/company: Acme
Entries only on the right
--------------------------
/name/nickname: Jenny
/groups/0: close-friends
/groups/1: gym
/favorite: true
Entries differing
--------------------------
/birthday: (1980-01-01, 1990-01-01)
/occupation: (Software engineer, null)
/name/first: (John, Jane)
/phones/0/number: (000000000, 111111111)
/phones/0/type: (home, mobile)
Related Topics
Bypass Generatedvalue in Hibernate (Merge Data Not in Db)
Prime Numbers by Eratosthenes Quicker Sequential Than Concurrently
Jackson and Generic Type Reference
In Java, How to Check If a String Contains a Substring (Ignoring Case)
Green Threads VS Non Green Threads
Precise Definition of "Functional Interface" in Java 8
Differencebetween a Javabean and a Pojo
Methods VS Constructors in Java
Listener Placement Adhering to the Traditional (Non-Mediator) MVC Pattern
Are Static Variables Shared Between Threads
What Is the Default Encoding of the Jvm
How to Set Java_Home Environment Variable on MAC Os X 10.9
Why Start an Arraylist with an Initial Capacity