Проблема при разборе нескольких объектов json, каждый из которых имеет несколько массивов из проверенного формата JSON-JavaString - PullRequest
0 голосов
/ 14 марта 2019

Хотите обработать следующую строку JSON (проверено с помощью jsonlint.com)

[{
    "label": "Hospital",
    "domain": "Health_Care",
    "synonymlabels": [{
        "label": "SHCO"
    }, {
        "label": "HCO"
    }],

    "childrenlabels": [{
        "label": "Childern_Hospital"
    }, {
        "label": "Mental_Hospital"
    }, {
        "label": "Heart_Hospital"
    }, {
        "label": "Orthopadic_Hospital"
    }, {
        "label": "General_Hospital"
    }, {
        "label": "Gynac_Hospital"
    }, {
        "label": "Cancer_Hospital"
    }, {
        "label": "Burn_Hospital"
    }, {
        "label": "Trauma_Care_Hospital"
    }]
},

{
    "label": "Doctor",
    "domain": "Health_Care",
    "synonymlabels": [{
        "label": "Clinician"
    }, {
        "label": "Physician"
    }, {
        "label": "Medical_Practitioner"
    }],

    "childrenlabels": [{
        "label": "Cardiaologist"
    }, {
        "label": "Allergist"
    }, {
        "label": "Nurologist"
    }, {
        "label": "Gynacologist"
    }, {
        "label": "General_Physician"
    }, {
        "label": "Anesthetist"
    }, {
        "label": "Physiotherapist"
    }, {
        "label": "Urologist"
    }, {
        "label": "Oncologist"
    }, {
        "label": "Homeopath"
    }, {
        "label": "Dentist"
    }]
}
]

Пример кода

Я могу запустить следующий пример кода и получить желаемый результат. Если я изменяю строку JSON, т.е. объект "{}", на JSON ARRAY "[{}, {}, {}]" для анализа и необходимых изменений в коде (не знаю, что делать с массивом), тогда я получаю нет результатов в консоли. Чувство паралича в поиске моей ошибки. Пожалуйста помоги. Почти сутки боролся за настройку кода.

import java.io.IOException; 
import java.io.StringReader;  

import com.google.gson.stream.JsonReader; 
import com.google.gson.stream.JsonToken;  

public class gsontester { 
   public static void main(String args[]) { 

      String jsonString = 
         "{ \"name\":\"Mahesh Kumar\", \"age\":21,\"verified\":false,\"marks\": [100,90,85,100,14,95]}";  
      JsonReader reader = new JsonReader(new StringReader(jsonString));    
      try { 
         handleJsonObject(reader); 
      } 
      catch (IOException e) { 
         e.printStackTrace(); 
      } 
   } 

   private static void handleJsonObject(JsonReader reader) throws IOException { 
      reader.beginObject(); 
      String fieldname = null; 

      while (reader.hasNext()) { 
         JsonToken token = reader.peek(); 

         if (token.equals(JsonToken.BEGIN_ARRAY)) { 
            System.out.print("Marks [ "); 
            handleJsonArray(reader); 
            System.out.print("]"); 
         } else if (token.equals(JsonToken.END_OBJECT)) { 
            reader.endObject(); 
            return; 
         } else {            
            if (token.equals(JsonToken.NAME)) {     
               //get the current token 
               fieldname = reader.nextName(); 
            } 

            if ("name".equals(fieldname)) {       
               //move to next token 
               token = reader.peek(); 
               System.out.println("Name: "+reader.nextString() );           
            } 

            if("age".equals(fieldname)) { 
           //move to next token 
           token = reader.peek(); 
           System.out.println("Age:" + reader.nextInt());       
        } 

        if("verified".equals(fieldname)) { 
           //move to next token 
           token = reader.peek(); 
           System.out.println("Verified:" + reader.nextBoolean());           
        }             
     } 
  } 


}

выход

Name: Mahesh Kumar
Age:21
Verified:false

Marks [ 100 90 85 100 14 95 ]

1 Ответ

1 голос
/ 14 марта 2019

Ваш JSON имеет один хитрый элемент - массивы меток содержат one-element JSON object.Мы можем развернуть его, используя специальный десериализатор.Для этого давайте создадим простую POJO структуру, которая соответствует JSON полезной нагрузке.JSON начинается с [, поэтому это означает, что мы должны проанализировать его как массив.Все элементы имеют одинаковую структуру.Мы можем определить его следующим образом:

class Phrase {

    private String label;
    private String domain;

    @JsonAdapter(StringWrapperJsonDeserializer.class)
    @SerializedName("synonymlabels")
    private List<String> synonymLabels;

    @JsonAdapter(StringWrapperJsonDeserializer.class)
    @SerializedName("childrenlabels")
    private List<String> childrenLabels;

    public String getLabel() {
        return label;
    }

    public void setLabel(String label) {
        this.label = label;
    }

    public String getDomain() {
        return domain;
    }

    public void setDomain(String domain) {
        this.domain = domain;
    }

    public List<String> getSynonymLabels() {
        return synonymLabels;
    }

    public void setSynonymLabels(List<String> synonymLabels) {
        this.synonymLabels = synonymLabels;
    }

    public List<String> getChildrenLabels() {
        return childrenLabels;
    }

    public void setChildrenLabels(List<String> childrenLabels) {
        this.childrenLabels = childrenLabels;
    }

    @Override
    public String toString() {
        return "Phrase{" +
                "label='" + label + '\'' +
                ", domain='" + domain + '\'' +
                ", synonymLabels=" + synonymLabels +
                ", childrenLabels=" + childrenLabels +
                '}';
    }
}

Когда мы хотим использовать другое имя для свойства в Java по сравнению с тем, что мы имеем в JSON, мы используем SerializedName аннотацию.Чтобы сообщить библиотеке Gson, что мы хотим обрабатывать данный элемент определенным образом, мы используем аннотацию JsonAdapter.В случае, если мы не знаем, как написать собственный десериализатор, всегда безопасно использовать тип Map<String, Object> для неизвестного или случайного объекта JSON.Если у нас есть список объектов, мы можем использовать List<Map<String, Object>>.Давайте напишем простой десериализатор для массивов меток:

class StringWrapperJsonDeserializer implements JsonDeserializer<List<String>> {

    @Override
    public List<String> deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context) throws JsonParseException {
        if (json.isJsonArray()) {
            final JsonArray array = (JsonArray) json;
            final int size = array.size();
            if (size == 0) {
                return Collections.emptyList();
            }

            List<String> labels = new ArrayList<>(size);
            for (int i = 0; i < size; i++) {
                JsonObject jsonElement = (JsonObject) array.get(i);
                Set<String> keys = jsonElement.keySet();
                for (String key : keys) {
                    labels.add(jsonElement.getAsJsonPrimitive(key).getAsString());
                }
            }

            return labels;
        }

        return Collections.emptyList();
    }
}

Алгоритм довольно прост: если данный элемент является массивом, выполните итерацию по нему и возьмите каждый объект один за другим.Для каждого объекта получите все ключи и добавьте соответствующие значения в список labels, который является нашим результатом процесса десериализации.Пример использования, может выглядеть следующим образом:

import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import com.google.gson.JsonArray;
import com.google.gson.JsonDeserializationContext;
import com.google.gson.JsonDeserializer;
import com.google.gson.JsonElement;
import com.google.gson.JsonObject;
import com.google.gson.JsonParseException;
import com.google.gson.annotations.JsonAdapter;
import com.google.gson.annotations.SerializedName;

import java.io.File;
import java.io.FileReader;
import java.lang.reflect.Type;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Set;
import java.util.stream.Stream;

public class GsonApp {

    public static void main(String[] args) throws Exception {
        File jsonFile = new File("./resource/test.json").getAbsoluteFile();

        Gson gson = new GsonBuilder()
                .setPrettyPrinting()
                .create();

        Phrase[] phrases = gson.fromJson(new FileReader(jsonFile), Phrase[].class);
        Stream.of(phrases).forEach(System.out::println);
    }
}

Надпечатки кода выше:

Phrase{label='Hospital', domain='Health_Care', synonymLabels=[SHCO, HCO], childrenLabels=[Childern_Hospital, Mental_Hospital, Heart_Hospital, Orthopadic_Hospital, General_Hospital, Gynac_Hospital, Cancer_Hospital, Burn_Hospital, Trauma_Care_Hospital]}
Phrase{label='Doctor', domain='Health_Care', synonymLabels=[Clinician, Physician, Medical_Practitioner], childrenLabels=[Cardiaologist, Allergist, Nurologist, Gynacologist, General_Physician, Anesthetist, Physiotherapist, Urologist, Oncologist, Homeopath, Dentist]}

Читайте также:

...