javax.json produces uncomprehensible json - java

I have a Java class with two atrributes that I convert to json using this method. I followed this other answer:
Return JSONArray instead of JSONObject, Jersey JAX-RS
public String toString(){
// takes advantage of toString() implementation to format {"a":"b"}
JsonObject json = Json.createObjectBuilder()
.add("sentence", sentence)
.add( "category", category).build();
return json.toString();
}
The String I get is encapsulated into an ArrayList of strings, and sent via HTTP (I am using Jersey):
return Response.status(200).entity(response).build();
How ever, the node client is use cannot parse it properly: it gets the array part, accesses the elements perfectly. But not the json keys and values;
returns undefined:
jsonRespuesta = JSON.parse(body)[0];
console.log(jsonRespuesta);
console.log("Frase: " +jsonRespuesta.sentence + " ,Categoria: " + jsonRespuesta.category);
Returns:
{"sentence":"hola","category":"2"}
Frase: undefined ,Categoria: undefined
What's failing? If it helps, capturing the packets with wireshark displays the array members as strings

Is your java client encoding the JSON twice? I noticed you are adding json strings to an ArrayList, but you should really be adding objects to the ArrayList and then stringifying the whole thing once.
Try using JSON.parse() again on jsonRepuesta and see if that gets you what you're looking for. Alternatively, log out a typeof jsonRepuesta -- looks like it's still a string.
Also, see here.

Related

Using JsonPath to parse JSON String recursively

I'm trying to parse a given JSON in String format, for example:
{
"id": "indeed",
"interaction_data":
"{\"data\":\"{\\\"something\\\":\\\"blabla\\\"}\",\"somethingElseNotNested\":\"Indeed\"}"
}
I'm working with Kotlin, and I called JsonPath.parse on the value above, the problem is, interaction_data is parsed as a String, instead of it being treated as a JSON as well.
So when I call read("$.interaction_data.data.something") it gives me an error, since interaction_data is treated as a String, instead of an object.
Any way around this? (other than parsing this part separately, I need to handle this generically).
Thanks!
Json interaction_data property is triple stringifyied. Why you don't try this
var jsonObject=..your json;
var jsonParsed=JSON.parse(jsonObject.interaction_data);
jsonParsed.data=JSON.parse(jsonParsed.data);
JsonObject.interaction_data=jsonParsed;
result
{
"id":"indeed",
"interaction_data":{"data"{"something":"blabla"},"somethingElseNotNested":"Indeed"}
}

Can't parse JSON array of objects

I have a NodeJS cloud function that takes a bunch of javascript objects (entries from a db) in the form of an array, and sends them to the client.
On the server I do this using:
return JSON.stringify(result);
Where "result" is the array of JS objects. Then I send data to the client.
In my Android client, I receive the String, and need to iterate through every object in the original array and process them separately. I can't! I always get errors like:
I: [Batch] com.google.gson.JsonSyntaxException: com.google.gson.stream.MalformedJsonException: Expected name at line 1 column 3 path $[0].
On my Android client, I have tried:
WebItemEntry [] items = new Gson().fromJson(jsonString, WebItemEntry[].class);
AND ...
ArrayList<WebItemEntry> items = new Gson().fromJson(jsonString, new TypeToken<ArrayList<WebItemEntry>>(){}.getType());
Neither seem to work. Same error as above.
The raw output I get from the database is the JSON string that consists of five individual entries that I would like to iterate through and parse. Its kind of a mess, but you can see its deliminator is the brace {. I really want to use GSON or similar in my android client to parse these entries individually and convert them to my custom Java class: WebItemEntry.
[{\"charityID\":0,\"purchaserZIP\":\"\",\"category\":\"Women\u0027s Accessories\",\"valueCents\":0}, {... same thing for a different entry here...}, {new entry ... }]
On the server ignore stringify and return plain object, those \" characters appear when js object stringify twice. so replace return JSON.stringify(result); with return result;.

How to convert Complex JSON string in to MAP in scala

I have a text file which contains a line like
players={"Messi":{"Details":{"Goals":500},"Country":"Argentina"},"Neymar":{"Clubs":["Santos", "FC barcelona", "Paris saint German"], "Country":"Brazil"}}
Now I am used a regex for extract the
{"Messi":{"Details":{"Goals":500},"Country":"Argentina"},"Neymar":{"Clubs":["Santos", "FC barcelona", "Paris saint German"],"Country":"Brazil"}}
from the text file and pass it in to a case class which accepts the value as a String.
and I am making a Dataframe using this case class.
In my case every line may be different in the contents with in the JSON String.So I am looking for a general solution to Convert any complex Json string to Map values.
When checking dataframe.printSchema, I am getting the players column as a String type.
But I need it to be as a Map type which holds a Key and value as a Struct type.
I tried method referred in this link
How can I convert a json string to a scala map?
when I used this way,I got error
"org.json4s.package$MappingException: Do not know how to convert JObject(List((Details,JObject(List((Goals,JString(500))))), (Country,JString(Argentina)))) into class java.lang.String "
and I used following solutions
Converting JSON string to a JSON object in Scala
But these too won't worked for me.
This is my case class
case class caseClass (
Players :String = ""
)
I am Extracting the json string using a user defined function.
Simply my requirement is that I have a complex Json String which contains keys and values as struct,list etc..
so I want to make the string to its corresponding JSON which holds a proper schema with respect to its contents.
Kindly expecting Valuable solutions.
If you also can live with JsValue as value instead of String it looks a bit simpler:
import play.api.libs.json._
case class CaseClass (
Players :Option[JsValue]
)
object CaseClass {
implicit val jsonFormat = Json.format[CaseClass ]
}
I saw some problems with your Json - so you would need to have something like:
val json = Json.parse("""{
"Players":{
"Messi":{"Details":{"Goals":500},"Country":"Argentina"},
"Neymar":{"Clubs":["Santos", "FC barcelona", "Paris saint German"], "Country":"Brazil"}
}
}"""
)
To get a String out of this you can use:
json.validate[CaseClass] match {
case JsSuccess(cc, _) => cc.Players.toString
case JsError(errors) => // handle errors
}
I got another solution which I think More easier.
I Made an own schema for the JSON and Used from_json method with the schema,and it worked well.
from_json(col("Players"),ownschema).as("new_Json")
and my ownschema contains the structure of the Json String.
For any doubts, Comment.
Happy Coding.

Can't get value from JSONObject

So I am using the simple json library to perform some json operations. Right now I can construct a JSONObject from a json string but I am not able to get the value from the object I created.
For example if I do something like:
String value = (String) jsonRecord.get("Key");
I will get an error saying:
java.lang.ClassCastException: org.json.simple.JSONObject cannot be cast to java.lang.String
I removed the type cast to string and it works in IntelliJ. However, when I do this at command line it gives me an error saying:
error: incompatible types: Object cannot be converted to String
The schema is as follows:
{
"myArray": {
"array": ["Decaf mocha", "Vanilla mocha", "Chai Latte"]
},
"Item": {
"string": "Decaf macha"
}
}
Update: the toString() fixed the problem. But when I tried to get the array I am getting:
java.lang.ClassCastException: org.json.simple.JSONObject cannot be cast to org.json.simple.JSONArray
Can someone please suggest how to fix the problem? Thanks!
Your value is a JSONObject, not a string. Your error message makes that quite clear. If you really want it as a string, use
String value = jsonRecord.get("Key").toString();
You can pass any object to System.out.println, not just strings, but to actually turn it to a string, you need to call toString() yourself.
However, if you're expecting an actual String as the Key, and not a JSONObject, then you should take a second look at your JSON, because you're doing something wrong.
UPDATE:
Okay, looking at your schema, I see the problem. Instead of mapping the keys to values directly, your JSON maps keys to objects which then contain values. So to get the array in the JSON you posted, instead of
value = jsonRecord.get("myArray")
you would use
JSONArray value = jsonRecord.getJSONObject("myArray").getJSONArray("array");
and for the string, you would use
String value = jsonRecord.getJSONObject("Item").getString("string");
Just need to add the current "org.json" dependency would resolve your issue as latest version holds get() method (JSONObject class) which returns Object.
Below is my maven dependency:-
<dependency>
<groupId>org.json</groupId>
<artifactId>json</artifactId>
<version>20190722</version>
</dependency>
Below is my code which performs get key operation.
public void iterateJsonObject(JSONObject jsonObj) {
jsonObj.keySet().forEach(keyStr ->
{
Object keyvalue = jsonObj.get(keyStr);
System.out.println("key: "+ keyStr + " value: " + keyvalue);
});
}
You can prevent the ClassCastException by using Generics, because Generics provide compile time checks and can be used to develop type-safe applications.
You are not converting the json record value that you are fetching into a string.
String value = String.valueOf(jsonRecord.get("Key"));
his should fix your problem. You can also use toString() method but I personally prefer String.valueOf() over it because at times toString() tends to give garbage value.

Can't get JSONArray from .net web service

I have a multi-platform Cordova app backed by a .net web service which returns JSON data for syncing. This works fine.
I am now trying to add native calls into the Android version of the app which are hooked into BroadcastReceiver so that I can provide rich notifications when the app isn't running.
The scheduling and execution of these events are running fine; but I am having real problems in processing the result of the web service call.
The web service call (VB.net) is:
<OperationContract()>
<WebInvoke(Method:="POST", ResponseFormat:=WebMessageFormat.Json)>
Public Function SyncNotifications_Native(ByVal dateAfter As String, ByVal which As Integer, ByVal userID As Int32) As String
Dim rowsList As New List(Of Dictionary(Of String, Object))()
Dim row As Dictionary(Of String, Object)
:::
:::
While dr.Read()
row = New Dictionary(Of String, Object)
row.Add("allow_reply", dr("allow_reply"))
row.Add("content", dr("content"))
row.Add("date_added", dr("date_added")
row.Add("date_deleted", dr("date_deleted")
row.Add("date_read", dr("date_read")
row.Add("deleted", dr("deleted"))
row.Add("last_update", Now().ToString("yyyy-MM-dd HH:mm:ss"))
row.Add("notification_id", dr("notification_id"))
row.Add("subject_line", dr("subject_line"))
row.Add("user_id", dr("user_id"))
rowsList.Add(row)
End While
Return New JavaScriptSerializer().Serialize(details)
End Function
This should return an array of zero or more entries.
I'm using an AsyncTask to get the data. This is the data I get back from the call:
{"d":"
[{\"allow_reply\":1,\"content\":\"test content\",
\"date_added\":\"2016-02-04 23:37:50\",\"date_deleted\":\"\",
\"date_read\":\"\",\"deleted\":0,\"last_update\":\"2016-02-04 23:38:43\",
\"notification_id\":27,\"subject_line\":\"test\",\"user_id\":1}]
"}
I've looked at various resources and have tried all types of solutions. This is what I'm currently doing:
Convert the return string to a JSON Object:
JSONObject json2 = new JSONObject(s);
Try to get the array out of the object:
JSONArray results = json2.getJSONArray("d");
This way gives me an error of:
java.lang.String cannot be converted to JSONArray
I've seen a suggestion in another post that I'm actually returning a SOAP response from my web service; I'm not sure, I haven't seen any other example JSON responses which start with
{"d":
How can I properly get the returned array into a JSONArray so that I can pass it off to another function?
Thanks
Am not a Java dev so:
{"d": "[{\"allow_reply\":1,\....."} is an Object
with a d field
whose value is a string "[{\"allow_reply\":1,\....."} and is why you get java.lang.String cannot be converted to JSONArray
so you'll have to parse (aka "deserialize")
So in Javascript (you'll have to translate to Java):
//this is the data your service returns
var foo = {"d": "[{\"allow_reply\":1,\"content\":\"test content\",\"date_added\":\"2016-02-04 23:37:50\",\"date_deleted\":\"\",\"date_read\":\"\", \"deleted\":0,\"last_update\":\"2016-02-04 23:38:43\",\"notification_id\":27,\"subject_line\":\"test\",\"user_id\":1}]"};
//parse the string
var data = JSON.parse(foo.d);
data now contains your array
So in your code above, you have to parse the string and convert it into the object it represents (from a string).
Hth...

Categories

Resources