Read multipile JSON objects from single file with Jackson - java

I'm using Jackson 2.6.5.
I'm trying to read the following JSON:
{
"metadata1":"value",
"metadata2":"value"
}
{
"field1":"value",
"field2":"value",
....
}
With the following code:
JSONObject jsonObj = new JSONObject(jsonString);
But jsonObj contains only the "first" part of my JSON (the metadata), How can I read the "second" part of my JSON? (the part with the fields)?
EDIT
I know that my JSON doesn't contain "," so how can I parse it without "," between the jsons?

Seems like the JSON you added is missing a , sign between the two objects.
If you get such an non-json as input string, you might want to consider to:
First manipulate the input string by adding it the missing , . E.g. find the location of }{ and replace it with },{
And only then to insert it to the jackson

Your json is invalid, so you can't parse invalid json scheme by json parsing tools out of the box,
Instead you could read file by yourself into 2 strings - one valid json per string and then parse it with any json parser.

Related

Serialized JSON String as Value in JSON

I want a serialized JSON string to be treated simply as a string in my JSON when reading it using Jackson. When I simply escape the serialized JSON string and use it as a value, the serialized string gets treated as part of the JSON and parsed. Any ideas as to how to go about doing this?
For example:
"{\"payload\":\"{id:\"some-random-id\",version:554471325}\"}"
I would like this to be read in memory something like the following:
{ payload: "{id:\"some-random-id\",version:554471325}" }
However, the parser is trying to read the serialized string as JSON and turn it into the following:
{ payload: {id:"some-random-id", version:554471325} }
Note the difference between the two outputs. In one case, the value associated with payload is a string, in the other it's a JSON object. I'm trying to get the former, what I'm getting instead is an attempt at the latter.
Valid JSON is "set of name/value pairs", so what are you missing is the name field, and it's the reason why it's beiing parsed.
For example if the JSON is:
{"data": "{\"payload\":\"{id:\"some-random-id\",version:554471325}\"}"}
the value of data is not going to be parsed.
Btw. the JSON in payload contains key names without quotes (should probably be {"id": 123, "version": 456})
UPDATE: Answer replaced because question changed.
The examples in the question are not valid JSON. To see what it should be, let's generate it as nested JSON strings:
ObjectMapper objectMapper = new ObjectMapper();
Map<String, Object> payloadObj = Map.of("id", "some-random-id", "version", 554471325);
String payloadJson = objectMapper.writeValueAsString(payloadObj);
System.out.println(payloadJson);
Map<String, Object> rootObj = Map.of("payload", payloadJson);
String rootJson = objectMapper.writeValueAsString(rootObj);
System.out.println(rootJson);
String rootString = objectMapper.writeValueAsString(rootJson);
System.out.println(rootString);
Output
{"id":"some-random-id","version":554471325}
{"payload":"{\"id\":\"some-random-id\",\"version\":554471325}"}
"{\"payload\":\"{\\\"id\\\":\\\"some-random-id\\\",\\\"version\\\":554471325}\"}"
The third line of output is what should have been the text of the first block in the question.
"{\"payload\":\"{id:\"some-random-id\",version:554471325}\"}"
But as you can see, that text is lacking many double-quotes and backslashes, so it is not valid nested JSON strings, so you can't expect a JSON parser to parse it.
JSON parsers are often lenient, and will do its best to parse it anyway, but don't blame the parser if it gets it wrong. Blame the original text and fix that, rather than trying to parse bad JSON.
Original Answer
Keys are supposed to be names, or numbers, not entire complex objects, but if you want a JSON as the key in another JSON, just invoke the JSON serializer twice.
Example
ObjectMapper objectMapper = new ObjectMapper();
Map<String, Object> data1 = Map.of("foo", 42, "bar", List.of(1, 1, 2, 3, 5, 8));
String json1 = objectMapper.writeValueAsString(data1);
System.out.println(json1);
Map<String, Object> data2 = Map.of("Test", "Hello World", json1, 3.14, "End", "Now!");
String json2 = objectMapper.writeValueAsString(data2);
System.out.println(json2);
Note: Map.of() and List.of() are Java 9+
Output
{"foo":42,"bar":[1,1,2,3,5,8]}
{"{\"foo\":42,\"bar\":[1,1,2,3,5,8]}":3.14,"Test":"Hello World","End":"Now!"}
I know this is a terribly worded question, and I apologize for that. However, I can't come up with a better way of wording it and I'm unable to supply code. For anyone who stumbles on this and understands what I'm asking, I found a workaround.
I encoded the serialized JSON string to base64 so it was detected by Jackson as a string rather than a JSON object.
The example in the question above becomes:
"{\"payload\":\"e2lkOiJhbnktZXhlY3V...\"}"
where e2lkOiJhbnktZXhlY3V... is a base64 encoded representation of the string "{id:\"some-random-id\",version:554471325}"

Parsing Nested JSON in java without know structure of JSON

I have a use case where i get a random jsonstring and variable name. I need to verify if that particular variable is present in that json, and if present fetch its value. For example, let us the json is as follows
{
"a" : {
"b":1,
"c":2
}
}
Along with above jsonString, say i get an input "a.b" . Now I need to return 1.
Is there any library to achieve this in java directly?
JsonPath is a library that provides the functionality you're after.
You will have to do some conversion between your input and the library's input.
As per your example, if your input is "a.b":
String convertedInput = ".." + input
JsonPath.read(json, convertedInput)

converting jsonstring to java object

I am trying to convert Json String into Java Object. It is working for other inputs just for one input its not working. Is their any other way to do this?
My code:
JsonParser parser=new JsonParser();
JsonObject sel=parser.parse(selectedTerritory).getAsJsonObject();
TmsMapItBuilderBean dataSet = new Gson().fromJson(sel, TmsMapItBuilderBean.class);
ArrayList dataList = dataSet.getResultList();
resultMapData = mapServiceDelegate.processAssetDataWithGeoCodeForTerritories(subId, dataList);
It shows the following error:
Error on json convert to object :com.google.gson.JsonSyntaxException:
com.google.gson.stream.MalformedJsonException: Unterminated object near
ddress' :'2500 LEE'S CHAPEL RD', "stat
Your JSON is broken. You use a character that delimits the field's with which you are encoding your object. Use an escape to encode ' as a string.
Example:
{ 'name': 'tom\'s Hut' }
However as someone pointed out ' are not meant to be used for JSON Objects. I highly encourage you to use double-quotes.
{"name": "tom's Hut"}
Would be the correct way...
For more information on JSONs see: http://www.json.org/

Parse serialized json payload in java

im struggling with json again :(
Here is the original response:
{"xml-fragment":{"workItem":{"#id":"251","#version":"74"},"presentation":{"#formIdenitifier":"1.0.0.201310151421/openspaceGWTPull_DefaultChannel/.default/Npda/NpdaProcess/UserReconcile/UserReconcile.gwt.json","#type":"GWT_FORM","#version":"1.0.0.201310151421","#activityName":"UserReconcile"},"workTypeDetail":{"#typePiled":"false","#pilingLimit":"0","#uid":"WT__RIoPEDWTEeOr4-yR8gXd7g","#version":"1.0.0.201310151421"},"payloadModel":{"serializedPayload":"{items:[{\"$param\":\"BankReconInput\",\"mode\":\"IN\",\"$value\":[{\"bankAccountTx_pk\":\"55213\",\"amount\":\"10099\",\"reference\":\"ImAmReference\",\"date\":\"2013-10-15\",\"reconType\":\"?\",\"amxcaseref\":\"pvm:0a12iq\",\"$type\":\"coza.npda.bom.BankTransaction\"}]}]}","#payloadMode":"JSON"}}}
i want to for example get value of amount from the serializedPayload. The problem is that it is not a json object. If i try:
obj = new JSONObject(jsonResp).getJSONObject("xml-fragment").getJSONObject("payloadModel");
this returns to me serializedPayload as a string and #payloadMode as a string.
i tried:
obj = new JSONObject(jsonResp).getJSONObject("xml-fragment").getJSONObject("payloadModel").getJSONObject("serializedPayload");
its confirms that serializedPayload is not a json object.
I looked at this example: http://developer.android.com/reference/org/json/JSONTokener.html
But its data is not as complex as mine and i am struggling to find java examples of how to do this.
Please can anyone help.
You don't need an example, you need to look at the JSON and think for a second.
serializedPayload is not a JSON object to begin with, it's really a string that has another piece of json encoded inside, sort of like the russian nesting dolls (frankly, it's an abomination).
You need to take the string, and then parse it again, using another JSONObject, sort of:
String payload = data..getJSONObject("xml-fragment").getJSONObject("payloadModel").getString("serializedPayload");
JSONObject theRealData = new JSONObject(payload);

Escape character in JSON parsing with org.json.JSONObject;

I am using org.json to parse and write json. While serializing, i.e converting to string, I see json object adds an extra escape character. How can be this be avoided, if possible ?
String jsonStr = "{\"AD\":\"</p>\"}";
JSONObject jsonObject = new JSONObject(jsonStr);
System.out.println(jsonStr);
System.out.println(jsonObject.toString());
Output:
{"AD":"</p>"}
{"AD":"<\/p>"}
A number of other StackOverflow posts point out that this happens because (1) it is allowed by the JSON spec, and (2) it allows the JSON string to be inserted as-is into certain XML/HTML contexts that would otherwise not allow strings with "</" inside them.
If this causes problems, I would seek out A Better Java JSON Library--one that lets you define more character-escaping options.

Categories