I use protoc to generate java classes used to serialize data. Sometimes, for example, I want my json to look like:
[
{
"foo": 1,
"bar": "a"
},
{
"foo": 2,
"bar": "b"
},
{
"foo": 3,
"bar": "c"
}
]
I will define an protobuff message:
message Sample {
uint64 foo = 1;
string bar = 2;
}
And I have to define one more message, for array type key:
message SampleResponse {
repeated Sample keys = 1;
}
Above json now looks like:
{
"keys": [
{
"foo": 1,
"bar": "a"
},
{
"foo": 2,
"bar": "b"
},
{
"foo": 3,
"bar": "c"
}
]
}
Is there a possibility to get rid of that excess wrapper-message?
Given that the main purpose of the Protocol Buffer wasn't JSON serialization/deserialization the answer is "No".
Related
I need to transform below Input JSON to output JSON and not sure about how to write spec for that. Need to re-position one field ("homePage") as a root element. Any help or suggestion would be appreciated.
Input JSON :
[{
"uuid": "cac40601-ffc9-4fd0-c5a1-772ac65f0587",
"pageId": 123456,
"page": {
"indexable": true,
"rootLevel": false,
"homePage": false
}
}]
Output JSON :
[{
"uuid": "cac40601-ffc9-4fd0-c5a1-772ac65f0587",
"pageId": 123456,
"homePage": false,
"page": {
"indexable": true,
"rootLevel": false
}
}]
This Jolt Spec should work for you. Tested with https://jolt-demo.appspot.com/
[
{
"operation": "shift",
"spec": {
"*": {
"uuid": "[&1].uuid",
"pageId": "[&1].pageId",
"page": {
"indexable": "[&2].page.indexable",
"rootLevel": "[&2].page.rootLevel",
"homePage": "[&2].homePage"
}
}
}
}
]
input:
{
"uuid" : "cac40601-ffc9-4fd0-c5a1-772ac65f0587",
"pageId" : 123456,
"page" : {
"indexable" : true,
"rootLevel" : false
},
"homePage" : false
}
output:
[ {
"uuid" : "cac40601-ffc9-4fd0-c5a1-772ac65f0587",
"pageId" : 123456,
"page" : {
"indexable" : true,
"rootLevel" : false
},
"homePage" : false
} ]
Explanation:
From the javadoc
& Path lookup
As Shiftr processes data and walks down the spec, it maintains a data structure describing the path it has walked.
The & wildcard can access data from that path in a 0 major, upward oriented way.
Example:
{
"foo" : {
"bar": {
"baz": // &0 = baz, &1 = bar, &2 = foo
}
}
}
Next thing: How to wrap the output object into the array?
A good example can be found in this post.
So, in our case:
"[&1].uuid" says:
Place the uuid value in the object inside the array. The index of the array is indicated by the &1 wildcard. For uuid it will be the index of the array, where the object with uuid key is placed in the original json.
Next, [&2] is similar to [&1]. However, looking at the "indexable" key, it is one level deeper in the input json. Thats why instead of [&1] we used [&2] (have a look again at the foo-bar example from the docs).
I am trying to convert an Avro Kafka Event to Json and need to manipulate The Avro Event by Removing Strings from this Event.
I am using GSON Library to manipulate the Json String Object but somehow its not removing the intended String.
JsonElement je = new Gson().fromJson(matchRequest, JsonElement.class);
JsonObject jo = je.getAsJsonObject();
jo.remove("com.XXX.XXXX");
jo.remove("com.XXX.XXX");
jo.remove("com.XXX.XXX");
System.out.println("#################"+jo);
Json String I am Receiving as matchRequest is
{"interaction_id":"321","customer_id":"32","context_id":"123","work_id":"ewq","work_request_id":"213","task_type":"123","match_type":"wert","resource_list":{"com.xxx.xxxx":{"rank":1,"resource_data":{"com.xxx.xxxx":{"account_id":1,"source_name":"Mankind","channel_id":"voice"}}}},"service_list":{"com.xxx.xxxx":{"rank":5,"priority":1,"resource_count":"gvk","min_proficiency":"10","max_proficiency":"1","attributes":{"com.xxx.xxxx":{"category":"edw","value":"33232"}},"resource_offered":{"com.xxx.xxxx":{"agent_id":"rewq","account_id":"123","source_name":"wqe","resource_address":"ewq","source_address":"rewq","channel_id":"212","channel_provider":"wqe"}}}},"matching_state":"OFFERED"}
JSON Format
"interaction_id": "321",
"customer_id": "32",
"context_id": "123",
"work_id": "ewq",
"work_request_id": "213",
"task_type": "123",
"match_type": "wert",
"resource_list": {
"com.XXXXXX": {
"rank": 1,
"resource_data": {
"com.XXXX": {
"account_id": 1,
"source_name": "Mankind",
"channel_id": "voice"
}
}
}
},
"service_list": {
"com.XXXX": {
"rank": 5,
"priority": 1,
"resource_count": "gvk",
"min_proficiency": "10",
"max_proficiency": "1",
"attributes": {
"com.XXXX": {
"category": "edw",
"value": "33232"
}
},
"resource_offered": {
"com.XXXX": {
"agent_id": "rewq",
"account_id": "123",
"source_name": "wqe",
"resource_address": "ewq",
"source_address": "rewq",
"channel_id": "212",
"channel_provider": "wqe"
}
}
}
},
"matching_state": "OFFERED"
}
When you look at the documentation of the remove() method, it needs a key from the JSON object in parameter.
However, the JSON you are receiving does not contain "com.xxx.xxxx" as key, but some keys, like "resource_list", are linked to another JSON object containing "com.xxx.xxxx" as a key.
You may want to look recursively into the JSON object you receive to remove the intended String.
You need to perform your operation over your array:
jo.getAsJsonObject("resource_list").remove("com.XXX.XXXX");
This should do the trick.
how to calculate total value for the below JSON value U.O.M Wise in Java?
sequence can be vary. We cannot expect number of uoms and sequence of results.
i have created hashset and made unique uom.
{
value=100
uom=kg
},
{
value=200
uom=kg
},
{
value=100
uom=lt
},
{
value=100
uom=ab
},
{
value=100
uom=lt
}
Please provide some code ref
This is not valid JSON as it uses = as key\value separator (change to something like this and use tools like JSONLint to validate):
[{
"value": "100",
"uom": "kg"
}, {
"value": "200",
"uom": "kg"
}, {
"value": "100",
"uom": "lt"
}, {
"value": "100",
"uom": "ab"
}, {
"value": "100",
"uom": "lt"
}
]
Even having this structure you can parse it into a collection of touples (value, uom) and then just sum everything having same uom
For example you can use this:
javax.json.JsonArray body = Json.createReader(new StringReader(YOUR_JSON_STRING)).readArray();
and read a JSON to array of touples
The goal is to start with a JSON string, parse it, and then recursively process every object property or array element. If the value is an array, and every element of the array is an object that contains a "Name" property, sort the array by the object.Name. The recursion is important, because the real-world JSON I am going to have to apply this to has three levels of nested arrays that need to be sorted.
Once the arrays are sorted into a deterministic order, finally, it should re-serialize the whole thing with properties in alphabetical order.
The purpose of this is to ensure consistency of the JSON, so I can do string comparison between the expected and the actual, and have it not be thrown off if things are serialized in a different order, or the array elements come back in a non-deterministic order (which is currently the case).
In pseudo-code, it would look something like this:
process_array( arr ) {
if ( arr.every( e => e.has("Name") ) ) {
arr.sort( byName )
}
arr.forEach( process )
}
process_object( obj ) {
for each key in obj {
process( obj[key] )
}
process( it ) {
if ( isArray( it ) {
process_arr( it )
} else {
process_object( it )
}
}
standardize( json ) {
generic_obj = parse( json )
process( generic_obj )
return serialize_with_sorted_keys( generic_obj )
}
To make it concrete, given this input:
[
{
"Id": "1",
"Name": "foo",
"Children": [
{
"Name": "two",
"Value": 2
},
{
"Value": 1,
"Name": "one"
}
],
"Other": [ 1, 3, 2 ]
},
{
"Name": "bar",
"Id": "2",
"Children": [
{
"Name": "Banana",
"Value": 3
},
{
"Value": 4,
"Name": "Cherry"
},
{
"Apples": "are tasty",
"Name": "Apple",
"Value": 5
}
]
}
]
The expected output would be:
[ // array elements are sorted by .Name
{ // object properties are sorted by key
"Children": [ // sorted by .Name
{
"Apples": "are tasty",
"Name": "Apple",
"Value": 5
},
{
"Name": "Banana",
"Value": 3
},
{ // properties sorted by name
"Name": "Cherry",
"Value": 4
}
],
"Id": "2",
"Name": "bar"
},
{
"Children": [
{
"Name": "two",
"Value": 2
},
{
"Name": "one",
"Value": 1
}
],
"Id": "1",
"Name": "foo",
"Other": [ 1, 2, 3 ] // NOTE: order has been changed!
}
]
How do I do this in Java in a generic way?
I want create a pojo from a json like this
{
"1": [
{
"idmapel": 1,
"label": "Fisika"
},
{
"idmapel": 2,
"label": "Kimia"
},
{
"idmapel": 3,
"label": "Biologi"
},
{
"idmapel": 4,
"label": "Matematika"
},
],
"2":[
{
"idmapel": 1,
"label": "Fisika"
}
]
}
when i generate from http://www.jsonschema2pojo.org/ it created a 1 and 2 class, but imagine if i have more than 2 keys. i want to be able to access element by something like this ObjectClass::getList(1) or ObjectClass::getList(2)
You can use a Map to do this.
Map<String, List<Pojo>> map = deserialize(jsonSring);
where Pojo is the class which has fields idmapel and label, deserialize is a method which deserializes the json to object and jsonString is the json string value to deserialize. Then you can access lists with keys
List<Pojo> list1 = map.get("1");
List<Pojo> list2 = map.get("2");