Gson 'fromJson' issue - java

I am trying to bind JSON to Java POJO class using com.google.gson.Gson
like this :
MyClass data = gson.fromJson(jsonString, MyClass.class);
When I am using below mentioned it's working fine
{
"data": "{\"key1\":{\"key11\":\"192.192.1.192\",\"key12\":\"WEB\"}}"
}
However, when below-mentioned data is used, I am getting MalformedJsonException
{
"data": "{"key1":{"key11":"192.168.1.158","key12":"WEB"}}"
}
Log :
com.google.gson.JsonSyntaxException: com.google.gson.stream.MalformedJsonException:
Unterminated object at line 1 column 354 path

You can not use " within a String to quote your JSON keys and values. You either have to escape them (like you did in your first example) or you have use single quotes '.
You are effectively trying to do String concatenation without using +.
This looks for the compiler like a list of Strings with variables in between:
"{"key1":{"key11":"192.168.1.158","key12":"WEB"}}"
The compiler would expect something like this:
"{" + key1 + ":{" + key11 + ":" + 192.168.1.158 + "," + key12 + ":" + WEB + "}}";
If you look at the String this way you immediately see the problem. That's why you should either escape the quotes or use single quotes:
"{\"key1\":{\"key11\":\"192.168.1.158\",\"key12\":\"WEB\"}}"
"{'key1':{'key11':'192.168.1.158','key12':'WEB'}}"

Related

evaluate JSON expression in child object

I am trying to evaluate json expression using Josson, but it gives invalid function error
String json ="{\"data\":{\"B\":\"calc(348+(96*$.SelectedPump.stg*$.ModelMaster.count))\"},\"SelectedPump\":{\"stg\":10,\"ab\":200},\"ModelMaster\":{\"count\":20}}";
Josson josson = Josson.fromJsonString(json.toString());
System.out.println(josson.getNode("data.eval(B)"));
Stacktrace:
Exception in thread "main" java.lang.IllegalArgumentException: Invalid function call eval() : Invalid function call calc() : Calc syntax error.
at com.octomix.josson.FuncDispatcher.apply(FuncDispatcher.java:84)
at com.octomix.josson.JossonCore.getPathBySteps(JossonCore.java:328)
at com.octomix.josson.JossonCore.getPathBySteps(JossonCore.java:352)
at com.octomix.josson.JossonCore.getPathBySteps(JossonCore.java:249)
at com.octomix.josson.JossonCore.getPathByExpression(JossonCore.java:211)
at com.octomix.josson.JossonCore.getNodeByExpression(JossonCore.java:147)
at com.octomix.josson.JossonCore.getNodeByExpression(JossonCore.java:142)
at com.octomix.josson.Josson.getNode(Josson.java:279)
The variables inside the math equation cannot contains special characters. You need to use substitution. The variable name can whatever you want without special characters and .. So, the statement of B become...
calc(348+(96*A*B), A:SelectedPump.stg, B:ModelMaster.count)
The function eval() in query data.eval(B) works on node data. So the original evaluation statement needs $. to re-start from the root to get the value. For this revised version eval(data.B), eval() works on the root node with parameter data.B. And therefore, $. is not necessary.
String json =
"{\n" +
" \"data\": {\n" +
" \"B\": \"calc(348+(96*A*B), A:SelectedPump.stg, B:ModelMaster.count)\"\n" +
" },\n" +
" \"SelectedPump\": {\n" +
" \"stg\": 10,\n" +
" \"ab\": 200\n" +
" },\n" +
" \"ModelMaster\": {\n" +
" \"count\": 20\n" +
" }\n" +
"}";
Josson josson = Josson.fromJsonString(json);
System.out.println(josson.getNode("eval(data.B)"));
// Output: 19548.0
Answer by Raymond Choi would be the best solution.
Alright, I have found a possible solution to this using Jossons template engine.
String json = "{\"data\":{\"B\":\"calc(348+(96*{{SelectedPump->stg}}*{{ModelMaster->count}}))\"},\"SelectedPump\":{\"stg\":10,\"ab\":200},\"ModelMaster\":{\"count\":20}}";
Jossons jossons = Jossons.fromJsonString(json);
String output = jossons.fillInPlaceholder("{\"s\":\"{{data->B}}\"}");
output = jossons.fillInPlaceholder(output);
System.out.println(output);
System.out.println(Josson.fromJsonString(output).getNode("$.eval(s)"));
It is necessary to adjust the JSON string to use placeholder to access the values from a different/nested node. We also have to create a new JSON string with a template that is filled in. Also also, it does sadly not recursively replace the placeholder, making it necessary to call jossons.fillInPlaceholder() two times. The first time it fetches the calculated formula and the second time it replaces the placeholder that are now present in the formula.
The output is:
output -> {"s":"calc(348+(96*10*20))"}
Josson.fromJsonString(output).getNode("$.eval(s)") -> 19548.0
The proposed code in the question fails, because Josson is not able to resolve nested/different node values. Pretty much as soon as we have a . present in the calc() formula, the syntax check fails. It is however possible to access nodes at the same level. So a JSON like this:
{
"data" : {
"B" : "calc(348+(96*SelectedPumpStg*ModelMasterCount))",
"SelectedPumpStg" : 10,
"ModelMasterCount" : 20
}
}
can be evaluated by:
String json = "{\"data\":{\"B\":\"calc(348+(96*SelectedPumpStg*ModelMasterCount))\",\"SelectedPumpStg\":10,\"ModelMasterCount\":20}}";
Josson josson = Josson.fromJsonString(json.toString());
System.out.println(josson.getNode("data.eval(B)"));
resulting in the same: 19548.0.
Either way, the input JSON has to be adjusted to work with Josson

getJSONArray from root objects in JSON format - Java

I've been spending the last couple of days trying to format a JSON string into a JSON object, but this is not quite the usual json string. Im receiving it from an url and have no problem converting it into a string but when im going to create the JSON object Ive found a whole lot of issues.
The JSON looks like this:
header {
gtfs_realtime_version: "1.0"
incrementality: FULL_DATASET
timestamp: 1511789066
}
entity {
id: "294-131-39-562-4732025"
vehicle {
trip {
trip_id: "131-39-562-4732025"
route_id: "131"
}
position {
latitude: 3.44351
longitude: -76.52622
}
timestamp: 1511789065
stop_id: "501450"
vehicle {
id: "21002"
label: "MC21002"
license_plate: "VCQ452"
}
}
}
entity {
id: "1087-431-55-35-4732025"
vehicle {
trip {
trip_id: "431-55-35-4732025"
route_id: "431"
}
position {
latitude: 3.3767517
longitude: -76.54276
}
timestamp: 1511789065
stop_id: "502150"
vehicle {
id: "31038"
label: "MC31038"
}
}
}
as you can see there is no array, nor commas separating the element that I need to process (entity), I cant even get the JSONObject from the root.
Any suggestions?
This is the last block of code I've tried in which I remove the header, insert all the entity objects into the array buses, and separate them by commas, but is no use
//getRespuesta(); gives me the string
//Log.d("LIVE", "RAW JSon: " + getRespuesta());
String[] parts = getRespuesta().split("[}]", 2);
String[] splitter = parts[1].split("(?=entity)");
String finalString = splitter[1];
for (int t = 2; t < splitter.length; t++) {
finalString = finalString + ",\n" + splitter[t];
}
Log.d("LIVEL", "SIZE: " + splitter[1]);
String JSonChunk = "{ \n \"buses\": [ \n " + finalString + "\n ] \n }";
//String JSonChunk = "{ \n " + parts[1] + "\n }";
try {
// Log.d("LIVE", "CHUNKED JSon: " + JSonChunk);
JSONObject json = new JSONObject(JSonChunk);
}catch........
As was mentioned in the comments and as you've seen you can't use a JSON parser on non-JSON. I'd take the following approach:
If this meets the specifications of a known format, someone has probably written a JSON converter you can run it through.
If it is a custom format but each line is a predictable format and does not rely on anything before or after, you can run each line through a custom converter and give it the 'JSON-ness.' (add commas, etc) Process each line at at time rather than trying to split up the whole thing at once.
If none of the above are true, you need to go into regular expression hell. Sorry :(
From my point of view you must transform it to a valid JSON String
You can try this regex:
https://regex101.com/r/15dHwd/1
That means, for each group that capture tou replace it with ": {"
That way: "position {" will re replaced with "position: {"
Now you have other issue,
"entity" appears twice
If you are 100% sure that you will get always that format, after the first replace:
Start with appending "{" on the beginning of the string
Get a regex to find the "entity" String
Replace the first match with "array: [ entity"
List item
On the end of the string append: "]}"

Java regex pattern match for []

I have a string output which I need to match and I am using a regex
String schemaName = "Amazon";
String test = "{\"data\": [], \"name\": \"Amazon\", \"title\": \"StoreDataConfig\"}";
String output= method("\\[\\]",schemaName);
Matcher n = Pattern.compile(output).matcher(test);
boolean available = n.find();
System.out.println(available);
I wanted to validate the same and passing the regex to a method as mentioned
private static String method(String data, String schemaName) throws IOException {
System.out.println(data);
return ("{\"data\": " + data + ", \"name\": " + "\"" + schemaName + "\"" + ", \"title\": \"StoreDataConfig\"}");
}
But I am always getting java.util.regex.PatternSyntaxException: Illegal repetition.
Can you let me know what is the mistake?
If I don't use a method for [] and just giving it directly, I am not getting an error
It looks like you are doing this:
Take a valid regex for matching [].
Embed the regex in some JSON
Attempt to compile the JSON-with-an-embedded-regex as if the whole lot was a valid regex.
That fails ... because the JSON-with-an-embedded-regex is not a valid regex.
For a start, the { character is a regex meta character.
But the real puzzle is .... what are you actually trying to do here?
If you simply want a regex that matches a literal string then this will do it.
Pattern p = Pattern.compile(Pattern.quote(someLiteralString)).
And you could build a regex out of sub-regexes and literal strings by using Pattern.quote to escape the literal parts and then concatenating.
If what you are ultimately trying to do here is to extract information from a JSON string using pattern matching / regexes, then ... don't. The better approach is to use a proper JSON parser, and extract the information you need from the JSON object tree.
It's because you need to escape {} characters like this "\\{"

Error with Jongo parsing JSON

I'm using a combination of Java Play Framework, MongoDB and Jongo as my go between for a basic web CRUD app. I keep receiving a JSON parse exception even though my string doesn't contain any illegal characters. It's actually failing on closing curly bracket at the end of the statement. Below is my error and code. The query string is just a string builder, searching if an object is empty or has a value, if it has a value it's appended to a string.
Jongo method:
public static Iterable<OneDomain> findWithQueryString(String queryString){
return domains().find("{#}", queryString).as(OneDomain.class);
}
Controller Methods:
String builder example:
if(queryStringBuilder.toString().equalsIgnoreCase("")){
queryStringBuilder.append("date: {$gte : " + searchObj.dateFrom + ", $lt: " + searchObj.dateTo + "}");
}else{
queryStringBuilder.append(" , ");
queryStringBuilder.append("date: {$gte : " + searchObj.dateFrom + ", $lt: " + searchObj.dateTo + "}");
}
String queryString = queryStringBuilder.toString();
Iterable<OneDomain> filteredIterable = OneDomain.findWithQueryString(queryString);
Gives me this error:
Caused by: com.mongodb.util.JSONParseException:
{"source : Online Lists , blacklist : true , vetted : true , is : false , isNot : true"}
^
with the error on the "}" ending it.
In addition to that, if I try to escape the characters by putting in a \" so it becomes \"date\" it will parse and error out like so:
Caused by: com.mongodb.util.JSONParseException:
{"\"source\" : \"Online Lists\" , \"blacklist\" : true , \"vetted\" : true , \"is\" : false , \"isNot\" : true"}
You're building JSON by hand, and doing it wrong. You need to learn the basic JSON syntax requirements
A basic JSON-encoded object is
{"key1":"value1","key2":"value with \" escaped internal quote"}
Note all of the quotes. Your json string is a single very long object key with no associated value, which is not permitted. All keys must have values.

Adding a " to a string in code

I'm writing some code for web services for my Android app which uses JSON. The url should look like this
url = url + "?maddr=" + mailAddr + "&pwd=FB&lect=" + """ + lectName + """ + "&fb=Test";
This is because the Lectname may be two or more words. However the compiler wont accept """, is there a character I can precede the " with to get the compiler to accept it into my string?
Try " \" ". You have to escape the "
http://en.wikipedia.org/wiki/Escape_character
You need this in (nearly) every programming language.

Categories

Resources