While retrieving objects from a Json file for an Android App, I am getting a NullPointerException when I try to access to the size of a Json Array.
Here is one Json Object of the "results" array:
results: [
{
aliases: null,
api_detail_url: "http://www.giantbomb.com/api/game/3030-26559/",
date_added: "2009-05-22 10:03:31",
date_last_updated: "2014-01-14 08:27:36",
deck: "All three Metroid Prime titles in one package. Metroid Prime and Metroid Prime 2: Echoes are reworked to include 480p widescreen, motion controls, and achievements.",
description: "<h2>Overview</h2><p style="">Metroid Prime Trilogy is a single-disc compilation for the <a data-ref-id="3045-36" href="/wii/3045-36/" slug="wii">Nintendo Wii</a> consisting of <a data-ref-id="3030-15473" href="/metroid-prime/3030-15473/" slug="metroid-prime">Metroid Prime</a>, <a data-ref-id="3030-1597" href="/metroid-prime-2-echoes/3030-1597/" slug="metroid-prime-2-echoes">Metroid Prime 2: Echoes</a>, and <a data-ref-id="3030-4725" href="/metroid-prime-3-corruption/3030-4725/" slug="metroid-prime-3-corruption">Metroid Prime 3: Corruption</a>. The first two games in the series, originally released for the <a data-ref-id="3045-23" href="/gamecube/3045-23/" slug="gamecube">Nintendo GameCube</a>, have been updated with 480p widescreen support, improved graphic effects, and motion controls similar to those found in Metroid Prime 3.",
expected_release_day: null,
expected_release_month: null,
expected_release_quarter: null,
expected_release_year: null,
id: 26559,
image: {},
name: "Metroid Prime Trilogy",
number_of_user_reviews: 3,
original_game_rating: [],
original_release_date: "2009-08-24 00:00:00",
platforms: [
{
api_detail_url: "http://www.giantbomb.com/api/platform/3045-36/",
id: 36,
name: "Wii",
site_detail_url: "http://www.giantbomb.com/wii/3045-36/",
abbreviation: "WII"
}
],
site_detail_url: "http://www.giantbomb.com/metroid-prime-trilogy/3030-26559/",
resource_type: "game"
}
I'm trying to get the size of "platforms", just because a game can be played, for example, both on PC and MAC:
if (response != null && response.length() > 0) {
Log.d(com.example.ludos2_0.MainActivity.TAG, "Response: "
+ response);
JsonObject jsonObject = (JsonObject) parser.parse(response);
JsonArray items = jsonObject.getAsJsonArray("results");
String id = null;
String title = null;
String thumbnail = null;
String description = null;
String image = null;
String platform = null;
//ArrayList<String> platform = new ArrayList<String>();
for (int index = 0; index < items.size(); index++) {
JsonObject itemObj = (JsonObject) items.get(index);
id = itemObj.get("id").getAsString();
title = itemObj.get("name").getAsString();
thumbnail = ((JsonObject)itemObj.get("image")).
get("tiny_url").getAsString();
image = ((JsonObject)itemObj.get("image")).
get("small_url").getAsString();
description = itemObj.get("deck").getAsString();
JsonArray platforms = jsonObject.getAsJsonArray("platforms");
Log.d(com.example.ludos2_0.MainActivity.TAG,
title);
for (int j = 0; j < platforms.size(); j++) {
JsonObject platformObj = (JsonObject) platforms.get(j);
platform = platformObj.get("name").getAsString();
videogamesList.add(new Videogame(id, title,
thumbnail, image, description, platform));
Log.d(com.example.ludos2_0.MainActivity.TAG,
title + " " + platform);
}
}
But I get a NullPointerException at the line of the 'platforms.size()'.
What am I doing wrong?
Thanks in advance and sorry for my English, I'm italian!
You are not getting values here
JsonArray platforms = jsonObject.getAsJsonArray("platforms");
platforms is null, thats why you are gettin that exception
Update:
I have realized you have a problem here:
JsonArray platforms = jsonObject.getAsJsonArray("platforms");
change to:
JsonArray platforms = itemObj.getAsJsonArray("platforms");
Make sure you are getting an object within platforms handler. Try this :
JsonArray platforms = jsonObject.getAsJsonArray("platforms");
You should get platforms from results not from your main object
JsonArray platforms = jsonObject.getAsJsonArray("platforms"); //WRONG
JsonArray platforms = itemObj.getAsJsonArray("platforms"); //GOOD
Related
I'm developing a web services in java.
In the service I have to check the value of the 'desagg' field if it is equal to 0 I do not have to do anything while if it is greater than 0 I have to make another query and put the result in place of the value of the 'desArticle' field inside the json
I try to use gson method of google library but i don't think is the right method
String sql="SELECT sigdoc as sigla, numdoc as numero, datdoc as data , procor AS seq_articolo, desagg , precorpo.codint as codiceInterno, qtauni AS quantitaArticolo, " +
" przuni AS prezzoVendita, (scont0/100) AS sconto1, (scont1/100) AS sconto2, (scont2/100) AS sconto3, impnet AS importoNetto, datcon as dataConsegna, serdoc as chiaveRiga," +
" coarfo as codiceArticolo, descri as desArticolo" +
" FROM precorpo " +
" INNER JOIN anamagge ON precorpo.codint=anamagge.codint " +
" WHERE tiprig=0 AND sigdoc='"+sigdoc+"' AND numdoc="+numdoc+"" +
" ORDER BY procor;";
try
{
json = db.executeQueryTOJSON2(sql);
JsonObject jobj = new Gson().fromJson(json, JsonObject.class);
int result = jobj.get("desagg").getAsInt();
if (result > 0)
{
String query2=" select group_concat(descri) from memodocu where pointm="+result+" group by pointm;";
ResultSet rs = db.executeQuery(query2);
while(rs.next())
{
String desc = rs.getString("group_concat(descri)");
}
}
}
catch(Exception e)
{
System.out.println("errore "+e);
}
json in output is:
[ { "sigla":"PREV" , "numero":1.1000122E7 , "data":"" , "seq_articolo":1 , "desagg":0 , "codiceInterno":25951 , "quantitaArticolo":2.0 , "prezzoVendita":4.62 , "sconto1":0.0000 , "sconto2":0.0000 , "sconto3":0.0000 , "importoNetto":9.24 , "dataConsegna":"" , "chiaveRiga":7379 , "codiceArticolo":"A025951" , "desArticolo":"025951 ARTICOLO DI PROVA" } , { "sigla":"PREV" , "numero":1.1000122E7 , "data":"" , "seq_articolo":2 , "desagg":100 , "codiceInterno":15879 , "quantitaArticolo":20.0 , "prezzoVendita":2.17 , "sconto1":0.0000 , "sconto2":0.0000 , "sconto3":0.0000 , "importoNetto":43.4 , "dataConsegna":"" , "chiaveRiga":7380 , "codiceArticolo":"A015879" , "desArticolo":"I want to modify this" } ]
I'm a beginner with json
Gson is the right way to go, according the doc you can parse the string and then gey a type-value by a given key
here the doc:
https://static.javadoc.io/com.google.code.gson/gson/2.6.2/com/google/gson/JsonElement.html#getAsInt--
JsonObject jobj = new Gson().fromJson(mySqlResultAsJson, JsonObject.class);
int result = jobj.get("desagg").getAsInt();
if (result >= 0)
{
do another request
}
If you want parse this :
{ "sigla":"PREV" , "numero":1.1000122E7 , "data":"" , "seq_articolo":2 , "desagg":100 , "codiceInterno":15879 , "quantitaArticolo":20.0 , "prezzoVendita":2.17 , "sconto1":0.0000 , "sconto2":0.0000 , "sconto3":0.0000 , "importoNetto":43.4 , "dataConsegna":"" , "chiaveRiga":7380 , "codiceArticolo":"A015879" , "desArticolo":"I want to modify this" }
You might do somthing like ;
MyObject myObj = new Gson().fromJson(myJsonStream, MyObject.class);
int desagg = myObj.getDesagg();
And define an object like this :
class MyObject {
private String sigla;
private float numero;
private String data;
...
}
I solved the problem!
JSONArray jsonarray = new JSONArray(json);
for (int i = 0; i < jsonarray.length(); i++)
{
JSONObject jsonobject = jsonarray.getJSONObject(i);
String tmp = jsonobject.getString("desagg");
if(!tmp.equals("0"))//vuol dire che dessagg diverso da 0
{
String sql2="select group_concat(descri) from memodocu where pointm="+tmp+" group by pointm;";
ResultSet rs = db.executeQuery(sql2);
String tmp2="";
while(rs.next())
{
tmp2=rs.getString("group_concat(descri)");
}
jsonobject.put("desArticolo", tmp2);
}
I used the jsonArray to parse json string and json object to get the value of the field I wanted then if tmp is different from 0 I go to run the query I take the result and update the value of the field desArticle
the final result will end up on the jsonarray variable, to print it you have to do jsonarray.toString ();
i have this fragment of JSON code that i want to parse: basically i want to store the "effective time" and "purpose", that you can see inside the "results" json array using Java(Android Studio), but i'm struggling doing it as it's my first time dealing with JSON.
{
"results": [
{
"effective_time": "20121114",
"inactive_ingredient": [
"Inactive ingredients *acetylated monoglycerides, *anhydrous lactose, *carnauba wax, colloidal silicon dioxide,*corn starch, *croscarmellose sodium, D&C Yellow #10 Aluminum Lake, FD&C Yellow #6 Aluminum Lake, hypromellose, *hypromellose phthalate, *iron oxide Yellow (iron oxide ochre), methacrylic acid copolymer, microcrystalline cellulose, *mineral oil, *polyethylene glycol (PEG)-400, *polysorbate 80, povidone, pregelatinized starch, *propylene glycol, *simethicone, silicon dioxide, sodium bicarbonate, sodium hydroxide, sodium lauryl sulfate, starch, stearic acid, talc, titanium dioxide, triacetin, and triethyl citrate. *May also contain."
],
"purpose": [
"Purpose Pain reliever"
],
"keep_out_of_reach_of_children": [
"Keep out of reach of children In case of overdose, get medical help or contact a Poison Control Center right away."
]
...
...
}
]
}
this is my code so far
String drugDescription="no description";
try{
JSONObject jsonQueryResult = new JSONObject(JSONFILE);
JSONArray jsonResultArray = jsonQueryResult.getJSONArray("result");
JSONObject jsonDrugDescription = jsonResultArray.getJSONObject(0);
drugDescription = jsonDrugDescription.toString();
}
catch(JSONException e){
e.printStackTrace();
}
searchResultTextView.setText(drugDescription);
drugDescription is still showing "no description"
thank you for the help!
If you are new you should go through some tutorial on Json parsing here.
For getting the effective_time and purpose you can do as:
try {
JSONObject jsonObject = new JSONObject(json);
JSONArray firstResult = jsonObject.getJSONArray("results");
if (firstResult != null && firstResult.length() > 0) {
for (int i=0; i<firstResult.length(); i++) {
JSONObject result = firstResult.getJSONObject(i);
// This is your effective_time;
String effective_time = result.getString("effective_time");
JSONArray purpose = result.getJSONArray("purpose");
if (purpose != null && purpose.length() > 0) {
for (int j=0; j<purpose.length(); j++) {
// This is the purpose;
String purposeData = purpose.getString(j);
}
}
}
}
} catch (JSONException e) {
e.printStackTrace();
}
I have a no. of checkboxes (20), what i did is if a user select any checkbox, its name is stored in an array (eg abc array below in code). The name of the string variable that stores the respective json is of the same name as of the checkbox. For eg if Checkbox "a" is clicked, string value "a" is stored in array and there is a string variable named "a" that stores the related json values. What I need is that if i pass the string value stored in array as InputStream is = new ByteArrayInputStream(abc.get(i).getBytes()), it should be used to parse the inputStream for json. But it gives NullPointerException since the string value "a" is not equal to string variable a. How can i solve this problem? I ran out of ideas here. Is there other ways to achieve what i want to do here?
code: String values of the selected checkboxes are stored in an array
String a = "[{\n"
+ "\t\t\t\"title\": \"title1\",\n"
+ "\t\t\t\"describ\": \"describ1\"\n"
+ "}]";
String b = "[{\n"
+ "\"title\": \"title2\",\n"
+ "\"describ\": \"describ2\"\n"
+ "}]";
String c = "[{\n"
+ "\t\t\t\"title\": \"title3\",\n"
+ "\t\t\t\"describ\": \"describ3\"\n"
+ "}]";
//and all jsons required are there
ArrayList<String> abc;
#Override
protected void beforeTestForApp(Form f) {
f.setTitle("abc");
abc = new ArrayList<>();
//I have stored "a" & "b" in the abc array here for simplicity, but it is dynamic,
//ie. if the user select checkbox c, c will be stored in abc array and so on
abc.add("a");
abc.add("b");
Button bb = new Button("go");
bb.addActionListener((e) -> {
showForm("TestForAppResult", null);
});
f.add(bb);
}
Form for json parser and displaying the values:
#Override
protected void beforeTestForAppResult(Form f) {
f.setLayout(new BoxLayout(BoxLayout.Y_AXIS));
InputStream is;
for (int i = 0; i < abc.size(); i++) {
Label heading = new Label(abc.get(i));
f.add(heading);
//this gives error since abc.get(i) gives string value, not string variable
is = new ByteArrayInputStream(abc.get(i).getBytes());
showDetails(is, f);
}
//if i do this instead of for loop jst above, i can get the result but since what value'll be stored in an array is not known,it is not possible
//is = new ByteArrayInputStream(a.getBytes());
//showDetails(is, f);
//is = new ByteArrayInputStream(b.getBytes());
//showDetails(is, f);
}
private void showDetails(InputStream is, Form f) {
JSONParser p = new JSONParser();
Hashtable<String, Object> test;
try {
test = p.parse(new InputStreamReader(is));
Vector aVector = (Vector) test.get("root");
for (int j = 0; j < aVector.size(); j++) {
Hashtable hm = (Hashtable) aVector.get(j);
String title = (String) hm.get("title");
String describ = (String) hm.get("describ");
Label z = new Label(title);
Label zz = new Label(describ);
f.add(z);
f.add(zz);
}
} catch (IOException ex) {
}
}
tbh i didnt get your problem concretely but i still try to give you some shots so you can try out.
If i understand correctly you have 20 objects which contains values underlying?
So then you have a JSONArray, just iterate trough it and grab that JSONObject.
now just use parseJSON instead of parse as it is deprecated...
here is a short snippet of my code
JSONArray jsonTasks = new JSONArray(responseString);
for (int index = 0; index < jsonTasks.length(); index++) {
JSONObject jsonObject = (JSONObject) jsonTasks.get(index);
if (jsonObject != null) {
Map jsonMap = new JSONParser().parseJSON(new InputStreamReader(new ByteArrayInputStream(jsonObject.toString().getBytes(UTF8)), UTF8));
System.out.println(jsonMap.get("date"));
This is a very straightforward question, but this error is very mysterious to me as I have not been able to find a solution or anyone else who has had this problem. I've also used a very similar technique in another activity and it worked just fine. I am making an android application which makes a POST request to a server. The response is a JSONObject that must be parsed into a number and another JSONObject which must also be parsed, and its values assigned to an array of CurrentGame objects. The first call to getJSONObject works fine, but calling getString on that JSONObject returns the following error:
java.lang.NullPointerException: Attempt to write to field 'java.lang.String com.xxxxx.xxxxx.CurrentGame.oppEmail' on a null object reference
Here is my java code:
private void handleResponse(JSONObject response){
int numGroups = 0;
try{
numGroups = response.getInt("Number");
}catch(JSONException e){
e.printStackTrace();
}
Log.i("Number of Groups", String.valueOf(numGroups));
CurrentGame[] currentGames = new CurrentGame[numGroups];
JSONObject current;
int yourTurn = 0;
for(int i = 0; i < numGroups; i++){
try{
current = response.getJSONObject(String.valueOf(i));
Log.i("Current JSONObject: ", String.valueOf(current));
if(current.has("OppEmail")){
currentGames[i].oppEmail = current.getString("OppEmail");
}
if(current.has("OppName")) {
currentGames[i].oppName = current.getString("OppName");
}
if(current.has("Group")) {
currentGames[i].group = current.getString("Group");
}
if(current.has("YourTurn")) {
yourTurn = current.getInt("YourTurn");
}
if(yourTurn == 0){
currentGames[i].yourTurn = true;
}
else{
currentGames[i].yourTurn = false;
}
}
catch (JSONException e){
e.printStackTrace();
}
}
}
Shouldn't the JSONObject.has() check at least be preventing this error?
I know the first getInt() and getJSONObject are working. Heres the Log:
06-21 21:58:56.644 20116-20116/com.xxxxx.xxxxx D/Response:﹕ {"Number":2,"0":{"Group":"Test Group 1","OppEmail":"xxxxx#xxxxx.edu","OppName":"MikeyP","YourTurn":0},"1":{"Group":"Test Group 2","OppEmail":"xxxxx#xxxxx.edu","OppName":"MikeyP","YourTurn":1}}
06-21 21:58:56.644 20116-20116/com.xxxxxx.xxxxxt I/Number of Groups﹕ 2
06-21 21:58:56.644 20116-20116/com.xxxxx.xxxxx I/Current JSONObject﹕ {"Group":"Test Group 1","OppEmail":"xxxxxx#xxxxx.edu","OppName":"MikeyP","YourTurn":0}
Here's the server code:
$games['Number'] = $numgames;
if($numgames > 0){
$i = 0;
while($row = mysqli_fetch_array($getgames)){
$currGame['Group'] = $row['GroupName'];
// Get the opponent's email and username
if($row['Player1'] != $email){
$opponent = $row['Player1'];
$currGame['OppEmail'] = $opponent;
$sql = "SELECT Username FROM users WHERE Email = '".$opponent."'";
$username = mysqli_query($conn, $sql);
$row2 = mysqli_fetch_assoc($username);
$currGame['OppName'] = $row2['Username'];
}
else if($row['Player2'] != $email){
$opponent = $row['Player2'];
$currGame['OppEmail'] = $opponent;
$sql = "SELECT Username FROM users WHERE Email = '".$opponent."'";
$username = mysqli_query($conn, $sql);
$row2 = mysqli_fetch_assoc($username);
$currGame['OppName'] = $row2['Username'];
}
// Determine if it is this player's turn
if($row['CurrentPlayer'] != $email){
$currGame['YourTurn'] = 0;
}
else{
$currGame['YourTurn'] = 1;
}
$games[$i] = $currGame;
$i++;
}
}
//Echo array of groups
header('Content-Type: application/json');
$response = json_encode($games);
echo $response;
Thank you in advance for any ideas as to what I'm doing wrong here. I know similar questions have been asked about getString() returning null, but having read them all I'm still very stumped.
Problem is caused by :
currentGames[i].oppEmail = current.getString("OppEmail");
line.
Because currentGames Array is initialized with size 2 but not added any item of type CurrentGame.
Instead of using currentGames[i].oppEmail create a object of CurrentGame class add all values then add it in currentGames Array like:
CurrentGame objCurrentGame=new CurrentGame();
if(current.has("OppEmail")){
objCurrentGame.oppEmail = current.getString("OppEmail");
}
... same for other fields
...
//Add objCurrentGame to Array
currentGames[i]=objCurrentGame;
Parsing json this way is not robust and error prone, it is recommended to use such libraries as
Gson
Jackson
Retrofit
as these open source libraries offer stable implementation for such purposes and there is no need to reinvent the wheel yourself.
example:
YourPojoClass obj = new Gson().fromJson("{SomeJsonString}", YourPojoClass.class);
In this way, you get the strongly typed pojo instance.You don't even need write the POJO class yourself, and there are many online service that can generate the POJO class out of json strings:
http://www.jsonschema2pojo.org/
http://pojo.sodhanalibrary.com/
I have been using VFP 8.0 for quite sometime and one of the most thing I enjoyed about it is the macro function;
name = "Paul James"
age = 25
result = My name is &name, I am &age years old.
I could also do,
dimension x[5];
x[0] = "box"
x[1] = "area"
text.&x[0]..text = "textbox" ---> textbox.text="textbox"
text.&x[1]..text = "textarea" ---> textarea.text="textarea"
That's with the FoxPro thing, I seem to have grown attached to it and am somewhat inclined wishing such exist with OOs Languages like Java (or it really does, im just missing some extra research?), anyway, I wanted to have something like that here's my problem;
I have a JSON Array, which I get all names of the response and store it in a temporary array by using the "names()" method provided in the android code factory.
Purposely, I want to create an array for each name in the temporary array that was created from the method;
To illustrate;
JSONArray response =
[{"name":"a","middlename":"aa","surname":"aaa"},{"name":"b","middlename":"bb","surname":"bbb"},{"name":"c","middlename":"cc","surname":"ccc"}]
temp[] = [{name,middlename,surname}];
Desired Output:
String[] name = new String[response.firstobject.length];
String[] middlename = new String[response.firstobject.length];
String[] surname = new String[response.firstobject.length];
Here's my actual code; The JSON Parser
#SuppressWarnings("null")
public ArrayList<String> parseJson(JSONArray ja) throws JSONException{
ArrayList<String> listItems = new ArrayList<String>();
String[] temp = null;
//Get all the fields first
for (int i=0; i<=0; ++i){
JSONObject jo = ja.getJSONObject(i);
if(jo.length()>0){
temp = new String[jo.names().length()];
for(int x=0; x<jo.names().length(); ++x){
temp[x] = jo.names().getString(x);
}
}
}
}
So I'm kinda stuck in the desired output, is this possible in the first place? Why I'm doing this, is that because I wanted to create a generic JSON response method; So that I don't have to remember all the names of the response just to use them. Im looking for a java/android solution (most likely the one that works with android).
Thanks in Advance!
I wouldn't necessarily try to replicate what you can do in Visual FoxPro since it's usually a good idea in that language to avoid macro substitution unless you absolutely have to use it, and you can't use a name expression instead.
Here is an example of a name expression:
STORE 'city' TO cVarCity
REPLACE (cVarCity) WITH 'Paris'
This is much faster especially in loops.
On the Java side you're probably looking at using the Reflection API.
I also work with vfp and I have some routines. Perhaps these functions serve you STRTRAN, CHRTRAN:
//--------- ejemplos :
// STRTRAN("Hola * mundo","*", "//") ==> "Hola // mundo"
public String STRTRAN(String cExpression, String cFindString, String cReplacement){
return cExpression.replace(cFindString, cReplacement);
}
//------------------ ejemplos:
// miToolkit.CHRTRAN("ABCDEF", "ACE", "XYZ"); // muestra XBYDZF. ok
// miToolkit.CHRTRAN("ABCDEF", "ACE", "XYZQRST"); // muestra XBYDZF. ok
// miToolkit.CHRTRAN("ABCD", "ABC", "YZ"); // muestra YZCD. No es como fox
public String CHRTRAN(String cString, String cFindChars, String cNewChars){
String cResult = cString;
char[] aFindChars;
char[] aNewChars;
int nLength = cFindChars.length();
aFindChars = cFindChars.toCharArray();
aNewChars = cNewChars.toCharArray();
if(cNewChars.length() < nLength){
nLength = cNewChars.length() ;
}
for(int i=0; i < nLength; i++){
cResult = cResult.replace( aFindChars[i], aNewChars[i] );
}
return cResult;
}
Saludos,
César Gómez,
Lima-Perú