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

Documents Java Discussion :

[Jackson] Lire un fichier CSV avec Jackson


Sujet :

Documents Java

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre éprouvé
    Homme Profil pro
    Développeur Java
    Inscrit en
    Novembre 2014
    Messages
    109
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Gironde (Aquitaine)

    Informations professionnelles :
    Activité : Développeur Java
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Novembre 2014
    Messages : 109
    Par défaut [Jackson] Lire un fichier CSV avec Jackson
    Bonjour,

    Je dois ouvrir un csv en utilisant l'api Jackson. Voilà mon code :

    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
     
    public class ImportCsvTest {
     
    	public static void main(String[] args) throws JsonProcessingException, IOException {
    		System.out.println("==================================\n"
    				+ "    Import CSV (Troncons) test\n" 
    				+ "==================================\n");
     
    		final String MONCSV = "C:/Users/dsonfils/Documents/Mes_Projets/SAGASE/Workspace/polex-referentiel-import/src/main/csv/Troncons.csv";
    		List<TronconCsv> liste = ImportTronconServiceImpl.openFile(MONCSV);
    		System.out.println(liste.size());
    	}
    }
     
    public static List<TronconCsv> openFile(String monFichier) throws JsonProcessingException, IOException{
    		CsvMapper mapper = new CsvMapper();
    		CsvSchema schema = CsvSchema.emptySchema().withHeader();
    		MappingIterator<TronconCsv> it = mapper.readerFor(TronconCsv.class)
    				.with(schema).
    				readValues(monFichier);
    		List<TronconCsv> tronconListe = it.readAll();
    		return tronconListe;
    	}
    Il se trouve que liste.size() me retourne 0 et je ne comprend pas pourquoi ....

    Mercie d'avance pour toutes suggestions

  2. #2
    Modérateur
    Avatar de joel.drigo
    Homme Profil pro
    Ingénieur R&D - Développeur Java
    Inscrit en
    Septembre 2009
    Messages
    12 430
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 55
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Ingénieur R&D - Développeur Java
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2009
    Messages : 12 430
    Billets dans le blog
    2
    Par défaut
    Salut,

    La méthode ObjectReader.readValues(String) prend un contenu de fichier, pas un fichier.

    L'alternative est de passer par un reader, par exemple, comme ça (ici, attention, pas de gestion d'encodage) :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    try(Reader reader = Files.newBufferedReader(Paths.get(monFichier))) {
         MappingIterator<TronconCsv> it = mapper.reader(TronconCsv.class).with(schema).readValues(reader); 
         List<TronconCsv> tronconListe = it.readAll();
         return tronconListe;
    }
    Tu peux aussi passer un contenu, en le construisant/lisant d'abord :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    String content = Files.lines(Paths.get(monFichier)).collect(Collectors.joining("\n")); // lecture du fichier et conversion en texte
    MappingIterator<TronconCsv> it = mapper.reader(TronconCsv.class).with(schema).readValues(content);
    L'expression "ça marche pas" ne veut rien dire. Indiquez l'erreur, et/ou les comportements attendus et obtenus, et donnez un Exemple Complet Minimal qui permet de reproduire le problème.
    La plupart des réponses à vos questions sont déjà dans les FAQs ou les Tutoriels, ou peut-être dans une autre discussion : utilisez la recherche interne.
    Des questions sur Java : consultez le Forum Java. Des questions sur l'EDI Eclipse ou la plateforme Eclipse RCP : consultez le Forum Eclipse.
    Une question correctement posée et rédigée et vous aurez plus de chances de réponses adaptées et rapides.
    N'oubliez pas de mettre vos extraits de code entre balises CODE (Voir Mode d'emploi de l'éditeur de messages).
    Nouveau sur le forum ? Consultez Les Règles du Club.

  3. #3
    Membre éprouvé
    Homme Profil pro
    Développeur Java
    Inscrit en
    Novembre 2014
    Messages
    109
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Gironde (Aquitaine)

    Informations professionnelles :
    Activité : Développeur Java
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Novembre 2014
    Messages : 109
    Par défaut
    Je te remercie pour ton aide. J'ai essayé d'implémenter ta première solution en écrivant un test unitaire :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
     
    @Test
    	public void ouvertureFichierMapperTest() throws IOException{
    		File moncsv = new File("src/test/resources/Troncons.csv");
    		CsvMapper mapper = new CsvMapper();
    		CsvSchema schema = mapper.schemaFor(TronconCsv.class).withHeader()
    				.withColumnSeparator(',').withNullValue("");
    		Reader reader = Files.newBufferedReader(Paths.get(moncsv.getAbsolutePath()));
    		MappingIterator<TronconCsv> it = mapper.readerFor(TronconCsv.class).with(schema).readValues(reader); 
    		List<TronconCsv> tronconListe = it.readAll();
    	}
    Ce test me renvoie une erreur du type :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    com.fasterxml.jackson.databind.exc.InvalidFormatException: Can not deserialize value of type java.lang.Long from String "5927;70;35;1": not a valid Long value
    Dans les dernière colonnes j'ai des nombres à virgules du genre 1,53. Du coup j'imagine que j'ai un problème avec withColumnSeparator(',') que j'ai remplacé par withColumnSeparator(';').

    Maintenant j'ai une erreur du type :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    com.fasterxml.jackson.databind.exc.InvalidFormatException: Can not deserialize value of type double from String "chemin": not a valid Double value
    Je me suis rendu compte que le schema ne renvoie pas les items de mon POJO (TronconCsv) dans le bon ordre. Du coup j'ai un conflit entre le type attendu et le type reçu. Pourtant j'ai bien utiliser l'annotation
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
     
    @JsonPropertyOrder(value ={"p1","p2",...,"pn"})
    public class TronconCsv{ 
        String p1;
        String p2;
        double p3
    }
    J'ai l'impression qu'il récupère par exemple la valeur de la colonne p2 et qu'il essaie de l'associer à p3.
    Une idée ?

  4. #4
    Membre éprouvé
    Homme Profil pro
    Développeur Java
    Inscrit en
    Novembre 2014
    Messages
    109
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Gironde (Aquitaine)

    Informations professionnelles :
    Activité : Développeur Java
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Novembre 2014
    Messages : 109
    Par défaut
    En fouillant d'avantage, il s'avère que j'ai oublié une annotation :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
     
    @JsonPropertyOrder(value ={"p1","p2","p3"})
    public class TronconCsv{ 
        @JsonProperty("p1")
        String p1;
     
        @JsonProperty("p2")
        String p2;
     
        @JsonProperty("p3")
        double p3
    }
    Mon schéma est bien dans l'ordre voulu à un détail pret... Une fois qu'il a finit de prendre ce qui est définit dans le @JsonPropertyOrder il rajoute au schéma des doublons de propriétés :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    schema ={"p1","p2","p3","p3","p1"}
    Ce qui est en vert ne devrait pas faire partie du schema...

    Je comprend pas le résultat que j'observe. Une idée ?

  5. #5
    Membre éprouvé
    Homme Profil pro
    Développeur Java
    Inscrit en
    Novembre 2014
    Messages
    109
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Gironde (Aquitaine)

    Informations professionnelles :
    Activité : Développeur Java
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Novembre 2014
    Messages : 109
    Par défaut
    J'ai résolu mon problème de schema.

    Il s'avère que j'avais fait du refecato sur les nom de variables (avec le racourci alt+shift+R dans éclipse). J'avais oublié de regénerer les getters/setters ....
    Du coup, les champs rajoutés dans le schema provenaient des getters/setters non renomés.

    Par contre j'ai toujours le problème de type :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    com.fasterxml.jackson.databind.exc.InvalidFormatException: Can not deserialize value of type double from String "4,79703": not a valid Double value
    J'imagine qu'il doit exister une anontation du type @Deserialize pour régler ce problème mais je n'ai pas encore trouvé ...


    EDIT :
    En fait il y a bien une annotation @JsonDeserialize(using=ItemDeserializer.class) qui existe.
    Il suffisait de créer la classe ItemDeserializer

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
     
    public class ItemDeserializer extends JsonDeserializer<Double> {
    	@Override
    	public Double deserialize(JsonParser jp, DeserializationContext ctxt) throws IOException {    	
            // moncode
        }
    }
    En fait le problème venait de la virgule qui est utilisé par défaut dans le csv. Grâce à la fonction si dessus, je peux remplacer la virgule par un point. J'ai bien un double à la fin.


    Du coup c'est résolu !

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. Lire un fichier csv avec séparateur ";"
    Par Invité dans le forum C++/CLI
    Réponses: 7
    Dernier message: 05/11/2015, 21h00
  2. Réponses: 11
    Dernier message: 07/10/2011, 09h19
  3. Lire fichier CSV avec tabulation comme séparation
    Par theNoob dans le forum Langage
    Réponses: 3
    Dernier message: 07/09/2009, 18h52
  4. Lire un fichier CSV envoyé avec une requête POST
    Par Marm B dans le forum Langage
    Réponses: 6
    Dernier message: 26/08/2009, 13h31
  5. [AC-2003] Lire un fichier CSV de 170Mo avec Access
    Par mmmxtina dans le forum VBA Access
    Réponses: 12
    Dernier message: 15/07/2009, 13h45

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