Hi guys I'm developing a Restful + JSON servlet, but I got a strange problem, if i try to compile my project source with this method:
public
static
WipdDBTable
parseJSON(String JSONBody)
{
JSONObject jsonObj;
JSONTokener jsonTok;
Iterator it;
String[] labels;
String[][] fields;
int i;
try {
jsonTok = new JSONTokener(JSONBody);
jsonObj = new JSONObject(jsonTok);
labels = new String[jsonObj.length()];
fields = new String[1][labels.length];
i = 0;
it = jsonObj.keys();
while(it.hasNext()) {
String key = it.next().toString();
labels[i] = key;
fields[0][i] = jsonObj.get(key);
i++;
}
return new WipdDBTable(labels, fields);
} catch(JSONException ex) {
return null;
}
}
I get this error:
WipdJSON.java:102: incompatible types
found : java.lang.Object
required: java.lang.String
fields[0][i] = jsonObj.get(key);
So I wrote a test class, with apparently the same source, but with this one I don't get any error:
public class jsontest
{
public static
void
main(String[] args)
{
String s1;
JSONObject jsonObj;
JSONTokener jsonTok;
s1 = "{\"lo\":\"ol\",\"json\":{\"1\":\"2\"},\"yo\":{\"lol\":\"lol\"}}";
try {
jsonTok = new JSONTokener(s1);
jsonObj = new JSONObject(jsonTok);
Iterator it = jsonObj.keys();
while(it.hasNext()) {
String key = it.next().toString();
System.out.print(key + "=>");
System.out.println(jsonObj.get(key));
}
} catch(JSONException ex) {
ex.printStackTrace();
}
}
}
jsonObj.get(key); return an Object, you need to cast it to a String if you want to get the value in a String variable. There is a getString method in the JSONObject class:
fields[0][i] = jsonObj.getString(key);
And you don't get any error in your test class as you're only outputting the value that is calling the toString() method.
fields[0][i] = jsonObj.get(key);
Change it to
fields[0][i] = (String) jsonObj.get(key);
Now, you are casting Object to String. if you are not sure it is String always check with instanceof operator.
Object obj = jsonObj.get(key);
if(obj instanceof String)
{
fields[0][i] = (String) jsonObj.get(key);
}
get method signature is look likes this
java.lang.Object get(java.lang.String key)
so definitely you have to cust it in your actual type.
for example
String key = (String)jsonObj.get(key);
Hi the error can be romove by replaceing line
fields[0][i] = jsonObj.get(key);
with
fields[0][i] = (String)jsonObj.get(key);
and it is not giving error in second code snippet because you are printing it in System.out.println but not assigning it to any String variable
System.out.println(jsonObj.get(key));
so if you try to assign it in any String variable without casting it in String variable it will also give error.
Related
This is my JSON request body to be sent for the request endpoint
{
"id": "191",
"order":"ASC"
}
HttpPost request1 = new HttpPost("/2.0/clusters/events");
Map< String, Object >jsonValues = new HashMap< String, Object >();
jsonValues.put("id", s);
//fetching id from another API and for each id fetching the events.
JSONObject jsonO = new JSONObject(jsonValues);
request1.addHeader("Authorization",bearerToken);
request1.addHeader("content-type", "application/json");
request1.addHeader("Accept","application/json");
StringEntity entity = new StringEntity(jsonO.toString(), "UTF8");
request1.setEntity(entity);
HttpResponse response1 = client.execute(request1);
String json1 = EntityUtils.toString(response1.getEntity());
event= new JSONObject(json1);
JSONArray arrays=event.getJSONArray("events");
List<JSONObject> json_Values = new ArrayList<JSONObject>();
for (int k=0;k< arrays.length();k++){
json_Values.add(arrays.getJSONObject(k));
JSONObject ids = arrays.getJSONObject(k);
String id=clusterids.get("id").toString();
String time=clusterids.get("timestamp").toString();
String type=clusterids.get("type").toString();
System.out.println("id:" + id + "\t" + "Time:" + time + "\t" + "Type:" + type + "\n");
Collections.sort(json_Values, new Comparator<JSONObject>() {
private static final String KEY_NAME = "timestamp";
#Override
public int compare(JSONObject a, JSONObject b) {
Object valA = new Object().toString();
Object valB = new Object().toString();
valA =a.get(KEY_NAME);
valB = b.get(KEY_NAME);
return ( (String) valA).compareTo( (String) valB);
}
});
JSONArray sortedJsonArray = new JSONArray();
for (int i = 0; i < arrays.length(); i++) {
System.out.println("Sorted array:"+sortedJsonArray.put(jsonValues.get(i)));
}
}
System.out.println("EVENTS:"+arrays);
}
return event;
}
Here I am comparing the two timestamp to fetch sorted response,but I am facing some exceptions like
Exception in thread "main" java.lang.ClassCastException: java.lang.Long cannot be cast to
java.lang.String
at testdatabricks.testdatabricks.Events$1.compare(Events.java:170)
at testdatabricks.testdatabricks.Events$1.compare(Events.java:1)
Can I send json body to sort the values? How to pass that? Help me to find this out.
Are you sure you want to make a string comparison? Anyway if so then your compare method is somewhat wrong and should more look like:
Collections.sort(json_Values, new Comparator<JSONObject>() {
private static final String KEY_NAME = "timestamp";
#Override
public int compare(JSONObject a, JSONObject b) {
String valA = a.get(KEY_NAME).toString();
String valB = b.get(KEY_NAME).toString();
return valA.compareTo(valB);
}
});
just because you initialise valA as a String Object (Object valA = new Object().toString();) does not mean that val stays a String Object. When you do valA =a.get(KEY_NAME); this will not cast this to a String but it stays in the type that a.get(KEY_NAME) had before (it is exactly the same object - seemingly sometimes of type Long). But String is a nice thing - as basically all Objects that you likely encounter in a JSON have meaningful toString() implementations. So you can use that to convert everything to String and make your String comparison.
But if you timestamp is always a Long your better of with a Long-comparison:
Collections.sort(json_Values, new Comparator<JSONObject>() {
private static final String KEY_NAME = "timestamp";
#Override
public int compare(JSONObject a, JSONObject b) {
Long valA = (Long)a.get(KEY_NAME);
Long valB = (Long)b.get(KEY_NAME);
return valA.compareTo(valB);
}
});
I think your bug is here from what I can make out of the stack trace:
public int compare(JSONObject a, JSONObject b) {
Object valA = new Object().toString();
Object valB = new Object().toString();
valA =a.get(KEY_NAME);
valB = b.get(KEY_NAME);
return ( (String) valA).compareTo( (String) valB);
}
your valA and valB are Long types. And that's okay because timestamps are in long format. You need to use Long instead of String. And this is how you do it:
Long valA = Long.parseLong(String.valueOf(a.get(KEY_NAME)));
Then simply return valA.compareTo(valB);
I posted here earlier and was flagged for my post being too similar to another previously answered. I don't believe this is, so have tried to reword it.
I have a JSON file where value is either a long, or can contain an object and a array:
{
"declaration-list" : [
{
"declared-variable" : "x301",
"value" : {
"operator" : "set",
"arguments" : [
0,
1
]
}
},
{
"declared-variable" : "x112",
"value" : -1
},
]
}
I have written the following code in java to parse the file and have managed to extract declared-variable from the array (Note: I'm using org.json.simple):
public static void getInput() throws IOException, ParseException {
JSONParser parser = new JSONParser();
File file = new File("myfile");
Object object = parser.parse(new FileReader(file));
JSONObject jsonObject = (JSONObject) object;
JSONArray jasonArray = (JSONArray) jsonObject.get("declaration-list");
for (Object JSI : jasonArray) {
if (JSI instanceof JSONObject) {
JSONObject declared_variable = (JSONObject) JSI;
String decVar = (String) declared_variable.get("declared-variable");
System.out.println(decVar);
JSONObject value = (JSONObject) JSI;
String operator = (String) value.get("operator");
System.out.println(operator);
}
}
}
How do I get a long from a JSONArray and deal with the case where value contains another JSONObject and JSONArray?
I hope this post is more clear, thanks.
It seems you are using the dependency (the version may differ):
<dependency>
<groupId>com.googlecode.json-simple</groupId>
<artifactId>json-simple</artifactId>
<version>1.1.1</version>
</dependency>
The appropriate value type interpretation (i.e. handling the value corresponding to its type) should be implemented.
Consider the following draft example. Take a look at the implementation of the handleDeclaredVariable method to get the basic understanding: it should answer your questions.
Update the loop:
for (final Object JSI : jasonArray) {
if (JSI instanceof JSONObject) {
handleDeclaredVariable((JSONObject) JSI);
}
}
Introduce the method:
private static void handleDeclaredVariable(final JSONObject variable) {
final String variableName = (String) variable.get("declared-variable");
final Object value = variable.get("value");
if (value instanceof JSONObject) {
final JSONObject jsonValue = (JSONObject) value;
final String operator = (String) jsonValue.get("operator");
final JSONArray arguments = (JSONArray) jsonValue.get("arguments");
System.out.println(
String.format(
"The value of the variable %s is a JSON object: operator: %s, arguments: %s",
variableName,
operator,
arguments
)
);
} else if (value instanceof Number) {
final Number numberValue = (Number) value;
System.out.println(
String.format(
"The value of the variable %s is a Number: %s",
variableName,
numberValue
)
);
} else {
System.err.println(
String.format(
"The value of the variable %s has unsupported type (%s): %s",
variableName,
value.getClass().getCanonicalName(),
value
)
);
}
}
I have a POJO class as:
public class D{
private JSONObject profileData;
public JSONObject getProfileData ()
{
return profileData;
}
public void setProfileData (JSONObject profileData)
{
this.profileData = profileData;
}
}
Now I populate this class like:
for (int i =0; i<identities.size();i++){
D d = new D();
d.setProfileData(profileData);
dList.add(d);
}
I create JSON object for profileData from GSON using a HashMap:
profileDataInJson = new JSONObject(gson.toJson(map1));
Where the signature of profileDataInJson is: JSONObject profileDataInJson = null;
Now the resultant JSON is like:
"profileData":{"map":{"ioCinema":"firstValue","ioSIMAvailable":"firstKey","Name":"onePair"}}
Wherein I get an unwanted object called map inserted in my main profileData object.
However when I print this inside the loop I get
{`"ioCinema":"firstValue","ioSIMAvailable":"firstKey","Name":"onePair"}`
Whish is exactly what I want inside profileData object, without nesting the map object.
How do I solve this?
"I am already aware that I can achieve this by converting the type of profileData in D class from JSONObject to String, which will induce escape characters - However I am looking for a generic solution"
EDIT:
map1 is constructed in two ways, depending on user input and both ways are as follows:
if (args.length >= 4 && args[1].equalsIgnoreCase("onePair")) {
map1 = new HashMap<>();
String key1 = args[2];
String value1 = args[3];
map1.put(key1, value1);
profileDataInJson = new JSONObject(gson.toJson(map1));
}
And:
if (args.length >= 1 && args[0].equalsIgnoreCase("update")) {
if (args.length >= 2)
profileData.setName(args[1] != null ? args[1] : "");
if (args.length >= 3)
profileData.setSIMAvailable(args[2] != null ? args[2] : "");
profileDataInJson = new JSONObject(profileData);
}
Signature: ProfileData profileData = new ProfileData();
The thing which puzzles me is when I try to traverse profileData and try to fetch the json object by name "map" I get a nullPointer exception
You don't need to use Gson to convert hashmap to a json object.
Simply use:
profileDataInJson = new JSONObject(map);
Add custom serializer to Gson, so that Gson serialize the org JSON as expected by you.
GsonBuilder gsonBuilder = new GsonBuilder();
gsonBuilder.registerTypeAdapter(JSONObject.class, new JsonSerializer<JSONObject>() {
#Override
public JsonElement serialize(final JSONObject src, final Type typeOfSrc,
final JsonSerializationContext context) {
return new JsonParser().parse(src.toString()).getAsJsonObject();
}
});
gsonBuilder.create().toJson(map1);
This will return {"ioCinema":"firstValue","ioSIMAvailable":"firstKey","Name":"onePair"}
JSON values that I get from server:
{
"Status":0,
"Message":"",
"Result":{"0B":"S.C. Blue Air","0Y":"FlyYeti","1X":"Branson Air"}
}
Getting the result as 'response' after connection and I am able to show my JSON string results on the screen.
JSONObject json = new JSONObject(response);
String status = json.getString("Status");
String message = json.getString("Message");
String result = json.getString("Result");
responseView.setText("Status" + status+ "Message" + message" + Result" + result);
I am okay the results of "Status" and "Message" but not with "Result" because want to separate "Result" objects as and able use each of them as objects.
For example:
When I type OB in my app, I will get the result S.C. Blue Air
Instead of :
String result = json.getString("Result");
use
if(json.get("Result") instanceof JSONObject){
JSONObject object = (JSONObject) json.get("Result");
//do what you want with JSONObject
String ob = object.get("0B");
}
If you want to store it some way you can put it to Map or create object if always it is same data
You can use some libraries such as Gson (Google) or Moshi (Square)
Those libraries allows you to declare your model as a plain java class (commonly called POJOS) annotated in some way that this libraries bind your properties in the JSON to your java properties.
In your case:
JSON:
{
"Status":0,
"Message":"",
"Result":{"0B":"S.C. Blue Air","0Y":"FlyYeti","1X":"Branson Air"}
}
MODEL:
public class MyCallResponse {
#SerializedName("Status")
int status;
#SerializedName("Message")
String message;
#SerializedName("Result")
Result result;
}
public class Result {
#SerializedName("0B")
String b;
#SerializedName("0Y")
String y;
#SerializedName("0X")
String x;
}
In this case, with Gson you can do:
MyCallResponse response = new Gson().fromJson(json, MyCallResponse.class);
Log.i("Response b", response.result.b);
Look at the documentation for more information about both libraries.
try this :
JSONObject json = new JSONObject(response);
JSONObject resultObj = json.getJSONObject("Result");
String OB = resultObj.getString("OB");
Try this
String base = ""; //Your json string;
JSONObject json = new JSONObject(base);
JSONOBject resultJson = json.getJSONObject("Result");
// Get all json keys "OB", "OY", "1X" etc in Result, so that we can get values against each key.
Set<Map.Entry<String, JsonElement>> entrySet = resultJson.entrySet();
Iterator iterator = entrySet.iterator();
for (int j = 0; j < entrySet.size(); j++) {
String key = null; //key = "OB", "OY", "1X" etc
try {
Map.Entry entry = (Map.Entry) iterator.next ();
key = entry.getKey ().toString ();
//key = "OB", "OY", "1X" etc
}
catch (NoSuchElementException e) {
e.printStackTrace ();
}
if (!TextUtils.isEmpty (key)) {
Log.d ("JSON_KEY", key);
String value = resultJson.getString(key);
//for key = "0B", value = "S.C. Blue Air"
//for key = "0Y", value = "FlyYeti"
//for key = "1X", value = "Branson Air"
}
}
It works with any array with dynamic json key.
Don't forget to accept the answer & upvote if it works.
I have Parsed some JSON data and its working fine as long as I store it in String variables.
My problem is that I need the ID in an int varibable and not in String.
i have tried to make a cast int id = (int) jsonObj.get("");
But it gives an error message that I cannot convert an object to an int.
So I tried to convert by using:
String id = (String) jsonObj.get("id");
int value = Integer.parseInt(id);
But also that is not working. What is wrong. How is JSON working with int?
My strings are working just fine its only when I try to make them as an int I get problems.
Here is my code :
public void parseJsonData() throws ParseException {
JSONParser parser = new JSONParser();
Object obj = parser.parse(jsonData);
JSONObject topObject = (JSONObject) obj;
JSONObject locationList = (JSONObject) topObject.get("LocationList");
JSONArray array = (JSONArray) locationList.get("StopLocation");
Iterator<JSONObject> iterator = array.iterator();
while (iterator.hasNext()) {
JSONObject jsonObj = (JSONObject) iterator.next();
String name =(String) jsonObj.get("name");
String id = (String) jsonObj.get("id");
Planner.getPlanner().setLocationName(name);
Planner.getPlanner().setArrayID(id);
}
}
You may use parseInt :
int id = Integer.parseInt(jsonObj.get("id"));
or better and more directly the getInt method :
int id = jsonObj.getInt("id");
It depends on the property type that you are parsing.
If the json property is a number (e.g. 5) you can cast to Long directly, so you could do:
(long) jsonObj.get("id") // with id = 5, cast `5` to long
After getting the long,you could cast again to int, resulting in:
(int) (long) jsonObj.get("id")
If the json property is a number with quotes (e.g. "5"), is is considered a string, and you need to do something similar to Integer.parseInt() or Long.parseLong();
Integer.parseInt(jsonObj.get("id")) // with id = "5", convert "5" to Long
The only issue is, if you sometimes receive id's a string or as a number (you cant predict your client's format or it does it interchangeably), you might get an exception, especially if you use parseInt/Long on a null json object.
If not using Java Generics, the best way to deal with these runtime exceptions that I use is:
if(jsonObj.get("id") == null) {
// do something here
}
int id;
try{
id = Integer.parseInt(jsonObj.get("id").toString());
} catch(NumberFormatException e) {
// handle here
}
You could also remove that first if and add the exception to the catch.
Hope this helps.
Its very simple.
Example JSON:
{
"value":1
}
int z = jsonObject.getInt("value");
Non of them worked for me.
I did this and it worked:
To encode as a json:
JSONObject obj = new JSONObject();
obj.put("productId", 100);
To decode:
long temp = (Long) obj.get("productId");
I use a combination of json.get() and instanceof to read in values that might be either integers or integer strings.
These three test cases illustrate:
int val;
Object obj;
JSONObject json = new JSONObject();
json.put("number", 1);
json.put("string", "10");
json.put("other", "tree");
obj = json.get("number");
val = (obj instanceof Integer) ? (int) obj : (int) Integer.parseInt((String) obj);
System.out.println(val);
obj = json.get("string");
val = (obj instanceof Integer) ? (int) obj : (int) Integer.parseInt((String) obj);
System.out.println(val);
try {
obj = json.get("other");
val = (obj instanceof Integer) ? (int) obj : (int) Integer.parseInt((String) obj);
} catch (Exception e) {
// throws exception
}
The question is kind of old, but I get a good result creating a function to convert an object in a Json string from a string variable to an integer
function getInt(arr, prop) {
var int;
for (var i=0 ; i<arr.length ; i++) {
int = parseInt(arr[i][prop])
arr[i][prop] = int;
}
return arr;
}
the function just go thru the array and return all elements of the object of your selection as an integer
For JsonNode use:Integer.parseInt(String.valueOf())