2017-05-24 4 views
0

ich Retrofit2 zu erhalten, um Nachrichten von einem Blog bin mit jeder Nachricht hat n Übungen Spanisch zu lernen, die die Struktur des Codes unten haben:Wie wird diese Struktur in einem Modell dargestellt?

Übungen Antwort Teil

"exercises": { 
     "number_of_exercises": 2, 
     "exercise1": { 
     "title": "Ejercicio de comprensión B.1 (Comprehension B.1)", 
     "question1": "La noticia habla...", 
     "answer1_1": "de un test para evaluar la inteligencia humana.", 
     "answer1_2": "de un descubrimiento científico relacionado con el ser humano.", 
     "answer1_3": "del descubrimiento de una nueva especie animal.", 
     "correctAnswer1": "de un descubrimiento científico relacionado con el ser humano.", 
     "question2": "Los genes identificados...", 
     "answer2_1": "pueden explicar algunos comportamientos sociales del ser humano.", 
     "answer2_2": "explican el funcionamiento completo del cerebro.", 
     "answer2_3": "están relacionados con la inteligencia.", 
     "correctAnswer2": "están relacionados con la inteligencia.", 
     "question3": "Este descubrimiento...", 
     "answer3_1": "no aportará nada a las investigaciones sobre el cerebro.", 
     "answer3_2": "podría ofrecer nuevos datos sobre el funcionamiento del cerebro.", 
     "answer3_3": "no es muy importante para la biología.", 
     "correctAnswer3": "podría ofrecer nuevos datos sobre el funcionamiento del cerebro.", 
     "question4": "Según el texto, los científicos ya saben todo sobre los procesos cognitivos.", 
     "answer4_1": "No se sabe.", 
     "answer4_2": "Verdadero.", 
     "answer4_3": "Falso.", 
     "correctAnswer4": "Falso." 
     }, 
     "exercise2": { 
     "title": "Ejercicio de vocabulario B.2 (Vocabulary B.2)", 
     "question1": "Relacionas 'cognitivo' con...", 
     "answer1_1": "la empatía.", 
     "answer1_2": "el conocimiento.", 
     "answer1_3": "una congestión.", 
     "correctAnswer1": "el conocimiento.", 
     "question2": "'Cohorte' es igual que...", 
     "answer2_1": "'conjunto'.", 
     "answer2_2": "'comprensión'.", 
     "answer2_3": "'finalización'.", 
     "correctAnswer2": "'conjunto'.", 
     "question3": "Lo contrario de 'específico' es...", 
     "answer3_1": "'genérico'.", 
     "answer3_2": "'aleatorio'.", 
     "answer3_3": "'concreto'.", 
     "correctAnswer3": "'genérico'.", 
     "question4": "El 'genoma' está relacionado con el ADN.", 
     "answer4_1": "No se sabe.", 
     "answer4_2": "Falso.", 
     "answer4_3": "Verdadero.", 
     "correctAnswer4": "Verdadero." 
     } 
    } 

Da die Anzahl der Übungen variiert (manchmal 1 oder mehr), weiß ich nicht, wie ich sie in einer Klasse nach ihrer Struktur darstellen soll.

Könnten Sie mir bitte helfen?

Ich habe bereits versucht, eine Klasse zu erstellen, aber mit den Unterklassen Übung 1, Exercise2, etc ... Ich bin auf der Suche nach dem besten Weg dieser Anforderung

+1

Sie json ein Array zurück Übungen anstelle von Attributen von einer variablen Anzahl. –

+0

Ja, es wäre großartig @ JonathanAste, aber leider plant der Kunde nicht, Änderungen an der API vorzunehmen :-( –

+0

Idealerweise sollten "Übungen" und "Fragen" beide Arrays sein. Die Frageobjekte würden eine Reihe möglicher Antworten enthalten –

Antwort

0

Versuchen Sie, diese zu vervollständigen: Wenn

try { 
    ArrayList<Exercise> exercises = new ArrayList<>(); 
    JSONObject json = new JSONObject(yourJson); 
    int exerciseQuantity = json.getInt("number_of_exercises"); 
    for (int i = 1; i <= exerciseQuantity; i++) { 
     Exercise e = json.get("exercise".concat(String.valueOf(i))); 
     if (e != null) { 
      exercises.add(e); 
     } 
    } 
} catch (JSONException e) { 
    e.printStackTrace(); 
} 
0

Sie verwenden Retrofit, wahrscheinlich verwenden Sie auch Gson. Zumindest lässt sich mit Gson auch für schlecht gestaltete JSON-Dokumente wunderbares Zeug implementieren.

Zunächst einmal können Sie Ihr eigenes Objektmodell entwerfen, um es bequem zu verwenden.

final class ExerciseWrapper { 

    final List<Exercise> exercises; 

    ExerciseWrapper(final List<Exercise> exercises) { 
     this.exercises = exercises; 
    } 

} 
final class Exercise { 

    final String title; 
    final List<Question> questions; 

    Exercise(final String title, final List<Question> questions) { 
     this.title = title; 
     this.questions = questions; 
    } 

} 
final class Question { 

    final String question; 
    final List<String> answers; 
    final int correctAnswer; 

    Question(final String question, final List<String> answers, final int correctAnswer) { 
     this.question = question; 
     this.answers = answers; 
     this.correctAnswer = correctAnswer; 
    } 

} 

Nun definieren einige Schnittstellen verschiedene Strategien für die Deserializer zu implementieren. Diese sind trivial, und Sie können so etwas verwenden, wenn Sie irgendwelche haben (wenn Sie beispielsweise Google Guava verwenden, verwenden Sie einfach Function und Supplier).

interface IFunction<T, R> { 

    R apply(T t); 

} 
interface ISupplier<T> { 

    T get(); 

} 

Als nächstes müssen Sie auf „Verflachung“ die Eigenschaften, die Arrays, wenn die angegebene JSON wäre gut gestaltet sein sollte. Die folgenden extract Methoden versuchen, über jede Objekteigenschaft zu iterieren und zu prüfen, ob sie einen Index extrahieren kann. Wenn ein Index extrahiert wird, versuchen sie sicherzustellen, dass die Listengröße für alle Elemente ausreicht. Sobald die Listengröße in Ordnung ist, versuchen sie, über eine Strategie von einem anderen Ort einen Wert zu erhalten.

final class Extractors { 

    private Extractors() { 
    } 

    static <R> List<R> extract(
      final JsonObject jsonObject, 
      final IFunction<? super String, Integer> scanner, 
      final IFunction<? super JsonElement, ? extends R> mapper 
    ) { 
     final List<R> list = new ArrayList<>(); 
     for (final Map.Entry<String, JsonElement> entry : jsonObject.entrySet()) { 
      final Integer i = scanner.apply(entry.getKey()); 
      if (i != null) { 
       ensureSize(list, i,() -> null); 
       list.set(i - 1, mapper.apply(entry.getValue())); 
      } 
     } 
     return list; 
    } 

    static <R> List<List<R>> extract(
      final JsonObject jsonObject, 
      final IFunction<? super String, Integer> superScanner, 
      final IFunction<? super String, Integer> subScanner, 
      final IFunction<? super JsonElement, ? extends R> mapper 
    ) { 
     final List<List<R>> superList = new ArrayList<>(); 
     for (final Map.Entry<String, JsonElement> entry : jsonObject.entrySet()) { 
      final Integer superI = superScanner.apply(entry.getKey()); 
      if (superI != null) { 
       final Integer subI = subScanner.apply(entry.getKey()); 
       if (subI != null) { 
        ensureSize(superList, superI, ArrayList::new); 
        final List<R> subList = superList.get(superI - 1); 
        ensureSize(subList, subI,() -> null); 
        subList.set(subI - 1, mapper.apply(entry.getValue())); 
       } 
      } 
     } 
     return superList; 
    } 

    private static <T> void ensureSize(final Collection<? super T> collection, final int size, final ISupplier<? extends T> defaultValueSupplier) { 
     while (collection.size() < size) { 
      collection.add(defaultValueSupplier.get()); 
     } 
    } 

} 

Die nächste Klasse repräsentiert ein paar String-to-Integer-Mapping-Strategie Factory-Methoden, um oben in den extract Methoden verwendet werden:

final class Scanners { 

    private Scanners() { 
    } 

    static IFunction<String, Integer> scanByPattern(final String pattern) { 
     return scanByPattern(Pattern.compile(pattern)); 
    } 

    static IFunction<String, Integer> scanByPattern(final Pattern pattern) { 
     return name -> { 
      final Matcher matcher = pattern.matcher(name); 
      if (!matcher.matches()) { 
       return null; 
      } 
      return parseInt(matcher.group(1)); 
     }; 
    } 

} 

Das waren einfache Teile. Das Schreiben eines benutzerdefinierten Deserializers ist möglicherweise komplizierter.

final class ExerciseJsonDeserializer 
     implements JsonDeserializer<Exercise> { 

    private static final JsonDeserializer<Exercise> exerciseJsonDeserializer = new ExerciseJsonDeserializer(); 

    private static final IFunction<String, Integer> questionScanner = scanByPattern("question(\\d+)"); 
    private static final IFunction<String, Integer> correctAnswerScanner = scanByPattern("correctAnswer(\\d+)"); 
    private static final IFunction<String, Integer> answerScanner1 = scanByPattern("answer(\\d+)_\\d+"); 
    private static final IFunction<String, Integer> answerScanner2 = scanByPattern("answer\\d+_(\\d+)"); 

    private ExerciseJsonDeserializer() { 
    } 

    static JsonDeserializer<Exercise> getExerciseJsonDeserializer() { 
     return exerciseJsonDeserializer; 
    } 

    @Override 
    public Exercise deserialize(final JsonElement jsonElement, final Type type, final JsonDeserializationContext context) 
      throws JsonParseException { 
     final JsonObject jsonObject = jsonElement.getAsJsonObject(); 
     return new Exercise(
       jsonObject.getAsJsonPrimitive("title").getAsString(), 
       mergeQuestionParts(
         extract(jsonObject, questionScanner, JsonElement::getAsString), 
         extract(jsonObject, answerScanner1, answerScanner2, JsonElement::getAsString), 
         extract(jsonObject, correctAnswerScanner, JsonElement::getAsString) 
       ) 
     ); 
    } 

    private static List<Question> mergeQuestionParts(final Iterable<String> questionTitles, final Iterable<List<String>> answers, 
      final Iterable<String> correctAnswers) { 
     final Iterator<String> questionIterator = questionTitles.iterator(); 
     final Iterator<List<String>> answerIterator = answers.iterator(); 
     final Iterator<String> correctAnswerIterator = correctAnswers.iterator(); 
     final List<Question> questions = new ArrayList<>(); 
     while (questionIterator.hasNext() && answerIterator.hasNext() && correctAnswerIterator.hasNext()) { 
      final String question = questionIterator.next(); 
      final List<String> rawAnswers = answerIterator.next(); 
      final String correctAnswer = correctAnswerIterator.next(); 
      questions.add(new Question(question, rawAnswers, rawAnswers.indexOf(correctAnswer))); 
     } 
     return questions; 
    } 
} 
final class ExerciseWrapperJsonDeserializer 
     implements JsonDeserializer<ExerciseWrapper> { 

    private static final JsonDeserializer<ExerciseWrapper> exerciseWrapperJsonDeserializer = new ExerciseWrapperJsonDeserializer(); 

    private static final IFunction<String, Integer> exerciseScanner = scanByPattern("exercise(\\d+)"); 

    private ExerciseWrapperJsonDeserializer() { 
    } 

    static JsonDeserializer<ExerciseWrapper> getExerciseWrapperJsonDeserializer() { 
     return exerciseWrapperJsonDeserializer; 
    } 

    @Override 
    public ExerciseWrapper deserialize(final JsonElement jsonElement, final Type type, final JsonDeserializationContext context) 
      throws JsonParseException { 
     final JsonObject jsonObject = jsonElement.getAsJsonObject(); 
     return new ExerciseWrapper(
       extract(jsonObject.getAsJsonObject("exercises"), exerciseScanner, je -> context.deserialize(je, Exercise.class)) 
     ); 
    } 

} 

Wie es in Java 8 verwendet wird:

private static final Gson gson = new GsonBuilder() 
     .registerTypeAdapter(ExerciseWrapper.class, getExerciseWrapperJsonDeserializer()) 
     .registerTypeAdapter(Exercise.class, getExerciseJsonDeserializer()) 
     .setPrettyPrinting() 
     .create(); 

public static void main(final String... args) 
     throws IOException { 
    try (final JsonReader jsonReader = getPackageResourceJsonReader(Q44165271.class, "exercise.json")) { 
     final ExerciseWrapper exerciseWrapper = gson.fromJson(jsonReader, ExerciseWrapper.class); 
     exerciseWrapper.exercises.forEach(exercise -> { 
      System.out.println(exercise.title); 
      exercise.questions.forEach(question -> { 
       System.out.println("\t" + question.question); 
       question.answers.forEach(answer -> System.out.println("\t\t" + answer)); 
       System.out.println("\t" + (question.correctAnswer + 1)); 
      }); 
     }); 
     System.out.println("-----"); 
     System.out.println(gson.toJson(exerciseWrapper)); 
    } 
} 

Ausgang:

muss
Ejercicio de comprensión B.1 (Comprehension B.1) 
    La noticia habla... 
     de un test para evaluar la inteligencia humana. 
     de un descubrimiento científico relacionado con el ser humano. 
     del descubrimiento de una nueva especie animal. 
    2 
    Los genes identificados... 
     pueden explicar algunos comportamientos sociales del ser humano. 
     explican el funcionamiento completo del cerebro. 
     están relacionados con la inteligencia. 
    3 
    Este descubrimiento... 
     no aportará nada a las investigaciones sobre el cerebro. 
     podría ofrecer nuevos datos sobre el funcionamiento del cerebro. 
     no es muy importante para la biología. 
    2 
    Según el texto, los científicos ya saben todo sobre los procesos cognitivos. 
     No se sabe. 
     Verdadero. 
     Falso. 
    3 
Ejercicio de vocabulario B.2 (Vocabulary B.2) 
    Relacionas 'cognitivo' con... 
     la empatía. 
     el conocimiento. 
     una congestión. 
    2 
    'Cohorte' es igual que... 
     'conjunto'. 
     'comprensión'. 
     'finalización'. 
    1 
    Lo contrario de 'específico' es... 
     'genérico'. 
     'aleatorio'. 
     'concreto'. 
    1 
    El 'genoma' está relacionado con el ADN. 
     No se sabe. 
     Falso. 
     Verdadero. 
    3 
----- 
{ 
    "exercises": [ 
    { 
     "title": "Ejercicio de comprensión B.1 (Comprehension B.1)", 
     "questions": [ 
     { 
      "question": "La noticia habla...", 
      "answers": [ 
      "de un test para evaluar la inteligencia humana.", 
      "de un descubrimiento científico relacionado con el ser humano.", 
      "del descubrimiento de una nueva especie animal." 
      ], 
      "correctAnswer": 1 
     }, 
     { 
      "question": "Los genes identificados...", 
      "answers": [ 
      "pueden explicar algunos comportamientos sociales del ser humano.", 
      "explican el funcionamiento completo del cerebro.", 
      "están relacionados con la inteligencia." 
      ], 
      "correctAnswer": 2 
     }, 
     { 
      "question": "Este descubrimiento...", 
      "answers": [ 
      "no aportará nada a las investigaciones sobre el cerebro.", 
      "podría ofrecer nuevos datos sobre el funcionamiento del cerebro.", 
      "no es muy importante para la biología." 
      ], 
      "correctAnswer": 1 
     }, 
     { 
      "question": "Según el texto, los científicos ya saben todo sobre los procesos cognitivos.", 
      "answers": [ 
      "No se sabe.", 
      "Verdadero.", 
      "Falso." 
      ], 
      "correctAnswer": 2 
     } 
     ] 
    }, 
    { 
     "title": "Ejercicio de vocabulario B.2 (Vocabulary B.2)", 
     "questions": [ 
     { 
      "question": "Relacionas \u0027cognitivo\u0027 con...", 
      "answers": [ 
      "la empatía.", 
      "el conocimiento.", 
      "una congestión." 
      ], 
      "correctAnswer": 1 
     }, 
     { 
      "question": "\u0027Cohorte\u0027 es igual que...", 
      "answers": [ 
      "\u0027conjunto\u0027.", 
      "\u0027comprensión\u0027.", 
      "\u0027finalización\u0027." 
      ], 
      "correctAnswer": 0 
     }, 
     { 
      "question": "Lo contrario de \u0027específico\u0027 es...", 
      "answers": [ 
      "\u0027genérico\u0027.", 
      "\u0027aleatorio\u0027.", 
      "\u0027concreto\u0027." 
      ], 
      "correctAnswer": 0 
     }, 
     { 
      "question": "El \u0027genoma\u0027 está relacionado con el ADN.", 
      "answers": [ 
      "No se sabe.", 
      "Falso.", 
      "Verdadero." 
      ], 
      "correctAnswer": 2 
     } 
     ] 
    } 
    ] 
} 
Verwandte Themen