Put missing double quotes in a JSON string value in java - java

I have a json string where all the values need to be surrounded with double quotes. for example (just a sample, it contains many similar fields)
{"Id": "2017",
"Currency": "AUD",
"Date": 2020-06-22,
"InCash": 0.000,
"Dep": "ABC90",
"sumCash": 770.87,
"AnotherDate": 2020-06-21}
to
{"Id": "2017",
"Currency": "AUD",
"Date": "2020-06-22",
"startCash": "0.000",
"Dep": "ABC90",
"sumCash": "770.87",
"AnotherDate": "2020-06-21"}
I am trying with regular expressions but its breaking the 'Date' fields.
jsonString.replaceAll(":[ ]*([\\w#\\.]+)", ": \"$1\"")
also tried with gson library, but its only putting the quotes on date values and not on the decimal values.
new JsonParser().parse(jsonString).toString()
What exactly I need to do to achieve it?

check this out
var newS = jsonString.replaceAll(": +((?!\\\\).*)(!?[,|}] *)", ": \"$1\"$2").replaceAll("\\\"\\\"","\"");
output
{
"Id": "2017",
"Currency": "AUD",
"Date": "2020-06-22",
"InCash": "0.000",
"Dep": "ABC90",
"sumCash": "770.87",
"AnotherDate": "2020-06-21"
}

if the other JSON form (rules) of yuior string don't change, this will work for the
name - value form.
note - i did not do the part where it could be a string in a list but its doable alsero
Find:
("\s*\w+\s*"\s*:(?!\s*")(?!\s*\d+\s*(?:,|\]|}))(?!\s*[{\[])(?!\s*(?:true|false|null)\s*(?:,|\]|}))\s*)(.+?)(?=[,}])
Replace:
$1"$2"
demo
see my complete PCRE regex for parsing JSON a eally simple structure spec.
here https://regex101.com/r/H8datD/1 which is not available to java until regex engine uses recursion (functions).
note - when needing to change just one aspect of JSON where it otherwise is complient with the spec structure
it is easy to extract the code in my regex to get right down to the area of interest. it easy !

Got it working with the below regex expression.
jsonString.replaceAll(": [ ]*([\\w#\\.-]+)", ": \"$1\""));
Thanks everyone for your help and support !

Related

Document.parse() constructor not working for nested json array

I have one extended json string.
{"_id": {"oid": "59a47286cfa9a3a73e51e72c"}, "theaterId": {"numberInt": "101100"}, "location": {"address": {"street1": "340 XDW Market", "city": "Bloomington", "state": "MN", "zipcode": "12427"}, "geo": {"type": "Point", "coordinates": [{"$numberDouble": "-193.24565"}, {"$numberDouble": "144.85466"}]}}}
Trying to convert above json string to document in order to insert it into MongoDB. For this I am using org.bson.Document.Document.parse(json_string) constructor.
But the document I am getting after parsing, doesn't preserve the datatype inside geo.coordinate arraylist (Check below Document). While it preserve datatype of theaterId.
{
"_id": {
"oid": "59a47286cfa9a3a73e51e72c"
},
"theaterId": {
"numberInt": "101100"
},
"location": {
"address": {
"street1": "340 XDW Market",
"city": "Bloomington",
"state": "MN",
"zipcode": "12427"
},
"geo": {
"type": "Point",
"coordinates": [-193.24565, 144.85466]
}
}
}
Is this a potential issue in Document.parse() API ?
Your fields in geo.coordinate are starting with dollar sign $. In theaterId you have numberInt, while in coordinate - $numberDouble.
Check the docs and this question for how to handle it depending on what you need. Considering, that it looks like numberInt satisfies your needs, you might just need to remove the dollars from field names.
Edit: After digging somewhat deeper into those docs, the one you provided as well, {"numberInt": "101100"} is not extended json with datatype, it's just a normal json object with property and value for that property. It would need to be {"$numberInt": "101100"} to be extended json. On the other hand {"$numberDouble": "-193.24565"} is extended. The datatype is not lost, it's parsed into List<Double>, since we know each element is of type Double the datatype can be reconstructed back.
If you take at Document.toJson(), under the hood it's working with RELAXED output mode, which will output coordinates as you are seeing them - [-193.24565, 144.85466]. If you provide EXTENDED output mode, for example like this:
JsonWriterSettings settings = JsonWriterSettings.builder().outputMode(JsonMode.EXTENDED).build();
System.out.println(document.toJson(settings));
then the datatype will be reconstructed back from the java type, and coordinates will look like so:
[{"$numberDouble": "-193.24565"}, {"$numberDouble": "144.85466"}]
In conclusion, there is no problem with Document.parse("json"), but there might be a problem with the json you are supplying to it.
Edit2:
As in showed in example, the datatypes can be reconstructed back from java types. I am not familiar with the way collection.insertOne(Document.parse(json_string)) works under the hood, but if you don't explicitly specify the mode, it might be using RELAXED by default, instead of EXTENDED. The docs here state - This format prioritizes type preservation at the loss of human-readability and interoperability with older formats., so it would make sense. But this is just a wild guess on my part though, you would need to dig into docs to make sure.

Get a dump of a section (object) of JSON

I'm looking to dump, rather toString() a section of JSON that I want to store locally as a string, since it it is highly variable and not imperative for me to know the contents.
I'm using JsonReader for the parsing:
https://developer.android.com/reference/android/util/JsonReader.html
Unfortunately, when I reach the token that contains what I want to dump, JsonReader does not have a method for dumping the entire JSON to a string.
This is the closest that it has:
https://developer.android.com/reference/android/util/JsonReader.html#toString()
It seems that I may have to use regex to pull out the value of the token I am targeting.
Is there another, better solution? How would I do this with regex?
Assume that this is the sample JSON and I am targeting the user key:
{
"id": 912345678901,
"text": "How do I read JSON on Android?",
"geo": null,
"user": {
"name": "android_newb",
"followers_count": 41
}
}

JSON validation shema using Java

I have this JSON:
{
"header":
{
"IssuerID": "000141",
"AuthenticationID": "e07020c0d040a050a0808099",
"AuthenticationDateTime": "20151103093035",
"AuthenticationDateTimeGMT": "20151103093035",
"Signature": "MThEMTExQkMzQzM0OUIxQjM5MDc2MjFGMzMyQjhDNTk1OTI0NDNERTg5ODcwQjNFOTc0ODQwNThBNkQxNTgzNTk2N0YzN0I2OTkyMzI1QjY2OENDQjgxRUNERDlGNDFDNzVCMzQ5Njg5NTY4NzkwNUQ5MzBDN0ExOTVGOUY0OUY2QjlCQzlDQkREOEQ3NjEzRkQ2OEYyMDhEQTY2QTkzNUZDM0UzOTI3RDk2OTYwODg4NTkyNzYyQUJCQkJFREZGNzNCNEEyNUU5OTc5OTFFODk2MTQ0Q0Y4Q0RGNzg1M0JBQTM4QkZBQzRFRUY2MTkzM0E4REI3QkQ0MEJBRkU4OTlEOTVDNTkxOTQ0M0IwNjMyMzZDQ0U4MzdBQTQzODU3RkMyOEQ0Rjk2NUMyRkNERUM0NDREQkIzNUM0QUVERDUzRjFBOTk5RTQ4Mjk4MzNERjU3RTQ1QUE2Nzc4MDUyRTdERTdGRTVFRURGRkVGMTlFN0Y2QTAyQTVCNjk3NUU2OUNGRUU3MzRGNDZDOTE0Q0U3NTk5NzdGNDkyOTdFQkRGREIwNDBCNDhBQTkzMzE1QjU0MzI1Njk0MjgxMjVDMzM5OUM3MTExNTg4NENBOTU3QTM4OTU5MTY5OTQ1NkQ2NDNFOUVEMjU5MjRDNzhEMDQxMEJGM0ZEQUVFM0Y1QTU="
},
"body":
{
"TransactionDateTime": "0151103093035",
"TransactionID": " SP020110216",
"IASauthenticationRequestReferenceID": "h0IrqhqBoUpUCiSv17NB0vHvABIUxHGCurJZFzUWdZJz9TxYio",
"VerificationID": "h0IrqhqBoUpUCiSv17NB0vHvABIUxHGCurJZFzUWdZJz9TxYio ",
"Acquirer_id": "000014",
"MerchantName": " Twin Hotel ",
"CurrencyCodeISO": "360",
"Amount": "970000.00",
"CardNumber": " BmaHLuFRg4SaPnaGB07t5fNrHXr/lyOa ",
"AuthenticationResponseCode": "00",
"AuthenticationResponseDetails": "Success",
"ValidityDateTimeExpireGMT": "20151103094035",
"Expiry_Period": "10"
}
}
How can I validate this json? For example, issuer id must be integer and have min and max values and if someone put headers instead of header it can get result: "json not valid".
I'm using java and json.org.simple for parsing.
Can anyone help me?
If you are looking for real schema validation you might want to have a look at http://json-schema.org/. There are validators for most common languages.
Assuming there are classes to represent the above structure you could try to use Java Bean Validation.
In your case, I would use a deserializer like jackson and not a json-schema, since you seem to have integer and dates encoded as string in your json. Thus, in a json-schema you would need to define strange regex. To see how to use jackson and to weigh the pros and cons of each method you can take a look a my blog post here: Three Ways to Validate JSON in Java

Mapping JSON Array to Java POJO

How would i map this JSON to an object?
{"d":"[{\"Key\":\"3\",\"ExternalKey\":\"143234A\",\"Name\":\"cup of juice\",\"Litres\":\"2 litres\",\"Date\":\"2016-10-06T08:32:27\",\"Capacity\":5.4900,\"CapacityType\":\"%\"}, {\"Key\":\"3\",\"ExternalKey\":\"143234A\",\"Name\":\"cup of milk\",\"Litres\":\"2.4 litres\",\"Date\":\"2016-10-06T08:32:27\",\"Capacity\":1667.6100,\"CapacityType\":\"M\"}]"}
I've tried using a HashMap but it just puts "d" as the string and the rest as a String object with one element
This is an extremely common problem known as data marshaling. In java, Jackson is the general best solution. Read this tutorial: http://wiki.fasterxml.com/JacksonInFiveMinutes
Your Json string has some extra " characters.
This is the final json:
{
"d": [
{
"Key": "3",
"ExternalKey": "143234A",
"Name": "cup of juice",
"Litres": "2 litres",
"Date": "2016-10-06T08:32:27",
"Capacity": 5.49,
"CapacityType": "%"
},
{
"Key": "3",
"ExternalKey": "143234A",
"Name": "cup of milk",
"Litres": "2.4 litres",
"Date": "2016-10-06T08:32:27",
"Capacity": 1667.61,
"CapacityType": "M"
}
]
}
Now you can copy the json and paste it here to get the pojo.
There are n numbers of libraries available for parsing the JSON and convert into in java classes.
Some of the examples are,
GSON
Jackson
Logan Square
Moshi, etc
You need to create a java class which map with your JSON Response and need to change your pojo according to parsing library.
For Example,
Using Logan Square you must annotate your POJO class to #JsonObject and all properties must be annotated with #JsonField.
Now, you can parse your json using method
...
LoganSquare.parse(jsonString, pojoClassName);
...
Hopefully this will help you.
Cheers
if i substring out the "d" key and map it as a JSON Array it works, that'll have to be the solution for now...

How to convert Invalid JSON String to JSONObject in Java?

I have a string response like below which is a invalid json as it contains "obj13=".I want to convert it to a JSONObject(JAVA) and use it.Is there any good way to convert it to JSONObject without using String split operation.
obj13={
players: [
{
name: "rocky",
place: "brazil",
age: "21",
},
{
name: "andy",
place: "New Zealand",
age: "23",
}
]
}
This is, of course, JavaScript, not JSON. If you can, I would go back to the service provider and ask for a JSON response.
If the format of the string is consistent, you could just use:
json=json.substring(json.indexof('=')+1);
and then parse the result. Note that most good parsers should have an option to allow the keywords without quotes and to allow the extraneous commas (mine does, but unfortunately for you it doesn't create JSONObject's but is of a lower level - it's designed to construct the data-structure of the caller's choice, which could be a JSONObject if that's what you wanted but you'd have to code it).
If the result may or may not have the assignment, you may want to get a bit fancier and ensure that the non-whitespace characters before the '=' are valid for a JS identifier and the first non-whitespace after it is '{'.

Categories