IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Format d'échange (XML, JSON...) Java Discussion :

[JSON / Jackson] Comment désérialiser une chaine JSON qui répète le nom de la variable qu'elle désérialise ?


Sujet :

Format d'échange (XML, JSON...) Java

  1. #1
    Membre très actif

    Profil pro
    Inscrit en
    Janvier 2007
    Messages
    608
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Janvier 2007
    Messages : 608
    Par défaut [JSON / Jackson] Comment désérialiser une chaine JSON qui répète le nom de la variable qu'elle désérialise ?
    Bonjour,

    Je souhaite appeler des services REST sur GeoServer.
    Les appels fonctionnent (retour avec code statut : 200) mais les objets je ne parviens pas à les dé-sérialiser correctement.

    J'ai cet objet, dont je voudrais au moins obtenir le name, en le désérialisant.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    @JsonIgnoreProperties(ignoreUnknown = true)
    @JsonRootName(value = "workspace")
    public class Workspace implements Serializable
    {
       /** Serial Id. */
       private static final long serialVersionUID = -858202108313130391L;
     
       /** Nom du workspace. */
       @JsonProperty("name")
       private String name;
     
       /** Lien vers le workspace. */
       @JsonProperty("href")
       private String href;
     
       /**
        * Renvoyer le nom du workspace.
        * @return Nom du workspace.
        */
       public String getName()
       {
          return this.name;
       }
     
       /**
        * Fixer le nom du workspace.
        * @param name Nom du workspace.
        */
       public void setName(String name)
       {
          this.name = name;
       }
     
       /**
        * Renvoyer le lien vers le workspace. 
        * @return Lien vers le workspace.
        */
       public String getHref()
       {
          return this.href;
       }
     
       /**
        * Fixer le lien vers le workspace.
        * @param href Lien vers le workspace.
        */
       public void setHref(String href)
       {
          this.href = href;
       }
     
       /**
        * @see java.lang.Object#toString()
        */
       @Override 
       public String toString()
       {
          return BabelTower.format(Workspace.class, Locales.getDefault(), "toString", this.name, this.href);
       }
    }

    Voici le test unitaire qui éprouve la désérialisation et montre le problème que je rencontre. Voici le contenu des deux chaînes qui participent au test :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    geoserver_workspace.json =>
    {"workspace":{"name":"topp","dataStores":"http:\/\/localhost:8080\/geoserver\/rest\/workspaces\/topp\/datastores.json","coverageStores":"http:\/\/localhost:8080\/geoserver\/rest\/workspaces\/topp\/coveragestores.json","wmsStores":"http:\/\/localhost:8080\/geoserver\/rest\/workspaces\/topp\/wmsstores.json"}}
     
    et geoserver_workspace_alternative.json =>
    {"name":"topp","dataStores":"http:\/\/localhost:8080\/geoserver\/rest\/workspaces\/topp\/datastores.json","coverageStores":"http:\/\/localhost:8080\/geoserver\/rest\/workspaces\/topp\/coveragestores.json","wmsStores":"http:\/\/localhost:8080\/geoserver\/rest\/workspaces\/topp\/wmsstores.json"}
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    @Test
    public void workspace_mapper() throws JsonGenerationException, JsonMappingException, IOException
    {
      // Sérialisation : pour voir la manière dont jackson sérialiserait lui-même l'objet si on le lui demandait.
      Workspace w1 = new Workspace();
      w1.setName("essai");
      w1.setHref("Lien vers url essai");
     
      StringWriter swtr = new StringWriter();
     
      ObjectMapper mapper = new ObjectMapper();
      mapper.writerWithDefaultPrettyPrinter().writeValue(swtr, w1);
      log.info("La séralisation de w1 donne en JSON {}", swtr.toString());
     
      // Désérialisation avec la chaîne JSON que renvoie geoserver.
      File fileW2 = new File(getClass().getClassLoader().getResource("geoserver_workspace.json").getFile());
      Workspace w2 = mapper.readValue(fileW2, Workspace.class);
      log.info("La désérialisation du workspace w2 depuis la chaîne sortie de geoserver donne : {}", w2);
     
      // Désérialisation avec la chaîne JSON pour laquelle notre test serait satisfait.
      File fileW3 = new File(getClass().getClassLoader().getResource("geoserver_workspace_alternative.json").getFile());
      Workspace w3 = mapper.readValue(fileW3, Workspace.class);
      log.info("La désérialisation du workspace w3 depuis la chaîne que jackson aurait préféré donne : {}", w3);
     
      assertNotNull("Le workspace n'a pas été extrait de la chaine w3", w3);
      assertNotNull("Le workspace de la chaîne w3 n'a pas de nom", w3.getName());
     
      assertNotNull("Le workspace n'a pas été extrait de la chaîne w2", w2);
      assertNotNull("Le workspace de la chaîne n'a pas de nom w2", w2.getName());
    }
    Voici les logs d'étape du déroulé de ce test :
    La séralisation de w1 donne en JSON {
    "name" : "essai",
    "href" : "Lien vers url essai"
    }

    La désérialisation du workspace w2 depuis la chaîne sortie de geoserver donne : {nom : null, lien : null}
    La désérialisation du workspace w3 depuis la chaîne que jackson aurait préféré donne : {nom : topp, lien : null}

    Quel paramétrage dois-je faire pour que Jackson désérialise correctement la chaîne qui vient de geoserver, et qui est celle-ci ?
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    {"workspace":{"name":"topp","dataStores":"http:\/\/localhost:8080\/geoserver\/rest\/workspaces\/topp\/datastores.json","coverageStores":"http:\/\/localhost:8080\/geoserver\/rest\/workspaces\/topp\/coveragestores.json","wmsStores":"http:\/\/localhost:8080\/geoserver\/rest\/workspaces\/topp\/wmsstores.json"}}
    Le @JsonRootName(value = "workspace") que j'ai mis sur mon objet est une expérience parmi tant d'autres que j'ai faites, mais qui n'aboutit pas.
    Parfois, je me demande si Jackson examine seulement les annotations que j'ai mises sur mon objet.

    Merci !

  2. #2
    Membre très actif

    Profil pro
    Inscrit en
    Janvier 2007
    Messages
    608
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Janvier 2007
    Messages : 608
    Par défaut
    Je commence à comprendre ce qui se passe.

    GeoServer répond systématiquement une chaîne JSON qui ne peut être lue que par un objet qui a pour variable membre workspace, et pas directement par un objet qui serait déjà un workspace.

    Si je crée la classe :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    class Essai
    {
       private Workspace workspace;
     
       public Workspace getWorkspace() {return this.workspace;}
       public void setWorkspace(Workspace workspace) {this.workspace = workspace;}
     
       @Override public String toString() {return this.workspace != null ? this.workspace.toString() : null;}
    };
    Et que j'essaie ceci :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    File fileW4 = new File(getClass().getClassLoader().getResource("geoserver_workspace.json").getFile());
    Essai w4 = mapper.readValue(fileW4, Essai.class);
    log.info("La désérialisation du workspace w4 depuis la chaîne sortie de geoserver donne : {}", w4);
    Tout fonctionne.
    La désérialisation du workspace w4 depuis la chaîne sortie de geoserver donne : {nom : topp, lien : null}

    Mais il me faut créer un objet "parent"...
    Du coup, malgré tout, je trouve que ça ne va pas.
    Je dois faire fausse route quelque-part.


    C'est assez curieux comme fonctionnement, et je suis débutant en JSON.

    J'obtiens ceci, si j'interroge Geoserver sur un browser avec :
    http://localhost:8080/geoserver/rest/workspaces.json

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    {
    	"workspaces": {
    		"workspace": [{
    			"name": "sf",
    			"href": "http:\/\/localhost:8080\/geoserver\/rest\/workspaces\/sf.json"
    		}, {
    			"name": "sde",
    			"href": "http:\/\/localhost:8080\/geoserver\/rest\/workspaces\/sde.json"
    		}, {
    			"name": "cite",
    			"href": "http:\/\/localhost:8080\/geoserver\/rest\/workspaces\/cite.json"
    		}, {
    			"name": "nurc",
    			"href": "http:\/\/localhost:8080\/geoserver\/rest\/workspaces\/nurc.json"
    		}, {
    			"name": "tiger",
    			"href": "http:\/\/localhost:8080\/geoserver\/rest\/workspaces\/tiger.json"
    		}, {
    			"name": "it.geosolutions",
    			"href": "http:\/\/localhost:8080\/geoserver\/rest\/workspaces\/it.geosolutions.json"
    		}, {
    			"name": "topp",
    			"href": "http:\/\/localhost:8080\/geoserver\/rest\/workspaces\/topp.json"
    		}]
    	}
    }
    avec à l'entendre, un workspace constitué de name et href,

    mais j'obtiens ceci, si je poursuis avec cette requête qui demande donc le détail du workspace nommé topp :
    http://localhost:8080/geoserver/rest...aces/topp.json

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    {
    	"workspace": {
    		"name": "topp",
    		"dataStores": "http:\/\/localhost:8080\/geoserver\/rest\/workspaces\/topp\/datastores.json",
    		"coverageStores": "http:\/\/localhost:8080\/geoserver\/rest\/workspaces\/topp\/coveragestores.json",
    		"wmsStores": "http:\/\/localhost:8080\/geoserver\/rest\/workspaces\/topp\/wmsstores.json"
    	}
    }
    qui dit qu'il est fait (aussi) d'un dataStores, coverageStores, wmsStores.

    Qu'attend t-il que je fasse ?
    Qu'appel par appel je complète mon objet Workspace des variables membres qui lui manquent, en exécutant chaque lien rest proposé en regard ?
    Ça promet d'être long !

Discussions similaires

  1. Réponses: 2
    Dernier message: 28/10/2015, 10h57
  2. Comment executer une requete json avec java?
    Par stpaul04 dans le forum Débuter avec Java
    Réponses: 7
    Dernier message: 03/08/2014, 04h27
  3. Key et valeurs d'une chaine JSON
    Par Mengué georges dans le forum Format d'échange (XML, JSON...)
    Réponses: 3
    Dernier message: 09/07/2013, 14h03
  4. Convertir une chaine json en array
    Par okoweb dans le forum jQuery
    Réponses: 5
    Dernier message: 08/11/2012, 12h52
  5. Réponses: 6
    Dernier message: 20/04/2011, 15h41

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo