CONNEXION
  • RetourJeux
    • Sorties
    • Hit Parade
    • Les + populaires
    • Les + attendus
    • Soluces
    • Tous les Jeux
    • Gaming
  • RetourActu Gaming
    • News
    • Astuces
    • Tests
    • Previews
    • Toute l'actu gaming
  • RetourBons plans
    • Bons plans
    • Bons plans Smartphone
    • Bons plans Hardware
    • Bons plans Image et Son
    • Bons plans Amazon
    • Bons plans Cdiscount
    • Bons plans Decathlon
    • Bons plans Fnac
    • Tous les Bons plans
  • RetourJVTech
    • Actus High-Tech
    • Intelligence Artificielle
    • Smartphones
    • Mobilité urbaine
    • Hardware
    • Image et son
    • Tutoriels
    • Tests produits High-Tech
    • Guides d'achat High-Tech
    • JVTech
  • RetourCulture
    • Actus Culture
    • Culture
  • RetourVidéos
    • A la une
    • Gaming Live
    • Vidéos Tests
    • Vidéos Previews
    • Gameplay
    • Trailers
    • Chroniques
    • Replay Web TV
    • Toutes les vidéos
  • RetourForums
    • Hardware PC
    • PS5
    • Switch 2
    • Xbox Series
    • Switch
    • Pokemon pocket
    • FC 25 Ultimate Team
    • League of Legends
    • Tous les Forums
  • PC
  • PS5
  • Xbox Series
  • Switch 2
  • PS4
  • One
  • Switch
  • iOS
  • Android
  • MMO
  • RPG
  • FPS
En ce moment Genshin Impact Valhalla Breath of the wild Animal Crossing GTA 5 Red dead 2
Liste des sujets

Java Jackson : où télécharger ?

Pseudo supprimé
Pseudo supprimé 10 juin 2016 à 13:31:55

Bonjour à tous,

Je souhaite utiliser l'API JackSON dans un projet Java pour manipuler des fichiers dont le contenu est formaté en JSON.

Il me faut donc, a priori, un .JAR.
Savez-où le télécharger dans cette page ? Je ne m'y retrouve pas... https://github.com/FasterXML/jackson/wiki/Jackson-Release-2.7.4

Pseudo supprimé
Pseudo supprimé 10 juin 2016 à 14:26:41

Utilise maven ou gradle et mets la dépendance qui va bien [[sticker:p/1lmb]]


<dependency>
    <groupId>com.fasterxml.jackson.core</groupId>
    <artifactId>jackson-core</artifactId>
    <version>2.7.4</version>
</dependency>

Tu peux le télécharger comme indiqué sur le github ( https://github.com/FasterXML/jackson-core ) directement en jar depuis le repo maven et l'inclure dans le /lib de ton application :
http://repo1.maven.org/maven2/com/fasterxml/jackson/core/jackson-core/

Mais utilise plutôt maven/gradle :hap:

Message édité le 10 juin 2016 à 14:31:19 par Pseudo supprimé
Pseudo supprimé
Pseudo supprimé 10 juin 2016 à 14:40:29

En fait j'ai réussi, sans utiliser Gradle/Maven !
Pour ceux que ça intéresse il suffit de télécharger le jar core + le jar databind + le jar annotations . :oui: !

Mais merci !
Alors par contre j'ai une nouvelle question. J'utilise l'ObjectMapper et sa méthode readValue pour créer une instance d'une classe A que j'ai écrite depuis un JSON (désérialisation).
J'ai remarqué que je ne peux pas, dans la classe A, mettre un constructeur à arguments car celui-ci écrase le constructeur vide. Apparemment, JackSON, pour effectuer la désérialisation, fait appel au constructeur vide. Est-ce que je me trompe ?

Pseudo supprimé
Pseudo supprimé 10 juin 2016 à 14:41:48

Et du coup la désérialisation avec le constructeur vide consiste à parcourir chaque valeur du fichier JSON et à l'attribuer aux attributs de la classe A dans l'ordre dans lequel ceux-ci apparaissent ? C'est le principe de la désérialisation quand il y a un constructeur vide, je crois.... :question: :question:

Enfin bref si quelqu'un peut m'éclairer à ce sujet ce serait vachement cool !

Pseudo supprimé
Pseudo supprimé 10 juin 2016 à 14:44:44

Ah je viens d'utiliser JsonCreator et JsonProperty pour pouvoir faire usage d'un constructeur à paramètres ! C'est cool je trouve :oui: :ok:

Pseudo supprimé
Pseudo supprimé 10 juin 2016 à 15:19:20

En réalité pour ton problème, tu peux tout-à-fait mettre des constructeurs à arguments.
Cependant, pour faire fonctionner ton objectMapper il faut absolument que ton pojo aie un constructeur par défaut.

Donc en gros si tu mets des constructeurs avec paramètres, ajoute un constructeur vide sans paramètre :ok:


public class Toto {
    
    // Constructeur par défaut (vide), utilisé par Jackson
    public Toto() {}

    // Constructeur avec paramètre
    public Toto(Integer i) {
    }
}
Message édité le 10 juin 2016 à 15:22:05 par Pseudo supprimé
Pseudo supprimé
Pseudo supprimé 11 juin 2016 à 14:30:19

Le 10 juin 2016 à 15:19:20 SemenceDeTroll a écrit :
En réalité pour ton problème, tu peux tout-à-fait mettre des constructeurs à arguments.
Cependant, pour faire fonctionner ton objectMapper il faut absolument que ton pojo aie un constructeur par défaut.

Donc en gros si tu mets des constructeurs avec paramètres, ajoute un constructeur vide sans paramètre :ok:


public class Toto {
    
    // Constructeur par défaut (vide), utilisé par Jackson
    public Toto() {}

    // Constructeur avec paramètre
    public Toto(Integer i) {
    }
}

Oui mais en utilisant les annotations JsonCreator et Jsonproperty, on peut très bien ne pas avoir de constructeur vide ^^ !

Pseudo supprimé
Pseudo supprimé 11 juin 2016 à 14:50:35

Oui en effet,
c'est juste que tu te lies très fortement à Jackson en utilisant les annotations, et que le jour où tu changeras de librairies ça risque d'avoir un coût non négligeable d'effectuer la dite migration.

Le constructeur vide (sauf si tu souhaites absolument l'éviter car sémantiquement ne répond pas à ta modélisation) est une petite astuce permettant d'éviter cela.

Je ne vois d'ailleurs pas pourquoi un POJO devrait être fortement lié à Jackson via des annotations (qui reste une librairie - donc tierce), côté modélisation objet je trouve cela très mauvais.

Une petite discussion d'ailleurs, apparemment JDK8 permet d'autres choses :
http://stackoverflow.com/questions/21920367/why-when-a-constructor-is-annotated-with-jsoncreator-its-arguments-must-be-ann

Message édité le 11 juin 2016 à 14:53:57 par Pseudo supprimé
Pseudo supprimé
Pseudo supprimé 11 juin 2016 à 14:53:50

Le 11 juin 2016 à 14:50:35 SemenceDeTroll a écrit :
Oui en effet,
c'est juste que tu te lies très fortement à Jackson en utilisant les annotations, et que le jour où tu changeras de librairies ça risque d'avoir un coût non négligeable d'effectuer la dite migration.

Le constructeur vide (sauf si tu souhaites absolument l'éviter car sémantiquement ne répond pas à ta modélisation) est une petite astuce permettant d'éviter cela.

Tout à fait ! Après je ne suis pas sûr d'avoir très bien compris comment fonctionne Jackson. Est-ce que ça te dérangerait que je pose une ou 2 questions à ce sujet :question:

Pseudo supprimé
Pseudo supprimé 11 juin 2016 à 15:02:05

Je ne suis absolument pas expert Jackson hein^^. Moi j'ai plutôt l'habitude de l'utiliser comme un simple service.
Le souci de ne pas mettre les annotations c'est qu'il va utiliser le nom des attributs dans le JSON, ce qui peut être dangereux en cas de renommage/refactoring et ne pas permettre la rétrocompatibilité (d'où l'existence des annotations qui supprime la corrélation entre nom des attributs et JSON généré, permettant le refactoring).

Cependant on peut très bien changer le texte dans l'annotation et tout autant casser la rétrocompatibilité.

C'est pour ça que je préfère finalement ne pas lié l'objet à sérialiser à jackson. Ca me permet de ne pas les coupler entre eux et de minimiser le temps de migration le jour où je changerai de librairie :)

Par ex :


@Component
public class JSONDelegateImpl implements JSONDelegate {
    
    private static final Logger logger = LoggerFactory.getLogger(JSONDelegateImpl.class);
    
    
    // Injections
    //----------------------------------------------------
    
    @Resource(name="jsonMapper")
    private ObjectMapper jsonMapper;
    
    
    // Process
    //----------------------------------------------------
    
    @Override
    public String serialize(Object obj) {
        String str = null;
        try {
            if(obj != null) {
                str = jsonMapper.writeValueAsString(obj);
            }

        } catch (JsonProcessingException e) {
            logger.warn("Unable to serialize object in JSON", e);
        }
        return str;
    }
    
    @Override
    public <T> T unserialize(String str, Class<T> clazz) {
        T object = null;
        try {
            object = jsonMapper.readValue(str, clazz);
        } 
        catch (JsonParseException e)   { errorJSON(str, clazz, e); } 
        catch (JsonMappingException e) { errorJSON(str, clazz, e); }
        catch (IOException e)          { errorJSON(str, clazz, e); }

        return object;
    }
    
    
    // Private methods
    //----------------------------------------------------
    
    private static <T> void errorJSON(String str, Class<T> clazz, Exception e) {
        logger.error("Unable to load unserialize {} in {}.class : {}", str, clazz.getName(), e.getMessage());
    }

}

où ObjectMapper est un singleton.


<bean id="jsonMapper" class="com.fasterxml.jackson.databind.ObjectMapper" />

Puis on l'utilise (sans savoir que c'est Jackson qui sert à sérialiser) :


Toto toto = new Toto("a", "b", "c");
String jsonToto = JSONDelegate.serialize(toto);
Message édité le 11 juin 2016 à 15:03:07 par Pseudo supprimé
Pseudo supprimé
Pseudo supprimé 11 juin 2016 à 15:05:43

Je vois.

Mais la méthode ObjectMapper::readValue, concrètement, que fait-elle ? J'ai du mal à comprendre le deuxième argument, car celui-ci peut très bien être une classe, ou une structure Java Collection, ou encore un TypeReference qu'on instancie... C'est bizarre...

Pseudo supprimé
Pseudo supprimé 11 juin 2016 à 15:10:07

ObjectMapper::readValue permet de désérialiser un object String (JSON) en un object Java.
Le deuxième argument permet à Jackson de savoir quel type d'objet utiliser.

Par ex :


Toto toto = new Toto("a", "b", "c");
String jsonToto = JSONDelegate.serialize(toto);
Toto toto2 = JSONDelegate.unserialize(jsonToto, Toto.class); // on doit retrouver l'objet Toto, donc toto2.equals(toto) == true
Pseudo supprimé
Pseudo supprimé 11 juin 2016 à 15:11:44

"Le deuxième argument permet à Jackson de savoir quel type d'objet utiliser."

Quel type d'objet Java utiliser ?

Pseudo supprimé
Pseudo supprimé 11 juin 2016 à 15:14:55
String json; // Ta String JSON
objectMapper.readValue(json, MyClass.class);

Jackson va essayer de créer une instance de la classe MyClass à partir du json fourni.

Message édité le 11 juin 2016 à 15:15:20 par Pseudo supprimé
Pseudo supprimé
Pseudo supprimé 11 juin 2016 à 15:16:03

D'accord donc ça va j'avais bien compris. ^^

Et dans ce genre de trucs, qu'essaie-t-il de faire ?
Map<String,Object> userData = mapper.readValue(new File("user.json"), Map.class);

Pseudo supprimé
Pseudo supprimé 11 juin 2016 à 15:18:37

http://stackoverflow.com/questions/2525042/how-to-convert-a-json-string-to-a-mapstring-string-with-jackson-json
:ok:

Pseudo supprimé
Pseudo supprimé 11 juin 2016 à 15:20:33

Mmmh moui merci x)

Pseudo supprimé
Pseudo supprimé 11 juin 2016 à 15:25:48

En fait je n'ai jamais utilisé Jackson dans ton cas d'utilisation (à chaque fois je l'utilise avec mes propres types définis).

J'imagine que le fait de lui donner une Map.class (une interface donc) est problématique et qu'il faille lui fournir une vraie classe pouvant être instanciée (donc ni interface, ni classe abstraite).


Map<String,String> map = new HashMap<String,String>();
ObjectMapper mapper = new ObjectMapper();
map = mapper.readValue(string, HashMap.class);

Ca semble marcher d'après ce que dis qqn. Ou sinon essaie de passer par les TypeReference.

Message édité le 11 juin 2016 à 15:27:54 par Pseudo supprimé
Pseudo supprimé
Pseudo supprimé 11 juin 2016 à 15:27:25

Mmmh merci ^^

En fait je te demande tout ça car je n'arrive pas à utiliser un JSON dont le contenu est un objet sans nom contenant 2 arrays d'objets...

C'est fatiguant...

Pseudo supprimé
Pseudo supprimé 11 juin 2016 à 15:32:34

Tu peux donner ton JSON (ou du moins juste un exemple, pas forcément le tout si c'est énorme...) pour que j'y jette un oeil ?

Sous forums
  • Aide à l'achat Mac
  • Macintosh
  • Création de sites web
  • Création de Jeux
  • Linux
  • Programmation
  • Internet
  • Steam Deck
  • Hardware
La vidéo du moment