Conversion entre objets Java et JSON à l'aide de Moshi

Aperçu

Pour implémenter le processus de conversion d'un objet Java en JSON et de son enregistrement dans un fichier, ou de conversion du JSON enregistré en objet Java, utilisez le SDK Android standard org.json, sans parler de Jackson. J'étais un peu dur, et quand j'ai cherché une bonne bibliothèque, j'ai trouvé Moshi de Square, Inc.. J'ai découvert qu'il existe une bibliothèque appelée /), alors je l'ai essayée facilement.


Moshi Moshi est une bibliothèque JSON développée par Square Inc. Il semble qu'il ait été présenté comme l'une des séries Ok à Droidcon Montréal 2015.

A Few 'Ok' Libraries (Droidcon MTL 2015)

Je n'aborderai pas cette fois, mais dans la série Ok, il existe d'autres clients HTTP OkHttp et une bibliothèque d'E / S Okio. / square / ooki /) etc. ont été libérés.

version

Depuis le 12 août 2017, date de la rédaction de cet article, la dernière version est 1.5.0 (2017/05) / 15).

taille du fichier

La taille du fichier est aussi petite que 64 Ko. Cela peut être un avantage dans le développement d'applications Android. Étant donné que Jackson est proche de 1 Mo et Gson de 144 Ko, le dernier 2.8.1 est assez petit.

Selon la documentation de l'API 1.4.0, les classes incluses dans le corps sont:

  1. FromJson
  2. Json
  3. JsonAdapter
  4. JsonAdapter.Factory
  5. JsonDataException
  6. JsonEncodingException
  7. JsonQualifier
  8. JsonReader
  9. JsonReader.Options
  10. JsonReader.Token
  11. JsonWriter
  12. Moshi
  13. Moshi.Builder
  14. ToJson
  15. Types

Dépendance

Si vous jetez un coup d'œil au code source de GitHub Repository, le test trouvera android.util.Pair. J'utilise uniquement reference / android / util / Pair.html), et il semble que l'implémentation de la bibliothèque n'inclut aucune dépendance du SDK Android. Par conséquent, comme les autres séries Ok, il peut être utilisé pour des applications autres que Android.

Notez que Okio est inclus dans la dépendance. Il s'agit également d'une bibliothèque d'E / S qui ne dépend pas du SDK Android.

Licence

Dans la version 1.5.0, c'était Apache 2.0 comme les autres séries Ok.


introduction

Ajout de dépendance

Vous pouvez l'utiliser simplement en ajoutant une ligne.

app/build.gradle


dependencies {
  compile 'com.squareup.moshi:moshi:1.5.0'

Paramètres Proguard pour les applications Android

Selon README of GitHub repository, les paramètres suivants sont requis lors de l'utilisation de Proguard. Ce paramètre n'est pas requis pour une utilisation dans les applications Java.

-dontwarn okio.**
-dontwarn javax.annotation.Nullable
-dontwarn javax.annotation.ParametersAreNonnullByDefault
-keepclasseswithmembers class * {
    @com.squareup.moshi.* <methods>;
}
-keep @com.squareup.moshi.JsonQualifier interface *

supposition

Environnement d'exécution

article valeur
IDE Android Studio 2.3 & IntelliJ IDEA
Java 1.8.0_131
OS Windows 10

Ci-dessous, l'explication de la classe d'échantillon requise pour cette vérification d'opération sera poursuivie, donc [Cliquez ici pour sauter si inutile](# java-% E3% 82% AA% E3% 83% 96% E3 % 82% B8% E3% 82% A7% E3% 82% AF% E3% 83% 88% E3% 81% A8-json-% E3% 82% 92% E7% 9B% B8% E4% BA% 92% E5% A4% 89% E6% 8F% 9B% E3% 81% 99% E3% 82% 8B).

Classe à utiliser cette fois

Travaillons avec une classe qui définit les onglets dans un navigateur Web.

Tab.java


import java.util.ArrayList;
import java.util.List;

class Tab {

    private List<History> histories;

    private int index;

    private String thumbnailPath;

    private String lastTitle;

    Tab() {
        histories = new ArrayList<>();
        index = -1;
    }

    // Simple accessor methods...

    void addHistory(final History history) {
        histories.add(history);
        index++;
    }

    History getLatest() {
        return histories.get(index);
    }
}

La classe History utilisée dans la classe Tab est une classe simple qui n'a que deux champs de type String, comme indiqué ci-dessous.

History.java


class History {

    private final String title;

    private final String url;

    private History(final String title, final String url) {
        this.title = title;
        this.url   = url;
    }

    public static History make(final String title, final String url) {
        return new History(title, url);
    }

    public String title() {
        return title;
    }

    public String url() {
        return url;
    }

}

Préparation

Initialisez l'objet Tab avant les étapes suivantes.

final Tab tab = new Tab();
tab.setThumbnailPath("file://~~");
tab.setLastTitle("Google");
tab.addHistory(History.make("Title", "URL"));

Convertir entre les objets Java et JSON

Moshi utilise une classe appelée JsonAdapter pour effectuer la conversion.

Obtenez JsonAdapter

Créez un objet Moshi et utilisez la méthode adaptateur pour spécifier le type à convertir et obtenir l'objet JsonAdapter.

final Moshi moshi = new Moshi.Builder().build();
final JsonAdapter<Tab> tabJsonAdapter = moshi.adapter(Tab.class);

Objet Java-> Conversion JSON

Exécutez avec JsonAdapter.toJson.

final String json = tabJsonAdapter.toJson(tab);

production

Le JSON suivant est généré.

{"histories":[{"title":"Title","url":"URL"}],"index":0,"lastTitle":"Google","thumbnailPath":"file://~~"}

Pretty Printing Si vous souhaitez générer le JSON dans un état formaté, cela prendra un certain temps.

pretty_print


final Buffer buffer = new Buffer(); // 1.
final JsonWriter prettyPrintWriter = JsonWriter.of(buffer); // 2.
prettyPrintWriter.setIndent("  "); // 3.
try {
    tabJsonAdapter.toJson(prettyPrintWriter, tab); // 4.
} catch (final IOException e) {
    e.printStackTrace();
}

final String json = buffer.readUtf8(); // 5

procédure

  1. Préparez un objet Buffer pour Okio
  2. Obtenez l'objet JsonWriter pour l'objet Buffer dans 1.
  3. Définissez un retrait sur 2 JsonWriter
  4. Passez JsonWriter et l'objet Java à JsonAdapter.toJson et exécutez Puisque l'écriture est effectuée sur l'objet Buffer de 5.1, lisez pour extraire la chaîne de caractères.

Cela peut être un peu déroutant car plus de classes sont utilisées, toJson ne renvoie plus de valeurs directement et toJson lève désormais des exceptions.

Résultat de sortie

Comme indiqué ci-dessous, JSON a été généré avec le retrait spécifié.

{
  "histories": [
    {
      "title": "Title",
      "url": "URL"
    }
  ],
  "index": 0,
  "lastTitle": "Google",
  "thumbnailPath": "file://~~"
}

Remarques

Bien que cela ne soit pas pratique du tout, il semble que la chaîne de caractères passée comme retrait à l'étape 3 ci-dessus n'a pas d'importance. Par exemple, si * 2 est spécifié comme retrait, le JSON suivant sera généré.

{
**"histories": [
****{
******"title": "Title",
******"url": "URL"
****}
**],
**"index": 0,
**"lastTitle": "Google",
**"thumbnailPath": "file://~~"
}

Bien sûr, si vous transmettez ce JSON à JsonAdapter.fromJson, qui sera décrit plus tard, vous obtiendrez une exception car il ne peut pas être analysé en tant que JSON.

Conversion d'objets JSON-> Java

Exécutez avec JsonAdapter.fromJson. Cette méthode peut lever une IOException et doit être prise en charge.

try {
    final Tab fromJson = tabJsonAdapter.fromJson(json);
} catch (IOException e) {
    e.printStackTrace();
}

production

Affiche le contenu de l'objet Tab obtenu avec une sortie standard.

System.out.println(fromJson.getLastTitle());
System.out.println(fromJson.getThumbnailPath());
System.out.println(fromJson.getLatest().title());
System.out.println(fromJson.getLatest().url());
Google
file://~~
Title
URL

Il semble que la classe History définie par moi-même soit également convertie correctement. Je pense que c'est bien de pouvoir convertir même une classe qui n'a pas de constructeur public.

Code source

Le code de cette vérification d'opération est mis dans l'essentiel. https://gist.github.com/toastkidjp/252bc2ac86de2c0a3625b9fed0b9fc62


Résumé

Moshi est une bibliothèque JSON légère et facile à utiliser. Étant donné que la bibliothèque elle-même n'inclut pas la dépendance du SDK Android, elle peut être utilisée non seulement pour Android, mais également pour le développement d'applications Java normales. J'ai décrit une méthode de conversion mutuelle simple utilisant ce Moshi.

référence

Recommended Posts

Conversion entre objets Java et JSON à l'aide de Moshi
Conversion mutuelle entre fonction et consommateur
Moshi ~ Bibliothèque de conversion Json ~
Convertir JSON et YAML en Java (en utilisant Jackson et SnakeYAML)
[Java] Différence entre == et égal
Différences entre Java "débutant" et Kotlin
[JAVA] Différence entre abstrait et interface
[Java] Relation entre H2DB et JDBC
[Java] Différence entre array et ArrayList
[Android] Convertissez Map en JSON à l'aide de GSON avec Kotlin et Java
Différences entre Java et .NET Framework
[Java] Différence entre fermable et fermable automatiquement
[Java] Différence entre StringBuffer et StringBuilder
Liste de conversion mutuelle de tableau / liste / flux Java
[Java] Différence entre longueur, longueur () et taille ()
[Java] Conversion mutuelle de notations telles que les cas de chameau et les cas de serpent [Jackson]
Convertir des objets Java org.w3c.dom.Document et des chaînes XML
Relation entre les modificateurs d'accès kotlin et java
Différence entre final et immuable en Java
Etude Java n ° 3 (conversion de type et exécution d'instruction)
[Pour les débutants] Différence entre Java et Kotlin
Essayez d'utiliser l'API au format JSON en Java
[Java] Différences entre les variables d'instance et les variables de classe
Coopération entre Java et Derby en utilisant JDBC (en utilisant NetBeans)
[Java] Différence entre la plage Intstream et la plageClosed
[Java] Mécanisme de calcul, opérateurs et conversion de type
Différence entre int et Integer en Java
HashMap # putAll () se comporte différemment entre Java 7 et Java 8
Conversion mutuelle Hex et UIColor avec Swift
Résumé de la conversion mutuelle entre les méthodes Groovy par défaut de Groovy et l'API Stream de Java
[Java] Comprendre la différence entre List et Set
Créer une API à l'aide de Retrofit2, Okhttp3 et Gson (Java)
Installez java et android-sdk sur Mac en utilisant homebrew
Différence entre next () et nextLine () dans Java Scanner
JSON avec Java et Jackson Part 2 XSS mesures
Résumer les différences entre l'écriture C # et Java
Distinguer les nombres positifs et négatifs en Java
[Java] Différence entre "variable finale" et "objet immuable"