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

Spring Java Discussion :

[REST API] - Json de retour non valide


Sujet :

Spring Java

  1. #1
    Membre du Club
    Homme Profil pro
    Alternance
    Inscrit en
    Février 2019
    Messages
    59
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Bas Rhin (Alsace)

    Informations professionnelles :
    Activité : Alternance
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Février 2019
    Messages : 59
    Points : 46
    Points
    46
    Par défaut [REST API] - Json de retour non valide
    Bonjour,

    Je suis entrain de faire une application JAVA avec une API Rest et je rencontre un petit problème.

    Le JSON de mon API n'est pas valide...
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    [
        [
            1,
            "FRJEADUP",
            "Jean",
            "DUPOND"
        ]
    ]
    Je ne comprend pas vraiment pourquoi et comment cela se fait... si quelqu'un aurai une réponse ?

    PS : J'utilise une architecture en oignon avec du CQRS et des ValueObjects.

    Voici tout mon code :

    CustomerController
    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
    @CrossOrigin("*")
    @RestController
    public class CustomerController {
     
        @Autowired
        private CustomerRepository repository;
     
        @ResponseBody
        @GetMapping(path = "/GetCustomers", produces = "application/json")
        public ResponseEntity<List<Customer>> getCustomers() {
            var GetAllCustomers = new GetAllCustomers(repository);
            return ResponseEntity.ok(GetAllCustomers.Do());
        }
     
    }
    ICustomerRepository
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    public interface ICustomerRepository {
     
        List<Customer> GetAll();
     
        void Add(Customer customer);
    }
    GetAllCustomers
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    public class GetAllCustomers {
     
        private ICustomerRepository _Repository;
     
        public GetAllCustomers(ICustomerRepository Repository) {
            _Repository = Repository;
        }
     
        public List<Customer> Do() {
            return _Repository.GetAll();
        }
    }
    CustomerRepository
    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
    @Repository
    public class CustomerRepository implements ICustomerRepository {
     
        @Autowired
        EntityManager entityManager;
     
        @SuppressWarnings("unchecked")
        @Override
        public List<Customer> GetAll() {
            try {
                String SQL = "SELECT ID, LOGIN, FOR_NAME, LAST_NAME FROM CUSTOMER";
                Query query = entityManager.createNativeQuery(SQL);
     
                List<Customer> customers = query.getResultList();
     
                return customers;
            } catch (NoResultException e) {
                return null;
            }
     
        }
    }
    Customer
    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
    private int _ID;
     
        private Login _Login;
     
        private ForName _ForName;
     
        private LastName _LastName;
     
        public Customer(Login Login, ForName ForName, LastName LastName) {
            _Login = Login;
            _ForName = ForName;
            _LastName = LastName;
        }
     
        public Customer(int ID, Login Login, ForName ForName, LastName LastName) {
            _ID = ID;
            _Login = Login;
            _ForName = ForName;
            _LastName = LastName;
        }
     
        public int getID() {
            return _ID;
        }
     
        public String getLogin() {
            return _Login.getValue();
        }
     
        public String getForName() {
            return _ForName.getValue();
        }
     
        public String getLastName() {
            return _LastName.getValue();
        }
     
        @Override
        public String toString() {
            return getID() + " " + getLogin() + " " + getForName() + " " + getLastName();
        }
    Login
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    public class Login {
     
        private String _Value;
     
        public Login(String Value) {
            _Value = Value;
        }
     
        public String getValue() {
            return _Value;
        }
    }
    ForName
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    public class ForName {
     
        private String _Value;
     
        public ForName(String Value) {
            _Value = Value;
        }
     
        public String getValue() {
            return _Value;
        }
    }
    LastName
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    public class LastName {
     
        private String _Value;
     
        public LastName(String Value) {
            _Value = Value;
        }
     
        public String getValue() {
            return _Value;
        }
    }
    Je sais qu'il y a beaucoup de classe et que ce n'est pas forcement simple à comprendre du premier regard..

    En espérant que quelqu'un pourra m'aider.

    WiZarD67

  2. #2
    Membre confirmé Avatar de licardentaistor
    Homme Profil pro
    Administrateur de base de données
    Inscrit en
    Juillet 2021
    Messages
    345
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Manche (Basse Normandie)

    Informations professionnelles :
    Activité : Administrateur de base de données

    Informations forums :
    Inscription : Juillet 2021
    Messages : 345
    Points : 495
    Points
    495
    Par défaut
    c'est un JSON valide ... https://jsonformatter.curiousconcept.com/#

    je ne vois pas où est le pb?

  3. #3
    Expert confirmé
    Homme Profil pro
    Inscrit en
    Septembre 2006
    Messages
    2 960
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Belgique

    Informations forums :
    Inscription : Septembre 2006
    Messages : 2 960
    Points : 4 389
    Points
    4 389
    Par défaut
    Citation Envoyé par licardentaistor Voir le message
    c'est un JSON valide ... https://jsonformatter.curiousconcept.com/#

    je ne vois pas où est le pb?
    Dans l'absolu, oui c'est du JSON...
    Mais si la liste est censée représenter une List<Customer>, pas nécessairement...
    cela pourrait être une array d'objets:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    [
    {
     "id" : 1,
     "login" : "FRJEADUP",
     "for_name" : "Jean",
     "last_name" : "DUPOND"
    }
    ]
    Donc le problème est plutôt les conventions entre le client et le serveur…

  4. #4
    Membre du Club
    Homme Profil pro
    Alternance
    Inscrit en
    Février 2019
    Messages
    59
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Bas Rhin (Alsace)

    Informations professionnelles :
    Activité : Alternance
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Février 2019
    Messages : 59
    Points : 46
    Points
    46
    Par défaut
    C'est bien ce type de JSON que je voudrai

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    [
        {
             "id" : 1,
             "login" : "FRJEADUP",
             "for_name" : "Jean",
             "last_name" : "DUPOND"
        }
    ]
    Si le problème vient d'une mauvaise conversion entre le serveur et le client il y a une solution ?

    Ou en vue de ce que je viens d'écrire il faut que je change mon format de retour ?

  5. #5
    Expert confirmé
    Homme Profil pro
    Inscrit en
    Septembre 2006
    Messages
    2 960
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Belgique

    Informations forums :
    Inscription : Septembre 2006
    Messages : 2 960
    Points : 4 389
    Points
    4 389
    Par défaut
    Citation Envoyé par WiZarD67 Voir le message
    Si le problème vient d'une mauvaise conversion entre le serveur et le client il y a une solution ?

    Ou en vue de ce que je viens d'écrire il faut que je change mon format de retour ?
    Justement : normalement avec Spring c'est automatique pour peu que les bons JAR soient dans le class path et que l'application context et le Java respectent les conventions...

    Or côté Java cela me semble OK : @RestController qui retourne un @ResponseBody et produces = "application/json"...
    reste à vérifier le reste...


  6. #6
    Membre du Club
    Homme Profil pro
    Alternance
    Inscrit en
    Février 2019
    Messages
    59
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Bas Rhin (Alsace)

    Informations professionnelles :
    Activité : Alternance
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Février 2019
    Messages : 59
    Points : 46
    Points
    46
    Par défaut
    Je viens d'essayer avec une List instancié dans mon End point et tout fonctionne correctement

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    @GetMapping(path = "/GetCustomer", produces = "application/json")
        @ResponseBody
        public ResponseEntity<List<Customer>> getCustomer() {
            List<Customer> ls = new ArrayList<Customer>();
            ls.add(new Customer(new Random().nextInt(), new Login("FRJEADUP"), new ForName("Jean"), new LastName("Dupond")));
            ls.add(new Customer(new Random().nextInt(), new Login("FRJEADUP"), new ForName("Jean"), new LastName("Dupond")));
            ls.add(new Customer(new Random().nextInt(), new Login("FRJEADUP"), new ForName("Jean"), new LastName("Dupond")));
            return ResponseEntity.ok(ls);
        }
    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
    [
        {
            "id": -122011726,
            "lastName": "Dupond",
            "login": "FRJEADUP",
            "forName": "Jean"
        },
        {
            "id": -1732593737,
            "lastName": "Dupond",
            "login": "FRJEADUP",
            "forName": "Jean"
        },
        {
            "id": 1721364557,
            "lastName": "Dupond",
            "login": "FRJEADUP",
            "forName": "Jean"
        }
    ]
    Je pense que ça doit venir de mon Repository... à ce niveau la

    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
    @SuppressWarnings("unchecked")
        @Override
        public List<Customer> GetAll() {
            try {
                String SQL = "SELECT ID, LOGIN, FOR_NAME, LAST_NAME FROM CUSTOMER";
                Query query = entityManager.createNativeQuery(SQL);
     
                List<Customer> customers = query.getResultList();
     
                return customers;
            } catch (NoResultException e) {
                return null;
            }
     
        }

  7. #7
    Expert confirmé
    Homme Profil pro
    Inscrit en
    Septembre 2006
    Messages
    2 960
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Belgique

    Informations forums :
    Inscription : Septembre 2006
    Messages : 2 960
    Points : 4 389
    Points
    4 389
    Par défaut
    Citation Envoyé par WiZarD67 Voir le message
    Je pense que ça doit venir de mon Repository... à ce niveau la

    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
    @SuppressWarnings("unchecked")
        @Override
        public List<Customer> GetAll() {
            try {
                String SQL = "SELECT ID, LOGIN, FOR_NAME, LAST_NAME FROM CUSTOMER";
                Query query = entityManager.createNativeQuery(SQL);
     
                List<Customer> customers = query.getResultList();
     
                return customers;
            } catch (NoResultException e) {
                return null;
            }
     
        }
    En effet : query.getResultList() d'un native query renvoit une liste d'Object...
    ce n'est pas un TypeQuery de JPA que vous invoquez... donc vous devez faire la conversion vous-même ou spécifier un mapping ou une Class dans createNativeQuery.

    Notez que si vous spécifiez une Class, il faut que le constructor correspondant aux types d'object de la List<Object> existe... donc dans votre cas un constructor (Integer, String, String, String).
    Et si votre classe Customer est votre objet métier (@Entity), vous risquez des problèmes de validation des champs que vous n'initialisez pas... c'est pour cela qu'en général on utilise une classe spécifique (un DTO).

  8. #8
    Membre du Club
    Homme Profil pro
    Alternance
    Inscrit en
    Février 2019
    Messages
    59
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Bas Rhin (Alsace)

    Informations professionnelles :
    Activité : Alternance
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Février 2019
    Messages : 59
    Points : 46
    Points
    46
    Par défaut
    En cherchant j'ai trouvé ce qui bloqué.

    Pour ceux qui veulent :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    @Override
        public List<Customer> GetAll() {
            String SQL = "SELECT * FROM CUSTOMER";
            Query query = entityManager.createNativeQuery(SQL, CustomerEntity.class);
     
            List<CustomerEntity> customersEntities = query.getResultList();
     
            List<Customer> customers = customersEntities.stream().map(x -> x.ToDomainEntity()).collect(Collectors.toList());
     
            return customers;
     
        }
    La méthode ToDomainEntity convertie mes objets JPA en entité métier.

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

Discussions similaires

  1. HExécuteRequêteSQL - Retour non valide
    Par WiZarD67 dans le forum HyperFileSQL
    Réponses: 7
    Dernier message: 01/02/2022, 15h30
  2. [X3-V7] Gestion des retours non validé : réintégration
    Par leloup84 dans le forum SAGE
    Réponses: 2
    Dernier message: 26/05/2020, 15h06
  3. REST API + JSON
    Par Herve_be dans le forum VB 6 et antérieur
    Réponses: 0
    Dernier message: 16/12/2017, 17h21
  4. REST API JSON to SyncAdapter AbstractThreadedSyncAdapter
    Par andronull dans le forum Android
    Réponses: 1
    Dernier message: 27/02/2014, 20h14
  5. [Débutant] WEB API et mauvais retour JSON
    Par scude dans le forum Services Web
    Réponses: 2
    Dernier message: 27/01/2013, 19h43

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