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

Développement Web en Java Discussion :

Optional vide et null


Sujet :

Développement Web en Java

  1. #1
    Membre confirmé Avatar de Badshade23
    Homme Profil pro
    Développeur Java
    Inscrit en
    Décembre 2014
    Messages
    203
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Développeur Java

    Informations forums :
    Inscription : Décembre 2014
    Messages : 203
    Par défaut Optional vide et null
    Bonjour,
    J'utilise Spring boot pour un projet web ou il servira de back et j'ai un problème.

    Je voudrais tester si mon optionnal est null ou vide.
    J'ai commencé comme ça :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
     
    @GetMapping("/user/{id}")
    	public ResponseEntity<User> getUserById(@PathVariable Long id) {
    		return Optional.ofNullable(userService.findUserById(id)).map(user -> {
    			return ResponseEntity.ok(user.get());
    		}).orElseGet(() -> ResponseEntity.notFound().build());
    	}
    Mais même si je teste la nullité de l'optionnal grâce à Optional.ofNullable, si celui-ci est vide il passe quand même dans la map et créer une exception avec le "user.get()". Je sais qu'il existe d'autres moyens avec le ispresent , ifpresent ... mais je voulais éviter de faire un "if - else". Le but de cette question et simplement de savoir si il y a un autre moyen que le basique if-else.

    Connaissez-vous un moyen de réussir ceci ?
    J'ai essayé comme ça aussi :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    @GetMapping("/user/{id}")
    	public ResponseEntity<User> getUserById(@PathVariable Long id) {
    		return Optional.ofNullable(userService.findUserById(id)).ifPresentOrElse(user -> ResponseEntity.ok(user.get()),
    				() -> ResponseEntity.notFound().build());
    	}
    Mais ifPresentOrElse a un retour à void donc ....

    Preneur d'idée, je ne sais pas si c'est réalisable

  2. #2
    Membre chevronné
    Homme Profil pro
    Architecte technique
    Inscrit en
    Mai 2020
    Messages
    338
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Belgique

    Informations professionnelles :
    Activité : Architecte technique

    Informations forums :
    Inscription : Mai 2020
    Messages : 338
    Par défaut
    Bonjour,

    C'est étrange; `Optional.ofNullable` crée un empty si la valeur est `null`. Il ne devrait donc pas passer dans le map.
    Quel genre d'excpetion avez-vous ? Etes vous sur qu'elle provienne du déréferencement de `user` ?

  3. #3
    Membre confirmé Avatar de Badshade23
    Homme Profil pro
    Développeur Java
    Inscrit en
    Décembre 2014
    Messages
    203
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Développeur Java

    Informations forums :
    Inscription : Décembre 2014
    Messages : 203
    Par défaut
    Salut,
    la valeur que retourne userService.findUserById(id); est un Optional<User>.
    Optional.ofNullable vérifie juste que l'optional n'est pas null mais il ne vérifie pas si celui-ci est vide ou non ...
    Donc on passe dans le map est celle-ci déclenche une exception au moment du user.get() car celui-ci n'existe pas.
    Comme dit plus haut je peux très bien faire comme ça :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
     
    @GetMapping("/user/{id}")
    	public ResponseEntity<User> getUserById(@PathVariable Long id) {
    		Optional<User> user = userService.findUserById(id);
    		if (user.isPresent()) {
    			return ResponseEntity.ok(user.get());
    		}
    		return ResponseEntity.notFound().build();
    	}
    Mais c'est pas ce que je recherche.

  4. #4
    Membre chevronné
    Homme Profil pro
    Architecte technique
    Inscrit en
    Mai 2020
    Messages
    338
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Belgique

    Informations professionnelles :
    Activité : Architecte technique

    Informations forums :
    Inscription : Mai 2020
    Messages : 338
    Par défaut
    Mais si userService.findUserById(id) retourne déjà un Optional<User>, pourquoi encore le mettre dans un Optional ?

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
     
    userService.findUserById(id)
    .map( user -> ResponseEntity.ok(user)) // == .map(ResponseEntity::ok)
    .orElseGet( () -> ResponseEntity.notFound().build() );
    Edit Si votre userService.findUserById peux retourner un null le mieux serait de corriger ça. Sinon il faut utiliser Optional.flatMap
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
     
    Optional.ofNullable( userService.findUserById(id) )
                    .flatMap( opt -> opt )
                    .map(ResponseEntity::ok)
                    .orElseGet(()->ResponseEntity.notFound().build());

  5. #5
    Membre confirmé Avatar de Badshade23
    Homme Profil pro
    Développeur Java
    Inscrit en
    Décembre 2014
    Messages
    203
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Développeur Java

    Informations forums :
    Inscription : Décembre 2014
    Messages : 203
    Par défaut
    Citation Envoyé par gervais.b Voir le message

    Edit Si votre userService.findUserById peux retourner un null le mieux serait de corriger ça. Sinon il faut utiliser Optional.flatMap
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
     
    Optional.ofNullable( userService.findUserById(id) )
                    .flatMap( opt -> opt )
                    .map(ResponseEntity::ok)
                    .orElseGet(()->ResponseEntity.notFound().build());
    Ok merci, c'est exactement ce que je recherchais. Je ne comprend pas vraiment pour le map fait un Optional<Optional<U>> . Pour flatMap je n'y est pas pensé, je l'utilise surtout dans des streams pour récupérer tout les éléments des listes par exemple. Plus qu'a comprendre le fonctionnement ^^.

  6. #6
    Membre chevronné
    Homme Profil pro
    Architecte technique
    Inscrit en
    Mai 2020
    Messages
    338
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Belgique

    Informations professionnelles :
    Activité : Architecte technique

    Informations forums :
    Inscription : Mai 2020
    Messages : 338
    Par défaut
    Ce n'est pas le map qui produit un Optional<Optional<User>> mais c'est le Optional.ofNullable( userService.findUserById(id) ). Etant donné que votre service retourne déjà un Optional c'est comme si vous faisiez Optional.ofNullable( Optional.ofNullable(..) ) .
    `flatMap` est jsutement la pour ça, pour "merger" deux Optional en quelques sortes.

    Comme je vous le conseillais, le plus propre serait d'éviter que userService.findUserById ne puisse retourner un null. Beaucoup d'IDE et d'autres systèmes de revue de code remontent un avertissement lorsqu'ils détectent qu'un Optional peut-être null. Ils sont justement la pour éviter d'utiliser des références null.




    Pensez à marquer la discussion comme résolue si possible.

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

Discussions similaires

  1. Lister tous les enregistrés vides (not null)
    Par Kijer dans le forum SQL Procédural
    Réponses: 7
    Dernier message: 21/10/2007, 14h34
  2. [MySQL] Transformer des champs vides en NULL
    Par Odomat dans le forum PHP & Base de données
    Réponses: 11
    Dernier message: 08/03/2007, 17h42
  3. [INSERT / UPDATE] Remplacer une valeur vide par NULL
    Par jissay dans le forum SQL Procédural
    Réponses: 4
    Dernier message: 28/09/2006, 14h15
  4. [V10/XE] chaine vides vs nulles :cry:
    Par 250rgv dans le forum Oracle
    Réponses: 5
    Dernier message: 25/08/2006, 09h32
  5. [8i]Chaine vide et NULL
    Par payenneville dans le forum Oracle
    Réponses: 10
    Dernier message: 26/01/2006, 18h55

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