I'm working on an android app, and the app must save a java object in json format into the SQLite database. I wrote the code for this operation, then they must extract the Json object and reconvert it into a Java Object.
When I try to call the method for deserializing the json object in to a string, I found this error in Android Studio:unhandled exception org.json.jsonexception
When I try to catch JSONException e the program runs but don't deserialize the json object.
This is the code for the method:
private void read() throws JSONException {
SQLiteDatabase db = mMioDbHelper.getWritableDatabase();
String[] columns = {"StringaAll"};
Cursor c = db.query("Alle", columns, null, null, null, null,null );
while(c.moveToNext()) {
String stringaRis = c.getString(0);
JSONObject jObj = new JSONObject(stringaRis);
String sPassoMed = jObj.getString("passoMed");
final TextView tView = (TextView) this.findViewById(R.id.mainProvaQuery);
tView.setText(sPassoMed);
// }
}
}
Can you help me please?
Yes, you need to catch the exception.
But when you catch it, you should not just throw it on the floor. Your application needs to do something about the exception. Or if you / it is not expecting an exception to occur at runtime, then at least you should report it. Here's a minimal example (for an Android app)
try {
...
JSONObject jObj = new JSONObject(stringaRis);
...
} catch (JSONException e) {
Log.e("MYAPP", "unexpected JSON exception", e);
// Do something to recover ... or kill the app.
}
Of course, this does not solve your problem. The next thing you need to do is to figure out why you are getting the exception. Start by reading the exception message that you have logged to logcat.
Re this exception message:
org.json.JSONException: Value A of type java.lang.String cannot be converted to JSONObject
I assume it is thrown by this line:
JSONObject jObj = new JSONObject(stringaRis);
I think that it is telling you is that stringaRis has the value "A" ... and that cannot be parsed as a JSON object. It isn't JSON at all.
Related
I have a service that looks like this:
public String storeTestRequest(Map<String, String> data, HttpSession session) {
JSONObject json = new JSONObject(data);
boolean hasHealthInsurance = json.getAsString("hasHealthInsurance").equals("true");
try {
this.testRequestRepository.save(new TestRequest(
json.getAsString("firstname"),
json.getAsString("surname"),
json.getAsString("street"),
hasHealthInsurance
));
return "All good.";
}
catch (Exception e) {
return "Something went wrong.";
}
}
In this example, I am saving the values of 4 fields but in fact there are much more and I don't want to validate any of them. So if all values could be saved successfully, I should get the message All good. But if some values are missing, I should get the message Something went wrong..
I have tried it with try & catch but I still get a 500 error.
Your hasHealthInsurance property is empty or null. Your exception message says it's caused by this line.
boolean hasHealthInsurance = json.getAsString("hasHealthInsurance").equals("true");
If you put this line in your try catch block, you will see the exception message in the catch block.
I call a post API which responds with details on specific addresses, however some of the responses that get returned have no data so they'll be returned as null. How do I stop the casting error in my code?
I currently only get the data as a Json Object and I'm not sure how to rework my code that so when a JsonNull Element gets returned I can handle that data.
JsonElement element = new JsonParser().parse(jsonString);
JsonObject jsonObject = element.getAsJsonObject();
jsonObject = jsonObject.getAsJsonObject("response"); // This is either an object or it is null
String buildName = jsonObject.get("buildingName").getAsString();
String buildNum = jsonObject.get("premisesNumber").getAsString();
String streetName = jsonObject.get("streetName").getAsString();
What I expect to be returned would be either the address details for valid addresses or no information at all for the invalid addresses.
The error that gets produced is this:
java.lang.ClassCastException: com.google.gson.JsonNull cannot be cast to com.google.gson.JsonObject
Before getAsString() check for isJsonNull(). It'll return true if object is Null.
You can rewrite your code as below
String buildName= (jsonObject.get("buildingName").isJsonNull ? null : jsonObject.get("buildingName").getAsString());
Normally is a good idea validate the data is JSON valid
public static boolean isJSONValid(String test) {
try {
new JSONObject(test);
} catch (JSONException ex) {
try {
new JSONArray(test);
} catch (JSONException ex1) {
return false;
}
}
return true;
}
Function above will return you true in case the string is a valid JSON object(could be an object or an array of objects).
After that you can continue parsing using Jackson lib or the GSON lib
I know that it's a bad practice to use Exceptions for flow control. But I faced the following situation: I need to parse JSON file, and if there are corrupted values for the key of a record I want to just log it and continue to parse another object from jsonArray. And even if the value is null I want to ignore it and go on.
So in my current implementation I use a try/catch block with continue. What would be a more correct approach here?
Here is how I've implemented it:
public static void parseMetrics(JSONParser parser, File jsonFile,
String metricKey, List<String> metricsList) throws IOException, ParseException {
JSONArray jsonArray = (JSONArray) parser.parse(new InputStreamReader(new FileInputStream(jsonFile)));
for (Object obj : jsonArray) {
try {
JSONObject jsonObject = (JSONObject) obj;
String metricValue = (String) jsonObject.get(metricKey);
Long metricDate = parseDate(jsonObject);
metricsList.add(new Metric(metricValue, metricDate));
} catch (java.text.ParseException e) {
continue;
log.error("Error when parsing JSON", e);
}
}
}
Actually you want to log with the error level the parsing problem.
So throwing a exception makes sense.
If the parsing error is an abnormal situation you should keep your way but just without the continue that is not convenient here :
for (Object obj : jsonArray) {
try {
JSONObject jsonObject = (JSONObject) obj;
String metricValue = (String) jsonObject.get(metricKey);
Long metricDate = parseDate(jsonObject);
metricsList.add(new Metric(metricValue, metricDate));
} catch (java.text.ParseException e) {
log.error("Error when parsing JSON", e);
}
}
But if you consider that the parsing problem is not an issue to log but a normal scenario that may happen, indeed you don't have to propagate the exception from parseDate() but you could return something like OptionalLong instead of Long.
It would give from the client side :
for (Object obj : jsonArray) {
JSONObject jsonObject = (JSONObject) obj;
String metricValue = (String) jsonObject.get(metricKey);
OptionalLong metricDate = parseDate(jsonObject);
metricDate.ifPresent(d -> metricsList.add(new Metric(metricValue, d));
}
You could also add a log in debug or info level if it makes sense.
This question already has answers here:
What is a NullPointerException, and how do I fix it?
(12 answers)
Closed 5 years ago.
I'm learning java recently and when I wanted to parse the data from a weather website, I got this error and I still can't figure it out, can anybody tell why I got this error: java.lang.NullPointerException ?
public class main {
public static void main(String []args) {
try {
URL url = new URL("http://api.worldweatheronline.com/premium/v1/past-weather.ashx?key=caa2f68a7b2b43a09c115021171404&format=json&q=atlanta&date=2015-07-20&tp=24");
InputStream is = url.openStream();
JsonReader rdr = Json.createReader(is);
JsonObject obj = rdr.readObject();
JsonArray data = obj.getJsonArray("weather");
JsonObject objectOfData = data.getJsonObject(0);
System.out.println(objectOfData.getString("date"));
} catch (Exception ex){
System.out.println(ex);
}
}
}
Here is the data parsed from Postman:
Here is the trace log:
Here is the picture of line 19
You may print the stack trace in the catch method, and find on which line there is error and act accordingly.
Part 1: Error with Callback
I checked your URL in my browser and it appears you have the callback parameter set to wrap the json with a request callback which looks like this:
request({"data": .... })
The parser is getting hung up on the first character which it doesn't recognize as proper json.
Try this URL instead:
http://api.worldweatheronline.com/premium/v1/past-weather.ashx?key=caa2f68a7b2b43a09c115021171404&format=json&q=atlanta&date=2015-07-20&tp=24
Part 2: Null Pointer Exception
The json is being parsed out of order. You needed to create an object from the root element "data" before accessing the array.
try {
URL url = new URL("http://api.worldweatheronline.com/premium/v1/past-weather.ashx?key=caa2f68a7b2b43a09c115021171404&format=json&q=atlanta&date=2015-07-20&tp=24");
InputStream is = url.openStream();
JsonReader rdr = Json.createReader(is);
JsonObject obj = rdr.readObject();
JsonObject objectOfData = (JsonObject) obj.get("data");
JsonArray data = objectOfData.getJsonArray("weather");
JsonObject a = data.getJsonObject(0);
System.out.println(a.getString("date"));
} catch (Exception ex){
System.out.println(ex);
}
I'm trying to parse a simple JSON string
try {
String candyJson = "{\"candies\":[ {\"name\":\"Jelly Beans\", \"count\":10}, {\"name\":\"Butterscotch\", \"count\":6}]}";
JSONObject candiesJSONobject = new JSONObject(candyJson);
JSONArray candiesJSONarray = candiesJSONobject.getJSONArray("candies");
Log.v("JSONObject", candiesJSONarray.getJSONObject(0).getString("name"));
} catch (JSONException e){
Log.e("MYAPP", e.toString());
}
The code works fine in this state without catching any exception and prints JSONObject name in the Android Log.
However when I don't try to catch the exception as shown in the following example:
String candyJson = "{\"candies\":[ {\"name\":\"Jelly Beans\", \"count\":10}, {\"name\":\"Butterscotch\", \"count\":6}]}";
JSONObject candiesJSONobject = new JSONObject(candyJson);
JSONArray candiesJSONarray = candiesJSONobject.getJSONArray("candies");
Log.v("JSONObject", candiesJSONarray.getJSONObject(0).getString("name"));
Android Studio gives me unhandled exception error on all JSON methods. Is it necessary to catch JSONException when parsing a JSON or am I doing something wrong?
This is a Java feature actually :-) Please read more about it here.
The idea is that - if a method states that it will throw an (non-Runtime) Exception, all the calls of that method are required to catch this exception, just in case.
It does not mean that you are getting this exception in your code, you can only see that when you actually run it. But Java requires you to be prepared for a situation where such exception is thrown.
Well since you're working with the org.json... json objects, yes most of their methods do throw exceptions that you must catch and handle.
However if you don't want to handle each exception on it's own i suggest you create a json utils class that will handle those things for you.
For example for the JSONObject constructor you can make your own method like so
public static JSONObject createObjectFromString(String objectString) {
try {
return new JSONObject(objectString);
} catch (JSONException e) {
Log.e("MYAPP", e.toString());
}
}
and just reuse this method when you want to create a new json object.
Yes actually if any method is throwing Exception you need to catch that Exception.
This is called as Checked Exceptions or Compile Time Exceptions.
In your case methods like
JsonArray getJsonArray(String name)
or
JsonObject getJsonObject(String name)
check here http://docs.oracle.com/javaee/7/api/javax/json/JsonObject.html#getJsonArray-java.lang.String-
are throwing ClassCastException So you either catch it or throw the exception.
Throwing Exception will lead to crash the app, So better Catch it.
If any method throws checked Exception, then caller can either handle this exception by catching it or can re throw it by declaring another throws clause in method declaration.
This is the reason Android Studio is showing unhandled exception error.