JSON String to POJO, using GSON, clarification needed - java

I have a JSON file, as String:
String compString = "{\n" +
" \"Component\": {\n" +
" \"name\": \"Application\",\n" +
" \"environment\": \"QA\",\n" +
" \"hosts\": [\n" +
" \"box1\",\n" +
" \"box2\"\n" +
" ],\n" +
" \"directories\": [\n" +
" \"/path/to/dir1/\",\n" +
" \"/path/to/dir2/\",\n" +
" \"/path/to/dir1/subdir/\",\n" +
" ]\n" +
" }\n" +
" }";
I have a bean representing it (correct if incorrectly)
public class Component {
String name;
String environment;
List<String> hosts = new ArrayList<String>();
List<String> directories = new ArrayList<String>();
// standard getters and setters
}
I am trying to feed this String to this class by:
Gson gson = new Gson();
Component component = gson.fromJson(compString, Component.class);
System.out.println(component.getName());
Above does not work. (I am getting null back, as if Component's name value is never set)
What am i missing please?

In fact, you have to remove the enclosing class from Json.
Indeed, JSON begins with the content of the enclosing class.
So your JSON would be:
String compString = "{\n" +
" \"name\": \"Application\",\n" +
" \"environment\": \"QA\",\n" +
" \"hosts\": [\n" +
" \"box1\",\n" +
" \"box2\"\n" +
" ],\n" +
" \"directories\": [\n" +
" \"/path/to/dir1/\",\n" +
" \"/path/to/dir2/\",\n" +
" \"/path/to/dir1/subdir/\",\n" +
" ]\n" +
" }\n";

String compString =
" {\n" +
" \"name\": \"Application\",\n" +
" \"environment\": \"QA\",\n" +
" \"hosts\": [\n" +
" \"box1\",\n" +
" \"box2\"\n" +
" ],\n" +
" \"directories\": [\n" +
" \"/path/to/dir1/\",\n" +
" \"/path/to/dir2/\",\n" +
" \"/path/to/dir1/subdir/\",\n" +
" ]}" ;
I think you should read more about json, I have removed something in your json string and then success.

Related

JsonPath is not throwing exception when path not present after an array with asterisk is used

Problem:
I have noticed that once [*] is in the path if the succeeding path key is present, it prints the value, but if the key is not present, it doesn't throw any exception.
JsonPath.read(json, "$.store.book[*].anyRandomKey") should throw error when anyRandomKey is not present.
But it returns an empty list.
Below is code to replicate this scenario
pom.xml dependency:
<dependency>
<groupId>com.jayway.jsonpath</groupId>
<artifactId>json-path</artifactId>
<version>2.4.0</version>
</dependency>
Java main class:
package main.java;
import com.jayway.jsonpath.JsonPath;
public class CheckValidPath {
public static void main(String[] args) {
String json = "{\n" +
" \"store\": {\n" +
" \"book\": [\n" +
" {\n" +
" \"category\": \"reference\",\n" +
" \"author\": \"Nigel Rees\",\n" +
" \"title\": \"Sayings of the Century\",\n" +
" \"price\": 8.95\n" +
" },\n" +
" {\n" +
" \"category\": \"fiction\",\n" +
" \"author\": \"Evelyn Waugh\",\n" +
" \"title\": \"Sword of Honour\",\n" +
" \"price\": 12.99\n" +
" },\n" +
" {\n" +
" \"category\": \"fiction\",\n" +
" \"author\": \"Herman Melville\",\n" +
" \"title\": \"Moby Dick\",\n" +
" \"isbn\": \"0-553-21311-3\",\n" +
" \"price\": 8.99\n" +
" },\n" +
" {\n" +
" \"category\": \"fiction\",\n" +
" \"author\": \"J. R. R. Tolkien\",\n" +
" \"title\": \"The Lord of the Rings\",\n" +
" \"isbn\": \"0-395-19395-8\",\n" +
" \"price\": 22.99\n" +
" }\n" +
" ],\n" +
" \"bicycle\": {\n" +
" \"color\": \"red\",\n" +
" \"price\": 19.95\n" +
" }\n" +
" },\n" +
" \"expensive\": 10\n" +
"}";
//Correct path is evaluated correctly
System.out.println(JsonPath.read(json, "$.store.book[*].author").toString());
//Wrong path doesn't throw a PathNotFoundException exception and returns an empty list
System.out.println(JsonPath.read(json, "$.store.book[*].anyRandomKey").toString());
}
}
Actually, it looks overcomplicated but it works as you need (throws PathNotFoundException for non existant path).
Just use this configuration:
Configuration configuration = Configuration.builder()
.options(Option.REQUIRE_PROPERTIES)
.build();
//Correct path is evaluated correctly
LOG.info(JsonPath.using(configuration)
.parse(json)
.read( "$.store.book[*].author").toString());
//Wrong path throws PathNotFoundException exception
LOG.info(JsonPath.using(configuration)
.parse(json)
.read("$.store.book[*].anyRandomKey").toString());

Firebase Firestore query bug if the document uses a large Map field

After I upgraded the Firestore android sdk from v20.1.0 to v21.6.0, my Firestore queries are not working as expected.
If I make a simple get() query or a snapshotListener query (realtime) on a single document, the query works once (or twice) then stops working or getting updates (if realtime query), the onEvent() method wouldn't be triggered.
After deep investigation and multiple tests, we (my work team) found that what causes this is that our documents, each, contain a large Map field with at least 5 levels of multi key-value pairs.
Our map field is called "items", when we tried to remove it from the document, the realtime query works perfectly as expected.
P.S: we tried to check the size of the documents, the average was between 6k bytes and 5k bytes, and Firestore allows 1Mb (1M bytes) as a maximum document size.
To reproduce the bug, follow below steps :
Add this line into your project gradle file :
dependencies {
classpath 'com.google.gms:google-services:4.3.3'
}
Add those two lines into the module:app gradle file :
dependencies {
implementation 'com.google.firebase:firebase-firestore:21.6.0'
implementation 'com.google.code.gson:gson:2.8.6'
}
Add this code to create and write a copy of my document into
firestore :
private void createAndWriteDocument() {
GsonBuilder gsonBuilder = new GsonBuilder();
gsonBuilder.setDateFormat("MMM d, yyyy HH:mm:ss");
gson = gsonBuilder.create();
FirebaseFirestore.getInstance()
.collection(COLLECTION_ORDERS)
.document("ZYaJKmQF9n1RknziD1tj")
.set(gson.fromJson(jsonOrder2, FireStoreOrder.class));
}
private final String jsonOrder2 = "{\n" +
" \"app_name\":\"Firestore-Sample\",\n" +
" \"app_version\":\"1.0.0\",\n" +
" \"canceled_at\":\"Sep 4, 2020 15:12:34\",\n" +
" \"comments_count\":4,\n" +
" \"countryID\":\"fr\",\n" +
" \"created_at\":\"Sep 4, 2020 12:21:55\",\n" +
" \"currency\":\"EUR\",\n" +
" \"delivered_at\":\"Sep 4, 2020 15:11:30\",\n" +
" \"delivery_agent_id\":\"1rvlTtfJKNVPVxZ2mp4T2CcI1Fj2\",\n" +
" \"delivery_assignment_status\":\"accepted\",\n" +
" \"delivery_fee\":5.0,\n" +
" \"distance\":3.2547,\n" +
" \"hearts_count\":0,\n" +
" \"in_progress_at\":\"Sep 4, 2020 15:06:51\",\n" +
" \"is_friends\":false,\n" +
" \"is_private\":false,\n" +
" \"is_public\":true,\n" +
" \"is_visible\":true,\n" +
" \"items\":{\n" +
" \"-MGNqMoKy8YovI11-QUK\":{\n" +
" \"category_id\":\"-LlbKEnwkC4KZtJyN691\",\n" +
" \"discount_price\":0.0,\n" +
" \"extras\":{\n" +
" \"-M1-qhcXr8tp5KpnLp9p\":{\n" +
" \"max\":10,\n" +
" \"name\":\"Chèvre\",\n" +
" \"price\":0.6,\n" +
" \"quantity\":5,\n" +
" \"row\":6\n" +
" },\n" +
" \"-M1-rHnm7Xzjo7rE73Pk\":{\n" +
" \"max\":10,\n" +
" \"name\":\"Vache kiri\",\n" +
" \"price\":0.6,\n" +
" \"quantity\":7,\n" +
" \"row\":4\n" +
" },\n" +
" \"-M1-me-3qKOqWzul67Sr\":{\n" +
" \"is_sub_extra\":true,\n" +
" \"max\":3,\n" +
" \"name\":\"Crispy Tenders\",\n" +
" \"price\":0.0,\n" +
" \"quantity\":1,\n" +
" \"row\":0\n" +
" },\n" +
" \"-M1-mKvK76SYLJBf3zh-\":{\n" +
" \"is_sub_extra\":true,\n" +
" \"max\":3,\n" +
" \"name\":\"Escalope de Poulet\",\n" +
" \"price\":0.0,\n" +
" \"quantity\":2,\n" +
" \"row\":0\n" +
" },\n" +
" \"-M1-rNaEFCyHlf9WIOaH\":{\n" +
" \"max\":10,\n" +
" \"name\":\"Raclette\",\n" +
" \"price\":0.6,\n" +
" \"quantity\":4,\n" +
" \"row\":5\n" +
" }\n" +
" },\n" +
" \"extras_title\":\"Suppléments\",\n" +
" \"ingredients\":{\n" +
" \"-MEYbO7SlOBFWUVzcvg6\":{\n" +
" \"description\":\"Ingredients description\",\n" +
" \"name\":\"Cheddar\",\n" +
" \"row\":0\n" +
" },\n" +
" \"-MEYbLvKvqPu3YZPPAjo\":{\n" +
" \"description\":\"Ingredients description\",\n" +
" \"name\":\"Laitus\",\n" +
" \"row\":0\n" +
" }\n" +
" },\n" +
" \"ingredients_title\":\"Ingrédients : Décocher pour enlever\",\n" +
" \"itemPrice\":0.0,\n" +
" \"main_image\":{\n" +
" \"ref\":\"/ZKRBeLgCauXKZ15rfRcuQTY2S1k1/-LlXe_ZbTQytlKujrhLF/products/1582717663739.jpg\",\n" +
" \"url\":\"https://firebasestorage.googleapis.com/v0/b/urban-food-a9a70.appspot.com/o/ZKRBeLgCauXKZ15rfRcuQTY2S1k1%2F-LlXe_ZbTQytlKujrhLF%2Fproducts%2F1582717663739.jpg?alt\\u003dmedia\\u0026token\\u003d1bbfd8a0-be5a-44c2-8dd9-d5a7dacf2243\"\n" +
" },\n" +
" \"max_extras\":30,\n" +
" \"name\":\"Tacos\",\n" +
" \"options\":{\n" +
" \"-LlfWYJR_zKtO1l0DjnF\":{\n" +
" \"elements\":{\n" +
" \"-LlfWj5L6weXYZUPUoGW\":{\n" +
" \"extras_title\":\"3 Viandes\",\n" +
" \"max\":1,\n" +
" \"max_extras\":3,\n" +
" \"min_extras\":3,\n" +
" \"name\":\"L : Choisir 3 Viandes\",\n" +
" \"price\":9.5,\n" +
" \"row\":0\n" +
" }\n" +
" },\n" +
" \"name\":\"Taille\",\n" +
" \"row\":-1\n" +
" },\n" +
" \"-LlfX5HY1rzcQpz1p6mG\":{\n" +
" \"elements\":{\n" +
" \"-LlfXbVB-QA-utApD3HO\":{\n" +
" \"max\":3,\n" +
" \"name\":\"Barbecue\",\n" +
" \"price\":0.0,\n" +
" \"quantity\":2,\n" +
" \"row\":0\n" +
" },\n" +
" \"-LlfXxF-7RRTZhFwXhyX\":{\n" +
" \"max\":3,\n" +
" \"name\":\"Marocaine\",\n" +
" \"price\":0.0,\n" +
" \"quantity\":2,\n" +
" \"row\":0\n" +
" }\n" +
" },\n" +
" \"max_quantity\":4,\n" +
" \"min_quantity\":1,\n" +
" \"name\":\"Sauces\",\n" +
" \"row\":3\n" +
" },\n" +
" \"-LlfWPIAjjgTiqtqEzep\":{\n" +
" \"elements\":{\n" +
" \"-LlfWPI9_w1gH1A3HTsB\":{\n" +
" \"name\":\"Tacos\",\n" +
" \"price\":0.0,\n" +
" \"row\":0\n" +
" }\n" +
" },\n" +
" \"name\":\"Type\",\n" +
" \"row\":2\n" +
" }\n" +
" },\n" +
" \"price\":0.0,\n" +
" \"product_id\":\"-LlfTFlgrNBdLZRn5xgn\",\n" +
" \"quantity\":2,\n" +
" \"sub_category_id\":\"-LlbKEnvPMIV3DnSiYlJ\"\n" +
" },\n" +
" \"-MGNqOGcRfYb-myLgc1d\":{\n" +
" \"category_id\":\"-LlkUx5iBSXhKdMYGxTA\",\n" +
" \"discount_price\":3.5,\n" +
" \"extras\":{\n" +
" \"-M2JOJaB_Gsc28GT8wEg\":{\n" +
" \"max\":2,\n" +
" \"name\":\"Harissa\",\n" +
" \"price\":0.0,\n" +
" \"quantity\":1,\n" +
" \"row\":2\n" +
" }\n" +
" },\n" +
" \"extras_title\":\"Sauces\",\n" +
" \"itemPrice\":0.0,\n" +
" \"main_image\":{\n" +
" \"ref\":\"/ZKRBeLgCauXKZ15rfRcuQTY2S1k1/-LlXe_ZbTQytlKujrhLF/products/1582809519364.jpg\",\n" +
" \"url\":\"https://firebasestorage.googleapis.com/v0/b/urban-food-a9a70.appspot.com/o/ZKRBeLgCauXKZ15rfRcuQTY2S1k1%2F-LlXe_ZbTQytlKujrhLF%2Fproducts%2F1582809519364.jpg?alt\\u003dmedia\\u0026token\\u003dabc457cb-2462-44be-886a-af83db3cb501\"\n" +
" },\n" +
" \"max_extras\":2,\n" +
" \"name\":\"Oignons frites\",\n" +
" \"options\":{\n" +
" \"-M15mpsXwAzsDRlLDHJI\":{\n" +
" \"elements\":{\n" +
" \"-M15mpsXwAzsDRlLDHJG\":{\n" +
" \"name\":\"Cheddar\",\n" +
" \"price\":0.0,\n" +
" \"row\":0\n" +
" }\n" +
" },\n" +
" \"name\":\"Au choix :\",\n" +
" \"row\":-1\n" +
" }\n" +
" },\n" +
" \"price\":3.5,\n" +
" \"product_id\":\"-M15mV_4Ui2B90GlzsaR\",\n" +
" \"quantity\":1,\n" +
" \"sub_category_id\":\"-LlkUx5h8rXECP8L_hjQ\"\n" +
" },\n" +
" \"-MGNqOxoHFGoigUXao96\":{\n" +
" \"category_id\":\"-LlkUx5iBSXhKdMYGxTA\",\n" +
" \"discount_price\":3.5,\n" +
" \"extras\":{\n" +
" \"-M2JOmBf1oN1BmUUHeiY\":{\n" +
" \"name\":\"Biggy burger\",\n" +
" \"price\":0.0,\n" +
" \"quantity\":1,\n" +
" \"row\":0\n" +
" }\n" +
" },\n" +
" \"itemPrice\":0.0,\n" +
" \"main_image\":{\n" +
" \"ref\":\"/ZKRBeLgCauXKZ15rfRcuQTY2S1k1/-LlXe_ZbTQytlKujrhLF/products/1582809369789.jpg\",\n" +
" \"url\":\"https://firebasestorage.googleapis.com/v0/b/urban-food-a9a70.appspot.com/o/ZKRBeLgCauXKZ15rfRcuQTY2S1k1%2F-LlXe_ZbTQytlKujrhLF%2Fproducts%2F1582809369789.jpg?alt\\u003dmedia\\u0026token\\u003d705593e0-e403-4931-b040-5b2261cb96e5\"\n" +
" },\n" +
" \"name\":\"Bacon frites\",\n" +
" \"options\":{\n" +
" \"-M15lyQyHs1GujtZxMtS\":{\n" +
" \"elements\":{\n" +
" \"-M15lyQxrRFaLAWGaa3i\":{\n" +
" \"name\":\"Sauce fromagère\",\n" +
" \"price\":0.0,\n" +
" \"row\":0\n" +
" }\n" +
" },\n" +
" \"name\":\"Au choix :\",\n" +
" \"row\":-1\n" +
" }\n" +
" },\n" +
" \"price\":3.5,\n" +
" \"product_id\":\"-M15lqmhF16ZOLqebPzs\",\n" +
" \"quantity\":1,\n" +
" \"sub_category_id\":\"-LlkUx5h8rXECP8L_hjQ\"\n" +
" }\n" +
" },\n" +
" \"itemsCount\":0,\n" +
" \"level_one_zone_id\":\"Île-de-France\",\n" +
" \"level_two_zone_id\":\"Paris\",\n" +
" \"order_id\":\"ZYaJKmQF9n1RknziD1tj\",\n" +
" \"order_number\":31,\n" +
" \"order_type\":\"delivery\",\n" +
" \"paid\":false,\n" +
" \"paid_with_loyalty\":0.0,\n" +
" \"picked_at\":\"Sep 4, 2020 15:12:46\",\n" +
" \"platform\":\"android\",\n" +
" \"processedAt\":{\n" +
" \"nanoseconds\":994000000,\n" +
" \"seconds\":1599228406\n" +
" },\n" +
" \"restaurant_photo\":\"https://firebasestorage.googleapis.com/v0/b/menutium-319d0.appspot.com/o/LHx3fTdtoaRlrAHSjznJSaPz9rP2%2F-MEYUb7iepk3pLwUyWX3%2Fprofile%2F1597250393877.jpg?alt\\u003dmedia\\u0026token\\u003dcbccd3fe-91fd-4397-ab34-79f5f241def2\",\n" +
" \"status\":\"picked\",\n" +
" \"store_id\":\"-MEYUb7iepk3pLwUyWX3\",\n" +
" \"store_name\":\"La Fourchette\",\n" +
" \"total_price\":50.2,\n" +
" \"updated_at\":\"Sep 7, 2020 18:54:02\",\n" +
" \"user_address\":\"166 Quai de Stalingrad, 92130 Issy-les-Moulineaux, France\\nIssy-les-Moulineaux\",\n" +
" \"user_coordinates\":\"48.8256954,2.2579879\",\n" +
" \"user_name\":\"Mo Salah\",\n" +
" \"user_phone\":\"+21650001002\",\n" +
" \"user_photo\":\"https://firebasestorage.googleapis.com/v0/b/menutium-319d0.appspot.com/o/2Bz8euUmPgMqc4Z7QZWJjLfsgV72%2Fphoto_profile?alt\\u003dmedia\\u0026token\\u003df5dcee5b-fdda-45bd-9ec3-982cfe7832bd\",\n" +
" \"user_uid\":\"2Bz8euUmPgMqc4Z7QZWJjLfsgV72\",\n" +
" \"validated_at\":\"Sep 4, 2020 15:12:42\",\n" +
" \"validatedBy\":{\n" +
" \"name\":\"Urban-Admin\",\n" +
" \"id\":\"admin\"\n" +
" }\n" +
"}";
Start a realtime query on this document :
FirebaseFirestore.getInstance()
.collection("orders")
.document("ZYaJKmQF9n1RknziD1tj")
.addSnapshotListener(new EventListener<DocumentSnapshot>() {
#Override
public void onEvent(#Nullable DocumentSnapshot value,
#Nullable FirebaseFirestoreException error) {
Log.d("testing", "onEvent triggered");
if (error != null) {
Log.i("testing", "test error : "+ error.getMessage());
}
}
});
We created two Android projects (Java code), put them into public Github repos so that anyone could reproduce the issue we are facing.
Everything is detailed into the Readme repos.
First Project repository
Second Project repository with minimal code
Before i create this question, i created an issue within the official firebase-android-sdk repository.
After five days, someone from the Firebase team answered me, they did found a bug in the Firestore sdk, fixed it, but still didn't released it, so he recommended to downgrade to older version than 21.5.0 to avoid the bug as a temporary workaround.
Github issue link here

how to remove attributes from json using Kotlin and jackson ObjectMapper

I want to remove all occurrence of "attributeToRemove" in the following JSON:
{
"Item994": [
{
"attributeToRemove": {
"someItem": null
},
"types": [
"type194",
"type294"
],
"p1": "SOS"
}
],
"Item99": [
{
"attributeToRemove": {
"someItem": null
},
"types": [
"type19",
"type29"
],
"p1": "SOS"
}
]
}
I tried using removeAll but I keep this Error: Type mismatch: inferred type is (JsonNode!) -> JsonNode! but (JsonNode!) -> Boolean was expected
Can anyone suggest how to fix this?
Here's my code:
import com.fasterxml.jackson.databind.ObjectMapper
fun main ( args : Array < String > ) {
val someString = "{\n" +
" \"Item994\": [\n" +
" {\n" +
" \"attributeToRemove\": {\n" +
" \"someItem\": null\n" +
" },\n" +
" \"types\": [\n" +
" \"type194\",\n" +
" \"type294\"\n" +
" ],\n" +
" \"p1\": \"SOS\"\n" +
" }\n" +
" ],\n" +
" \"Item99\": [\n" +
" {\n" +
" \"attributeToRemove\": {\n" +
" \"someItem\": null\n" +
" },\n" +
" \"types\": [\n" +
" \"type19\",\n" +
" \"type29\"\n" +
" ],\n" +
" \"p1\": \"SOS\"\n" +
" }\n" +
" ]\n" +
"}"
val mapper = ObjectMapper()
val jsonStr = mapper.writerWithDefaultPrettyPrinter()
.writeValueAsString(someString)
val jsonResult = mapper.readTree(someString)
jsonResult.removeAll { it.get("attributeToRemove") }
}
import com.fasterxml.jackson.annotation.JsonAutoDetect
import com.fasterxml.jackson.annotation.JsonIgnoreProperties
import com.fasterxml.jackson.annotation.JsonProperty
import com.fasterxml.jackson.databind.ObjectMapper
#JsonIgnoreProperties(ignoreUnknown = true)
class Item99 {
var p1: String? = null
var types: Array<String>? = null
}
#JsonIgnoreProperties(ignoreUnknown = true)
class Item994 {
var p1: String? = null
var types: Array<String>? = null
}
class Wrapper {
#JsonProperty("Item99")
var item99: Array<Item99>? = null
#JsonProperty("Item994")
var item994: Array<Item994>? = null
}
object Main {
var jsonString = "{\n" +
" \"Item994\": [\n" +
" {\n" +
" \"attributeToRemove\": {\n" +
" \"someItem\": null\n" +
" },\n" +
" \"types\": [\n" +
" \"type194\",\n" +
" \"type294\"\n" +
" ],\n" +
" \"p1\": \"SOS\"\n" +
" }\n" +
" ],\n" +
" \"Item99\": [\n" +
" {\n" +
" \"attributeToRemove\": {\n" +
" \"someItem\": null\n" +
" },\n" +
" \"types\": [\n" +
" \"type19\",\n" +
" \"type29\"\n" +
" ],\n" +
" \"p1\": \"SOS\"\n" +
" }\n" +
" ]\n" +
"}"
#JvmStatic
fun main(args: Array<String>) {
val mapper = ObjectMapper()
mapper.visibilityChecker = mapper.serializationConfig.defaultVisibilityChecker.withCreatorVisibility(JsonAutoDetect.Visibility.ANY)
val answer = mapper.readValue(jsonString, Wrapper::class.java)
print(mapper.writeValueAsString(answer))
}
}
convert jsonString to an Object, ignore the fields you want to remove then map back to a jsonString:
import com.google.gson.Gson
import com.google.gson.annotations.SerializedName
class Item99 {
var p1: String? = null
var types: Array<String>? = null
}
class Item994 {
var p1: String? = null
var types: Array<String>? = null
}
class Wrapper (
#SerializedName("Item99")
var item99: Array<Item99>?,
#SerializedName("Item994")
var item994: Array<Item994>?
)
object Main {
var jsonString = "{\n" +
" \"Item994\": [\n" +
" {\n" +
" \"attributeToRemove\": {\n" +
" \"someItem\": null\n" +
" },\n" +
" \"types\": [\n" +
" \"type194\",\n" +
" \"type294\"\n" +
" ],\n" +
" \"p1\": \"SOS\"\n" +
" }\n" +
" ],\n" +
" \"Item99\": [\n" +
" {\n" +
" \"attributeToRemove\": {\n" +
" \"someItem\": null\n" +
" },\n" +
" \"types\": [\n" +
" \"type19\",\n" +
" \"type29\"\n" +
" ],\n" +
" \"p1\": \"SOS\"\n" +
" }\n" +
" ]\n" +
"}"
#JvmStatic
fun main(args: Array<String>) {
val gson = Gson()
val wrapper = gson.fromJson(jsonString,Wrapper::class.java)
println(gson.toJson(wrapper))
}
}
The output will look like this:
{"Item99":[{"p1":"SOS","types":["type19","type29"]}],"Item994":[{"p1":"SOS","types":["type194","type294"]}]}

how to run mongodb native query with mongodb date function in spring-data-mongodb?

I want to execute the below native query in spring data mongodb :
db.runCommand({aggregate:"mycollection", pipeline :[{$match : {$and :
[{"orderDate" : {$gte : ISODate("2016-07-25T10:33:04.196Z")}},
{"orderDate" : {$lte :ISODate("2018-07-25T10:33:04.196Z")
}}
]}},
{ "$project" : { "orderType" : 1 ,"count" : 1 ,
"month" : { "$month" : [ "$orderDate"]}}},
{ "$group" : { "_id" : { "month" : "$month" , "orderType" : "$orderType"} ,
"count" : { "$sum" : 1} }}],
cursor:{batchSize:1000}})
I tried with mongoTemplate.executeCommand it executes a json string, Please help...
Regards
Kris
You can use the mongoTemplate.executeCommand(DBObject dbObject) variant.
Just change the date to extended json which is supported by Json parser and build the command.
Something like
long date1 = Instant.parse("2016-07-25T10:33:04.196Z").toEpochMilli();
long date2 = Instant.parse("2018-07-25T10:33:04.196Z").toEpochMilli();
DBObject dbObject = new BasicDBObject(
"aggregate", "mycollection").append(
"pipeline", JSON.parse("[\n" +
" {\n" +
" \"$match\": {\n" +
" \"$and\": [\n" +
" {\n" +
" \"orderDate\": {\n" +
" \"$gte\": \""+ date1 +"\"\n" +
" }\n" +
" },\n" +
" {\n" +
" \"orderDate\": {\n" +
" \"$gte\": \""+ date2 +"\"\n" +
" }\n" +
" }\n" +
" ]\n" +
" }\n" +
" },\n" +
" {\n" +
" \"$project\": {\n" +
" \"orderType\": 1,\n" +
" \"count\": 1,\n" +
" \"month\": {\n" +
" \"$month\": [\n" +
" \"$orderDate\"\n" +
" ]\n" +
" }\n" +
" }\n" +
" },\n" +
" {\n" +
" \"$group\": {\n" +
" \"_id\": {\n" +
" \"month\": \"$month\",\n" +
" \"orderType\": \"$orderType\"\n" +
" },\n" +
" \"count\": {\n" +
" \"$sum\": 1\n" +
" }\n" +
" }\n" +
" }\n" +
"]")).append(
"cursor", new BasicDBObject("batchSize", 1000)
);
mongoTemplate.executeCommand(dbObject)

comparing two json nodes recursively and printing the distinct value in java

I want to compare two big json nodes in java and if they are different I need to print the value which was distinct in both nodes.
JsonNode.equals() returns false if nodes are unequal but it does not tell the particular distinct value.
Thanks.
code example:
import org.codehaus.jackson.JsonNode;
import org.codehaus.jackson.map.ObjectMapper;
import org.codehaus.jackson.map.util.JSONPObject;
import org.json.JSONException;
import org.json.JSONObject;
import java.io.IOException;
import java.util.Iterator;
import java.util.Map;
public class TestJsonComp
{
static String json = "{\n" +
" \"d\" :\n" +
" {\n" +
" \"results\" :\n" +
" [\n" +
" {\n" +
" \"__metadata\" :\n" +
" {\n" +
" \"id\" : \" ##ServiceRoot##/Submit('##RequisitionUniqueName##')\",\n" +
" \"uri\" : \"##ServiceRoot##/Submit('##RequisitionUniqueName##')\",\n" +
" \"type\" : \".submitResponse\",\n" +
" \"etag\" : \"W/\\\"##RequisitionUniqueName##\\\"\"\n" +
" },\n" +
" \"status\" : \"ERROR\",\n" +
" \"uniqueName\" : \"##RequisitionUniqueName##\",\n" +
" \"errors\" :\n" +
" {\n" +
" \"results\" :\n" +
" [\n" +
" {\n" +
" \"__metadata\" :\n" +
" {\n" +
" \"id\" : \"##ServiceRoot##/RequisitionErrors(0)\",\n" +
" \"uri\" : \"##ServiceRoot##/RequisitionErrors(0)\",\n" +
" \"type\" : \".errors\",\n" +
" \"etag\" : \"W/\\\"0\\\"\"\n" +
" },\n" +
" \"id\" : 0,\n" +
" \"error_description\" : \"title.\"\n" +
" },\n" +
" {\n" +
" \"__metadata\" :\n" +
" {\n" +
" \"id\" : \"##ServiceRoot##/RequisitionErrors(1)\",\n" +
" \"uri\" : \"##ServiceRoot##/RequisitionErrors(1)\",\n" +
" \"type\" : \".errors\",\n" +
" \"etag\" : \"W/\\\"1\\\"\"\n" +
" },\n" +
" \"id\" : 1,\n" +
" \"error_description\" : \"Line item 1 must be set.\"\n" +
" }\n" +
" ]\n" +
" }\n" +
" }\n" +
" ]\n" +
" }\n" +
"}";
static String jsonCompare = "{\n" +
" \"d\" :\n" +
" {\n" +
" \"results\" :\n" +
" [\n" +
" {\n" +
" \"__metadata\" :\n" +
" {\n" +
" \"id\" : \"##ServiceRoot##/Submit('##RequisitionUniqueName##')\",\n" +
" \"uri\" : \"##ServiceRoot##/Submit('##RequisitionUniqueName##')\",\n" +
" \"type\" : \".submitResponse\",\n" +
" \"etag\" : \"W/\\\"##RequisitionUniqueName##\\\"\"\n" +
" },\n" +
" \"status\" : \"ERROR\",\n" +
" \"uniqueName\" : \"##RequisitionUniqueName##\",\n" +
" \"errors\" :\n" +
" {\n" +
" \"results\" :\n" +
" [\n" +
" {\n" +
" \"__metadata\" :\n" +
" {\n" +
" \"id\" : \"##ServiceRoot##/RequisitionErrors(0)\",\n" +
" \"uri\" : \"##ServiceRoot##/RequisitionErrors(0)\",\n" +
" \"type\" : \".errors\",\n" +
" \"etag\" : \"W/\\\"0\\\"\"\n" +
" },\n" +
" \"id\" : 0,\n" +
" \"error_description\" : \"title.\"\n" +
" },\n" +
" {\n" +
" \"__metadata\" :\n" +
" {\n" +
" \"id\" : \"##ServiceRoot##/RequisitionErrors(1)\",\n" +
" \"uri\" : \"##ServiceRoot##/RequisitionErrors(1)\",\n" +
" \"type\" : \".errors\",\n" +
" \"etag\" : \"W/\\\"1\\\"\"\n" +
" },\n" +
" \"id\" : 1,\n" +
" \"error_descriptio\" : \"Line item 1 must be set.\"\n" +
" }\n" +
" ]\n" +
" }\n" +
" }\n" +
" ]\n" +
" }\n" +
"}";
public static void main (String args []) throws IOException, JSONException
{
ObjectMapper objectMapper = new ObjectMapper();
JsonNode n1 = objectMapper.readTree(json);
JsonNode n2 = objectMapper.readTree(jsonCompare);
System.out.print(n1.equals(n2));
}
}
check Parse a JSON Object With an Undetermined Amount of Child Nodes.
You can get the list of children of one node. Then loop over the children, get the key/value and compare each element of the second node by using the key.
I would suggest use a file comparator and compare line by line. This will work if you also mind the order of the elements in the node. If order is not considered, then first use JsonNode.equals() to check the equality and only if nodes are unequal, use file comparator to print the differences.

Categories