Android: создание условий для пустых полей JSON - PullRequest
0 голосов
/ 25 января 2019

Мое приложение анализирует данные JSON из API Google Civic Information.Иногда данные могут быть недоступны для конкретного JSONobject или массива.В моем случае я пытаюсь проанализировать 8 полей из 2 JSONObjects ("офисы", "должностные лица") и 1 массива JSON ("адрес").Не все официальные лица будут иметь данные фотографии, адресные данные. Полный ответ JSON:

    {
 "normalizedInput": {
  "line1": "2613 Irvington Avenue",
  "city": "San Bernardino",
  "state": "CA",
  "zip": "92407"
 },
 "offices": [
  {
   "name": "President of the United States",
   "levels": [
    "country"
   ],
   "roles": [
    "headOfState",
    "headOfGovernment"
   ]
  },
  {
   "name": "Vice-President of the United States",
   "levels": [
    "country"
   ],
   "roles": [
    "deputyHeadOfGovernment"
   ]
  },
  {
   "name": "United States Senate",
   "levels": [
    "country"
   ],
   "roles": [
    "legislatorUpperBody"
   ]
  },
  {
   "name": "United States House of Representatives CA-31",
   "levels": [
    "country"
   ],
   "roles": [
    "legislatorLowerBody"
   ]
  },
  {
   "name": "Governor",
   "levels": [
    "administrativeArea1"
   ],
   "roles": [
    "headOfGovernment"
   ]
  },
  {
   "name": "Lieutenant Governor",
   "levels": [
    "administrativeArea1"
   ],
   "roles": [
    "deputyHeadOfGovernment"
   ]
  },
  {
   "name": "CA State Senate District 23",
   "levels": [
    "administrativeArea1"
   ],
   "roles": [
    "legislatorUpperBody"
   ]
  },
  {
   "name": "CA State Assembly District 40",
   "levels": [
    "administrativeArea1"
   ],
   "roles": [
    "legislatorLowerBody"
   ]
  },
  {
   "name": "City Treasurer"
  },
  {
   "name": "Mayor"
  },
  {
   "name": "City Attorney"
  },
  {
   "name": "City Clerk"
  },
  {
   "name": "Sheriff-Coroner"
  },
  {
   "name": "Auditor-Controller-Treasurer-Tax Collector"
  },
  {
   "name": "District Attorney"
  },
  {
   "name": "Assessor-Clerk-Recorder"
  },
  {
   "name": "San Bernardino County Superior Court Judge"
  },
  {
   "name": "Board of Supervisors, District 5"
  },
  {
   "name": "Board of Equalization Member District 1"
  },
  {
   "name": "Secretary of State"
  },
  {
   "name": "State Treasurer"
  },
  {
   "name": "Attorney General"
  },
  {
   "name": "State Superintendent of Public Instruction"
  },
  {
   "name": "State Controller"
  },
  {
   "name": "Board of Equalization Member District 2"
  },
  {
   "name": "Board of Equalization Member District 4"
  },
  {
   "name": "Board of Equalization Member District 3"
  },
  {
   "name": "Insurance Commissioner"
  }
 ],
 "officials": [
  {
   "name": "Donald J. Trump",
   "address": [
    {
     "line1": "The White House",
     "line2": "1600 Pennsylvania Avenue NW",
     "city": "Washington",
     "state": "DC",
     "zip": "20500"
    }
   ],
   "party": "Republican",
   "phones": [
    "(202) 456-1111"
   ],
   "photoUrl": "https://www.whitehouse.gov/sites/whitehouse.gov/files/images/45/PE%20Color.jpg",
   "channels": [
    {
     "type": "GooglePlus",
     "id": "+whitehouse"
    },
    {
     "type": "Facebook",
     "id": "whitehouse"
    },
    {
     "type": "Twitter",
     "id": "potus"
    },
    {
     "type": "YouTube",
     "id": "whitehouse"
    }
   ]
  },
  {
   "name": "Mike Pence",
   "address": [
    {
     "line1": "The White House",
     "line2": "1600 Pennsylvania Avenue NW",
     "city": "Washington",
     "state": "DC",
     "zip": "20500"
    }
   ],
   "party": "Republican",
   "phones": [
    "(202) 456-1111"
   ],
   "photoUrl": "https://www.whitehouse.gov/sites/whitehouse.gov/files/images/45/VPE%20Color.jpg",
   "channels": [
    {
     "type": "GooglePlus",
     "id": "+whitehouse"
    },
    {
     "type": "Facebook",
     "id": "whitehouse"
    },
    {
     "type": "Twitter",
     "id": "VP"
    }
   ]
  },
  {
   "name": "Kamala D. Harris",
   "address": [
    {
     "line1": "112 Hart Senate Office Building",
     "city": "Washington",
     "state": "DC",
     "zip": "20510"
    }
   ],
   "party": "Democratic",
   "phones": [
    "(202) 224-3553"
   ],
   "channels": [
    {
     "type": "Twitter",
     "id": "KamalaHarris"
    },
    {
     "type": "YouTube",
     "id": "UC0XBsJpPhOLg0k4x9ZwrWzw"
    }
   ]
  },
  {
   "name": "Dianne Feinstein",
   "address": [
    {
     "line1": "331 Hart Senate Office Building",
     "city": "Washington",
     "state": "DC",
     "zip": "20510"
    }
   ],
   "party": "Democratic",
   "phones": [
    "(202) 224-3841"
   ],
   "photoUrl": "http://bioguide.congress.gov/bioguide/photo/F/F000062.jpg",
   "channels": [
    {
     "type": "Facebook",
     "id": "SenatorFeinstein"
    },
    {
     "type": "Twitter",
     "id": "SenFeinstein"
    },
    {
     "type": "YouTube",
     "id": "SenatorFeinstein"
    }
   ]
  },
  {
   "name": "Pete Aguilar",
   "address": [
    {
     "line1": "109 Cannon House Office Building",
     "city": "Washington",
     "state": "DC",
     "zip": "20515"
    }
   ],
   "party": "Democratic",
   "phones": [
    "(202) 225-3201"
   ],
   "photoUrl": "https://aguilar.house.gov/sites/aguilar.house.gov/files/styles/congress_image_medium/public/wysiwyg_uploaded/Headshot_0.jpg?itok=LSt7qkOV",
   "channels": [
    {
     "type": "Facebook",
     "id": "reppeteaguilar"
    },
    {
     "type": "Twitter",
     "id": "RepPeteAguilar"
    },
    {
     "type": "YouTube",
     "id": "UCIXCmfuRWrbgdTw257_lxJQ"
    },
    {
     "type": "YouTube",
     "id": "UCxwbFLOlKDsXrwizV5jah7g"
    }
   ]
  },
  {
   "name": "Gavin Newsom",
   "address": [
    {
     "line1": "c/o State Capitol",
     "line2": "Suite 1173",
     "city": "Sacramento",
     "state": "CA",
     "zip": "95814"
    }
   ],
   "party": "Democratic",
   "phones": [
    "(916) 445-2841"
   ],
   "channels": [
    {
     "type": "Twitter",
     "id": "GavinNewsom"
    }
   ]
  },
  {
   "name": "Eleni Kounalakis",
   "address": [
    {
     "line1": "State Capitol",
     "line2": "Suite 1114",
     "city": "Sacramento",
     "state": "CA",
     "zip": "95814"
    }
   ],
   "party": "Democratic",
   "phones": [
    "(916) 445-8994"
   ]
  },
  {
   "name": "Mike Morrell",
   "address": [
    {
     "line1": "STATE CAPITOL",
     "line2": "1303 10TH ST RM 3056",
     "city": "Sacramento",
     "state": "CA",
     "zip": "95814"
    }
   ],
   "party": "Republican",
   "phones": [
    "(909) 919-7731"
   ],
   "photoUrl": "http://senate.ca.gov/sites/senate.ca.gov/files/senator_photos/morrell-mike.jpg",
   "emails": [
    "Senator.Morrell@senate.ca.gov"
   ],
   "channels": [
    {
     "type": "Twitter",
     "id": "MikeMorrellGOP"
    },
    {
     "type": "Facebook",
     "id": "MikeMorrellGOP"
    }
   ]
  },
  {
   "name": "James C. Ramos",
   "address": [
    {
     "line1": "PO BOX 942849",
     "city": "Sacramento",
     "state": "CA",
     "zip": "94249"
    }
   ],
   "party": "Democratic Party",
   "phones": [
    "(909) 476-5023"
   ],
   "emails": [
    "assemblymember.ramos@assembly.ca.gov"
   ]
  },
  {
   "name": "David C. Kennedy",
   "address": [
    {
     "line1": "300 N. \"D\" Street",
     "line2": "2nd Floor",
     "city": "San Bernardino",
     "state": "CA",
     "zip": "92418"
    }
   ],
   "party": "Nonpartisan",
   "phones": [
    "(909) 384-5022"
   ]
  },
  {
   "name": "R. Carey Davis",
   "address": [
    {
     "line1": "300 N. \"D\" Street - 6th Floor",
     "city": "San Bernardino",
     "state": "CA",
     "zip": "92418"
    }
   ],
   "party": "Nonpartisan",
   "phones": [
    "(909) 384-5133"
   ],
   "channels": [
    {
     "type": "Facebook",
     "id": "MayorCareyDavis"
    }
   ]
  },
  {
   "name": "Gary D. Saenz",
   "address": [
    {
     "line1": "300 N. \"D\" Street",
     "line2": "6th Floor",
     "city": "San Bernardino",
     "state": "CA",
     "zip": "92418"
    }
   ],
   "party": "Nonpartisan",
   "phones": [
    "(909) 384-5355"
   ],
   "emails": [
    "Attorney@sbcity.org"
   ]
  },
  {
   "name": "Georgeann \"Gigi\" Hanna",
   "address": [
    {
     "line1": "300 N. \"D\" Street",
     "line2": "2nd Floor",
     "city": "San Bernardino",
     "state": "CA",
     "zip": "92418"
    }
   ],
   "party": "Nonpartisan",
   "phones": [
    "(909) 384-5002"
   ]
  },
  {
   "name": "John McMahon",
   "address": [
    {
     "line1": "655 East Third Street",
     "city": "San Bernardino",
     "state": "CA",
     "zip": "92415"
    }
   ],
   "party": "Nonpartisan",
   "phones": [
    "(760) 956-5001"
   ],
   "emails": [
    "paffairs@sbcsd.org"
   ],
   "channels": [
    {
     "type": "Facebook",
     "id": "sbcountysheriff"
    },
    {
     "type": "Twitter",
     "id": "sbcountysheriff"
    }
   ]
  },
  {
   "name": "Oscar Valdez",
   "address": [
    {
     "line1": "222 W. Hospitality Lane",
     "line2": "4th Floor",
     "city": "San Bernardino",
     "state": "CA",
     "zip": "92415"
    }
   ],
   "party": "Nonpartisan",
   "phones": [
    "(909) 382-7014"
   ]
  },
  {
   "name": "Michael Ramos",
   "address": [
    {
     "line1": "303 West 3rd Street",
     "line2": "6th Floor",
     "city": "San Bernardino",
     "state": "CA",
     "zip": "92415"
    }
   ],
   "party": "Nonpartisan",
   "phones": [
    "(909) 382-3669"
   ],
   "channels": [
    {
     "type": "Facebook",
     "id": "SanBernardinoCountyDistrictAttorney"
    },
    {
     "type": "Twitter",
     "id": "sbcountyda"
    }
   ]
  },
  {
   "name": "Bob Dutton",
   "address": [
    {
     "line1": "First Floor",
     "line2": "222 W. Hospitality Lane",
     "city": "San Bernardino",
     "state": "CA",
     "zip": "92415"
    }
   ],
   "party": "Nonpartisan",
   "phones": [
    "(855) 732-2575"
   ]
  },
  {
   "name": "Denise Trager Dvorak",
   "party": "Nonpartisan"
  },
  {
   "name": "Josie Gonzales",
   "address": [
    {
     "line1": "385 N. Arrowhead Ave.",
     "line2": "5th Fl.",
     "city": "San Bernardino",
     "state": "CA",
     "zip": "92415"
    }
   ],
   "party": "Nonpartisan",
   "phones": [
    "(909) 387-4565"
   ],
   "channels": [
    {
     "type": "Facebook",
     "id": "supervisorgonzales"
    },
    {
     "type": "Twitter",
     "id": "SupervisorJosie"
    }
   ]
  },
  {
   "name": "Ted Gaines"
  },
  {
   "name": "Alex Padilla",
   "address": [
    {
     "line1": "1500 11th Street,",
     "city": "Sacramento",
     "state": "CA",
     "zip": "95814"
    }
   ],
   "party": "Democratic",
   "phones": [
    "(916) 653-6814"
   ]
  },
  {
   "name": "Fiona Ma",
   "address": [
    {
     "line1": "P.O. Box 942809",
     "city": "Sacramento",
     "state": "CA",
     "zip": "94209"
    }
   ],
   "party": "Democratic",
   "phones": [
    "(916) 653-2995"
   ]
  },
  {
   "name": "Xavier Becerra",
   "address": [
    {
     "line1": "Office of the Attorney General",
     "line2": "1300 \"I\" Street",
     "city": "Sacramento",
     "state": "CA",
     "zip": "95814"
    }
   ],
   "party": "Democratic",
   "phones": [
    "(916) 445-9555"
   ],
   "channels": [
    {
     "type": "Facebook",
     "id": "XavierBecerra"
    },
    {
     "type": "Twitter",
     "id": "AGBecerra"
    }
   ]
  },
  {
   "name": "Tony K. Thurmond",
   "address": [
    {
     "line1": "1430 N Street,",
     "city": "Sacramento",
     "state": "CA",
     "zip": "95814"
    }
   ],
   "party": "Nonpartisan",
   "phones": [
    "(916) 319-0800"
   ]
  },
  {
   "name": "Betty T. Yee",
   "address": [
    {
     "line1": "300 Capitol Mall,",
     "city": "Sacramento",
     "state": "CA",
     "zip": "95814"
    }
   ],
   "party": "Democratic",
   "phones": [
    "(916) 445-2636"
   ],
   "channels": [
    {
     "type": "Facebook",
     "id": "137732083043662"
    },
    {
     "type": "Twitter",
     "id": "CAController"
    }
   ]
  },
  {
   "name": "Malia Cohen"
  },
  {
   "name": "Mike Schaefer"
  },
  {
   "name": "Antonio Vazquez"
  },
  {
   "name": "Ricardo Lara",
   "address": [
    {
     "line1": "300 Capitol Mall,",
     "city": "Sacramento",
     "state": "CA",
     "zip": "95814"
    }
   ],
   "party": "Democratic"
  }
 ]
}

Поскольку данные обновляются Google, у меня нет возможности узнать, какие поля будут заполнены.Значит ли это, что я должен создавать условия и конструкторы для каждого случая?Я пытался использовать функцию optString, чтобы установить строку по умолчанию для пустых значений, но я не думаю, что я использую их правильно.

Вот мой класс Rep, который определяет объект:

    package com.example.gabe.politicianspulse;

import android.widget.ImageView;

public class Reps {
    private String officeName;
    private String officialName;
    private String party;
    private String photoUrl;
    private String line1;
    private String city;
    private String state;
    private String zip;
    private String phones;


    //continue to develop this with other values such as phone, photo, address etc.

    public Reps(){

    }

    public Reps(String officeName, String officialName, String party, String photoUrl, String line1, String city, String state, String zip, String phones) {
        this.officeName = officeName;
        this.officialName = officialName;
        this.party = party;
        this.photoUrl = photoUrl;
        this.line1 = line1;
        this.city = city;
        this.state = state;
        this.zip = zip;
        this.phones = phones;
    }

    public Reps(String officeName, String officialName, String party, String line1, String city, String state, String zip, String phones) {
        this.officeName = officeName;
        this.officialName = officialName;
        this.party = party;
        this.line1 = line1;
        this.city = city;
        this.state = state;
        this.zip = zip;
        this.phones = phones;
    }

    public Reps(String officeName, String officialName, String party, String photoUrl) {
        this.officeName = officeName;
        this.officialName = officialName;
        this.party = party;
        this.photoUrl = photoUrl;
    }



    public Reps(String officeName, String officialName, String party) {
        this.officeName = officeName;
        this.officialName = officialName;
        this.party = party;
    }

    public Reps(String officeName) {
        this.officeName = officeName;
    }

    public Reps(String name, String party) {
        this.officialName = name;
        this.party = party;
    }

    public Reps(String officeName, String officialName, String party, String line1, String city, String state, String zip) {
        this.officeName = officeName;
        this.officialName = officialName;
        this.party = party;
        this.line1 = line1;
        this.city = city;
        this.state = state;
        this.zip = zip;
    }

    public String getOfficeName() {
        return officeName;
    }

    public void setOfficeName(String officeName) {
        this.officeName = officeName;
    }

    public String getOfficialName() {
        return officialName;
    }

    public void setOfficialName(String officialName) {
        this.officialName = officialName;
    }

    public String getParty() {
        return party;
    }

    public void setParty(String party) {
        this.party = party;
    }

    public String getPhotoUrl() {
        return photoUrl;
    }

    public void setPhotoUrl(String photoUrl) {
        this.photoUrl = photoUrl;
    }

    public String getLine1() {
        return line1;
    }

    public void setLine1(String line1) {
        this.line1 = line1;
    }

    public String getCity() {
        return city;
    }

    public void setCity(String city) {
        this.city = city;
    }

    public String getState() {
        return state;
    }

    public void setState(String state) {
        this.state = state;
    }

    public String getZip() {
        return zip;
    }

    public void setZip(String zip) {
        this.zip = zip;
    }

    public String getPhones() {
        return phones;
    }

    public void setPhones(String phones) {
        this.phones = phones;
    }
}

Вот моя функция разбора.У меня есть 2 разных реализации, которые я пробовал.Сначала я попытался использовать функцию optString для размещения пустых значений, например, так:

 private void getData(){
        final ProgressDialog progressDialog = new ProgressDialog(this);
        progressDialog.setMessage("Loading...");
        progressDialog.show();

        StringRequest stringRequest = new StringRequest(Request.Method.GET, url, new Response.Listener<String>() {
            @Override
            public void onResponse(String response) {
                progressDialog.dismiss();
                try{
                    JSONObject jsonObject = new JSONObject(response);
                    //first loop through offices array. Retrieve officeName value
                    JSONArray officesArray = jsonObject.getJSONArray("offices");        //One array for offices
                    JSONArray officialsArray = jsonObject.getJSONArray("officials");    //one array for officials
                    for (int i = 0; i < officesArray.length(); i++) {
                        JSONObject jsonOffices = officesArray.getJSONObject(i);
                        JSONObject jsonOfficials = officialsArray.getJSONObject(i);
                        JSONArray jsonAddress = jsonOfficials.getJSONArray("address");      //Declare address array here?
                        Reps reps1 = new Reps(jsonOffices.optString("name", "No Data"),
                                jsonOfficials.optString("name", "No Data"),
                                jsonOfficials.optString("party", "No data"),
                                jsonOfficials.optString("photoUrl", "No data"),
                                jsonAddress.getJSONObject(0).optString("line1", "No data"),
                                jsonAddress.getJSONObject(0).optString("city", "No data"),
                                jsonAddress.getJSONObject(0).optString("state", "No data"),
                                jsonAddress.getJSONObject(0).optString("zip", "No data")
                        );
                        repList.add(reps1);

                        /*if(jsonOfficials.has("photoUrl")){
                            Reps reps = new Reps(jsonOffices.getString("name"),
                                    jsonOfficials.getString("name"),
                                    jsonOfficials.getString("party"),
                                    jsonOfficials.getString("photoUrl"));
                            repList.add(reps);
                        }else{
                            Reps ree = new Reps(jsonOffices.getString("name"),
                                    jsonOfficials.getString("name"),
                                    jsonOfficials.getString("party"));
                            repList.add(ree);
                        }
                                //object with photoURL data, but no address data
                   */ }
                    adapter = new RepRvAdapter(repList, getApplicationContext());
                    myrv.setAdapter(adapter);
                }catch (JSONException e){
                    e.printStackTrace();
                }
            }
        }, new Response.ErrorListener() {
            @Override
            public void onErrorResponse(VolleyError error) {
                Log.e("Volley", error.toString());
                progressDialog.dismiss();
            }
        });
        RequestQueue requestQueue = Volley.newRequestQueue(this);
        requestQueue.add(stringRequest);
    }
}

Затем я попытался использовать различные условные выражения для создания объектов для каждого случая, например, так: (Я добавил условие только для объектов без данных photoUrl длясейчас. Я хотел бы знать, если это лучший подход, прежде чем я напишу остальные условия.)

//fetch json data from Civic API
    private void getData(){
        final ProgressDialog progressDialog = new ProgressDialog(this);
        progressDialog.setMessage("Loading...");
        progressDialog.show();

        StringRequest stringRequest = new StringRequest(Request.Method.GET, url, new Response.Listener<String>() {
            @Override
            public void onResponse(String response) {
                progressDialog.dismiss();
                try{
                    JSONObject jsonObject = new JSONObject(response);
                    //first loop through offices array. Retrieve officeName value
                    JSONArray officesArray = jsonObject.getJSONArray("offices");        //One array for offices
                    JSONArray officialsArray = jsonObject.getJSONArray("officials");    //one array for officials
                    for (int i = 0; i < officesArray.length(); i++) {
                        JSONObject jsonOffices = officesArray.getJSONObject(i);
                        JSONObject jsonOfficials = officialsArray.getJSONObject(i);
                        //JSONArray jsonAddress = jsonOfficials.getJSONArray("address");      //Declare address array here?
                        if(jsonOfficials.has("photoUrl")){
                            Reps reps = new Reps(jsonOffices.getString("name"),
                                    jsonOfficials.getString("name"),
                                    jsonOfficials.getString("party"),
                                    jsonOfficials.getString("photoUrl"));
                            repList.add(reps);
                        }else{
                            Reps ree = new Reps(jsonOffices.getString("name"),
                                    jsonOfficials.getString("name"),
                                    jsonOfficials.getString("party"));
                            repList.add(ree);
                        }
                                //object with photoURL data, but no address data
                    }
                    adapter = new RepRvAdapter(repList, getApplicationContext());
                    myrv.setAdapter(adapter);
                }catch (JSONException e){
                    e.printStackTrace();
                }
            }
        }, new Response.ErrorListener() {
            @Override
            public void onErrorResponse(VolleyError error) {
                Log.e("Volley", error.toString());
                progressDialog.dismiss();
            }
        });
        RequestQueue requestQueue = Volley.newRequestQueue(this);
        requestQueue.add(stringRequest);
    }
}

Я бы предпочел использовать метод, аналогичный функции optstring, вместо создания условия длякаждый случай, поскольку это было бы утомительно и занимало много времени.Я думаю, мой вопрос к вам, как бы вы подошли к этой проблеме наиболее эффективным способом?

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...