how to remove attributes from json using Kotlin and jackson ObjectMapper - java

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"]}]}

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());

Multiple JSONs in one Request --> Each of them to an Object

I am requesting via OKHttpClient data from my api, and im trying with an getAll() to split up the JSON response into my objects i need.
Here is an example for my response i get:
[
{
"value":"data",
"id":5
},
{
"value":"data",
"id":6
},
{
"value":"data",
"id":7
},
{
"value":"data",
"id":8
},
{
"value":"data",
"id":9
},
{
"value":"value",
"id":10
}
]
I believe you can use GSON in Android, so kindly see the code below:
static class SimpleExample{
private String value;
private Integer id;
}
public static void main(String[] args){
String json = "[{\n"
+ " \"value\":\"data\",\n"
+ " \"id\":5\n"
+ " },\n"
+ " {\n"
+ " \"value\":\"data\",\n"
+ " \"id\":6\n"
+ " },\n"
+ " {\n"
+ " \"value\":\"data\",\n"
+ " \"id\":7\n"
+ " },\n"
+ " {\n"
+ " \"value\":\"data\",\n"
+ " \"id\":8\n"
+ " },\n"
+ " {\n"
+ " \"value\":\"data\",\n"
+ " \"id\":9\n"
+ " },\n"
+ " {\n"
+ " \"value\":\"value\",\n"
+ " \"id\":10\n"
+ " }\n"
+ "]";
final GsonBuilder gsonBuilder = new GsonBuilder();
final Gson gson = gsonBuilder.create();
SimpleExample[] allObjects = gson.fromJson(json, SimpleExample[].class);
System.out.println(allObjects.length);
}
<dependency>
<groupId>com.google.code.gson</groupId>
<artifactId>gson</artifactId>
<version>2.8.9</version>
</dependency>

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.

JSON String to POJO, using GSON, clarification needed

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.

Categories