web-dev-qa-db-fra.com

Comment imprimer un objet Java complexe (par exemple, avec des champs qui sont des collections d'objets)?

Je recherche une fonction de bibliothèque (idéalement, à partir d'un framework couramment utilisé, par exemple Spring, Gava, Apache Commons, etc.) qui imprimera correctement les valeurs de tout objet Java.

C'est une question générale plutôt que spécifique. J'ai vu des questions similaires sur StackOverflow pour lesquelles une réponse courante est "implémentez votre propre méthode toString() sur la classe" mais cette option n'est pas toujours pratique - je recherche un moyen général de le faire avec n'importe quel objet rencontré, ce qui peut être à l'origine à partir du code tiers. Une autre suggestion consiste à utiliser RefectionToStringBuilder de Apache Commons, par exemple:

new ReflectionToStringBuilder(complexObject, new RecursiveToStringStyle()).toString()

Mais cela a un usage limité - par exemple quand il tombe sur une collection, il a tendance à produire quelque chose comme ceci:

Java.util.ArrayList@fcc7ab1[size=1]

Un exemple de cas d'utilisation réel consiste à enregistrer une Iterable<PushResult> renvoyée par la méthode pushCommand.call() de JGit - si vous postez une réponse, assurez-vous que cela fonctionne avec cet objet ainsi qu'avec tout autre objet complexe.

6
Steve Chambers

Vous pouvez essayer d'utiliser Gson. il sérialise également des tableaux, des cartes ou quoi que ce soit ....

MyObject myObject = new MyObject();
Gson gson = new GsonBuilder().setPrettyPrinting().serializeNulls().create();
gson.toJson(myObject);

Pour la désérialisation, utilisez:

gson.fromJson(MyObject.class);

Pour les cartes typées, voir la réponse suivante: Gson: existe-t-il un moyen plus simple de sérialiser une carte

3
Naxos84

Un moyen possible de le faire pour tout objet sans l'utilisation d'une bibliothèque externe serait d'utiliser la réflexion d'un type générique. Dans l'extrait suivant, nous accédons simplement à chaque champ (y compris les champs privés) et affichons leur nom et leur valeur:

public static <T> String printObject(T t) {
    StringBuilder sb = new StringBuilder();

    for (Field field : t.getClass().getDeclaredFields()) {
        field.setAccessible(true);

        try {
            sb.append(field.getName()).append(": ").append(field.get(t)).append('\n');
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    return sb.toString();
}

Cette méthode peut être placée dans une classe d’utilitaire pour un accès facile.

Si l'un des champs de l'objet ne remplace pas Object#toString, il imprimera simplement le type de l'objet et son hashCode.

Exemple:

public class Test {

    private int x = 5;

    private int y = 10;

    private List<List<Integer>> list = Arrays.asList(Arrays.asList(1, 2, 3), Arrays.asList(4, 5, 6));

}

>> printObject(new Test());
>>
>> x: 5
>> y: 10
>> list: [[1, 2, 3], [4, 5, 6]]
1
Jacob G.

Vous pouvez utiliser un mappeur JSON (ou un autre format) pour imprimer joliment votre objet. Il doit gérer la plupart des champs "standard" (primitives, chaînes, collections, cartes, tableaux, etc.). Dans le cas contraire, vous pouvez toujours ajouter un sérialiseur personnalisé.

Par exemple, avec Jackson, cela pourrait être aussi simple que cela:

public static void main(String... args) throws Exception {
  ObjectMapper om = new ObjectMapper();
  om.enable(SerializationFeature.INDENT_OUTPUT); //pretty print
  String s = om.writeValueAsString(new Pojo());
  System.out.println(s);
}


static class Pojo {
  private int id = 1;
  private List<String> list = Arrays.asList("A", "B");
  //getters etc.
}

Ce code affiche:

{
  "id" : 1,
  "list" : [ "A", "B" ]
}
1
assylias

Vous pouvez utiliser la classe ObjectMapper pour lier des données avec json. vous pouvez l'utiliser comme ci-dessous:

ObjectMapper mapper = new ObjectMapper();

vous pouvez enregistrer JSON en objet comme ci-dessous

Object json = mapper.readValue(input,object.class);

vous pouvez l'écrire dans une variable chaîne

String prettyJson = mapper.writerWithDefaultPrettyPrinter().writeValueAsString(json);

ça devrait marcher.

1
Sagar Trivedi

Vous pouvez utiliser GSON pour convertir votre objet en chaîne. Cela fonctionnera pour tous les objets,

Gson gson = new Gson();
System.out.println(gson.toJson(objectYouWantToPrint).toString());
0
Vijayakumar