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

Android Studio Java Discussion :

Problème Android studio / org.apache.xerces / web service / Tomcat 9


Sujet :

Android Studio Java

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre confirmé
    Profil pro
    Inscrit en
    Août 2007
    Messages
    66
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Août 2007
    Messages : 66
    Par défaut Problème Android studio / org.apache.xerces / web service / Tomcat 9
    Bonjour à tous

    Je suis en train de créer une application sur Android qui se connecte à un web service JSON / REST sur un serveur Tomcat 9. J'utilise JEE8.
    Le service web qui est sur le serveur Tomcat 9 va ensuite mettre à jour des lignes dans des tables d'une base de données d'un serveur MySQL 5.7.
    Tout est en local sur ma machine de développement.

    J'ai tout d'abord codé le service web qui communique avec la base de données sous Eclipse Oxygen sous forme d'un 'Dynamic Web Project'.
    Après avoir inclut les jars nécessaire dans la librairie du WEB-INF, j'ai testé et tout se passe bien : le service web est accessible et met à jour la base de données.

    Ensuite, il m'a fallut créer l'application Android. J'ai donc créé un projet Android Studio 3.0.1.
    Pour plus de sûreté, j'ai inclus comme librairies tous les jars que j'avais dans le répertoire "lib" du dossier "WEB-INF" de mon service web de manière à ne pas avoir de "classNotFound" ...
    Les librairies qui commencent par une majuscules sont les miennes dont j'ai besoin pour assurer le fonctionnel de l'appli.

    Nom : JARS.png
Affichages : 438
Taille : 17,8 Ko

    Désormais lorsque je lance mon appli et que je teste un appel à mon web service sous Apache 9, j'ai une exception qui se produit :

    E/AndroidRuntime: Caused by: java.lang.ClassNotFoundException: Didn't find class "org.apache.xerces.jaxp.datatype.DatatypeFactoryImpl" on path: DexPathList[[....
    Nom : NOT_FOUND.png
Affichages : 475
Taille : 107,7 Ko

    J'ai été étonné car je n'avais pas besoin de ce Xercès lorsque je faisais mes tests sous Eclipse ...
    J’imaginais naïvement qu'il me fallait importer une librairie de plus dans mon dossier "lib" : j'ai donc ajouté xercesImpl-2.0.0.jar.

    Nom : XERCES.png
Affichages : 418
Taille : 19,4 Ko

    Seulement, en compilant mon projet et bien avant de lancer l’exécution j'obtiens une erreur :

    Nom : GRADDLE.png
Affichages : 415
Taille : 41,3 Ko

    Je suis donc bloqué : si je ne met pas le jar Xerces ça plante parce qu'il n'est pas là, si je met le jar Xerces ça plante parce qu'il ne peut pas compiler ...
    J'ai tenté d'ajouter la ligne multiDexEnabled true dans le fichier graddle mais sans succès ...

    Là j'avoue que je suis coincé et je suis loin d'être un expert en Android ...

    Quelqu’un a t il fait face à ce problème et a trouvé une solution ?

    Merci de votre aide.

  2. #2
    Modérateur
    Avatar de grunk
    Homme Profil pro
    Lead dév - Architecte
    Inscrit en
    Août 2003
    Messages
    6 693
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 41
    Localisation : France, Côte d'Or (Bourgogne)

    Informations professionnelles :
    Activité : Lead dév - Architecte
    Secteur : Industrie

    Informations forums :
    Inscription : Août 2003
    Messages : 6 693
    Par défaut
    Le but c'est quoi ?

    1- consommer un webservice depuis ton appli android ?
    ou
    2- avoir un serveur web sur ton appli qui expose un webservice ?

    Si la réponse est 1 , tu peux supprimer toutes tes lib , elle ne servent à rien. Il suffit d'utiliser HttpURLConnection (out tout autre client http) pour faire des requêtes sur ton webservice.
    Si la réponse est 2 , je doute que l'ensemble de tes lib soient compatible android , puisque toute l'api java n'est pas disponible.
    Pry Framework php5 | N'oubliez pas de consulter les FAQ Java et les cours et tutoriels Java

  3. #3
    Membre confirmé
    Profil pro
    Inscrit en
    Août 2007
    Messages
    66
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Août 2007
    Messages : 66
    Par défaut
    Bonjour,

    Merci de votre aide : j'avais peur d'être tout seul dans le noir

    Tout d'abord, l'appli sur Android doit en fait consommer des méthodes d'un classe montée en service qui est située sur un serveur Tomcat 9.
    Pour l'instant ce serveur web est sur la même machine que mon émulateur Android d'où je fais les tests.
    Cependant, c'est plus que simplement consommer un service, c'est aussi récupérer des objets à travers une déserialisation JSON.

    Je m'explique.

    Par exemple, j'ai une méthode de ma classe de service qui sert à l'enregistrement de nouveaux profils. Mon application Android doit transmettre au service des paramètres (par exemple nom et prénom) et en échange, le service lui envoi une instance d'un classe (par exemple Profil). C'est pour cela que j'avais imaginé que je pourrais avoir besoin de Jersey/Jackson coté client pour assurer la déserialisation et obtenit mon objet (que j'exploite ensuite dans l'appli Android).

    Je sais pas si HttpURLConnection pourrait faire cela. J'avoue que je suis novice en Android

    Merci de votre aide.

  4. #4
    Modérateur
    Avatar de grunk
    Homme Profil pro
    Lead dév - Architecte
    Inscrit en
    Août 2003
    Messages
    6 693
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 41
    Localisation : France, Côte d'Or (Bourgogne)

    Informations professionnelles :
    Activité : Lead dév - Architecte
    Secteur : Industrie

    Informations forums :
    Inscription : Août 2003
    Messages : 6 693
    Par défaut
    Citation Envoyé par XAMLdev Voir le message
    Cependant, c'est plus que simplement consommer un service, c'est aussi récupérer des objets à travers une déserialisation JSON.
    Non c'est exactement consommer un webservice .

    - Tu fais une requête HTTP via un client HTTP (par défaut HttpURLConnection est disponible , mais tu peux en installer un autre si ca te chante)
    - Cette requête te retourne un JSON qu'il faut ensuite parser.
    => Tu peux faire ca manuellement avec les classes dédiées à la manipulation json
    => Ou via un parser comme , gson, jackson, etc ...

    Donc très clairement tout tes jars ne servent strictement à rien.

    De plus quand c'est possible , on ajoute les dépendance via le fichier gradle et non directement des jar.
    Pour jackson ca va ressembler a quelque chose comme :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    implementation 'com.fasterxml.jackson.core:jackson-core:2.9.4'
    implementation 'com.fasterxml.jackson.core:jackson-annotations:2.9.4'
    implementation 'com.fasterxml.jackson.core:jackson-databind:2.9.4'
    Tu peux également utiliser retrofit qui est une lib qui gère la communication avec les webservice de bout en bout.
    Pry Framework php5 | N'oubliez pas de consulter les FAQ Java et les cours et tutoriels Java

  5. #5
    Membre confirmé
    Profil pro
    Inscrit en
    Août 2007
    Messages
    66
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Août 2007
    Messages : 66
    Par défaut
    Bonjour,

    J'ai suivit vos conseils : j'ai utilisé les objets de HttpURLConnection qui sont disponibles dans le package java.net.

    J'ai utilisé les trois packages de Jackson (bind, code et annotations).

    Pour ceux qui suivent cette conversation ils sont ici : https://github.com/FasterXML/jackson.

    Je teste tout d'abord mon code dans Eclipse plus facile à faire tourner qu'Android Studio et l'émulateur.

    J'ai réussit à passer des paramètres simples (des String) au service qui m'a renvoyé des sérialisations JSON d'instances d'objets.

    Grace à l'objet ObjectMapper de Jackson comme suit :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
     
     
    ObjectMapper objectMapper =  new ObjectMapper();
     
    MaClasse monInstance = objectMapper.readValue(jsonString, MaClasse.class);
    jsonString est une String obtenue après l’exécution d'une connexion HttpURLConnection.

    J'ai cependant un soucis pour la dernière méthode de mon service plus complexe.

    Comme j'ai changé de technologie, je ne sais pas faire ce qui se faisait avant.

    Je m'explique :

    Avant pour appeler la dernière méthode de mon service, j'utilisais le client Jersey comme suit :

    Dans le code de mon client console Java :

    Comme import :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
     
    import javax.ws.rs.client.Client;
    import javax.ws.rs.client.ClientBuilder;
    import javax.ws.rs.client.Entity;
    import javax.ws.rs.core.Form;
    import javax.ws.rs.core.GenericType;
    import javax.ws.rs.core.MediaType;
    Comme code :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
     
    TypeDeMaClasseDeRetour objet =  
    		_client
    		.target("URL de mon service")
    		  .path("Nom de la méthode de mon service")
    		  .queryParam("Nom du paramètre 1", "Valeur du paramètre 1")
    		  .queryParam("Nom du paramètre 2", "Valeur du paramètre 2")
    		  .request(MediaType.APPLICATION_JSON)
    		  .post( Entity.entity(list, MediaType.APPLICATION_JSON), TypeDeMaClasseDeRetour.class);
    Avec list : une classe POJO de type MaListe contenant une liste d'objets et quelques propriétés ...
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
     
    public class MaListe 
    {
    	private List<MonType> _list;
     
    	.....
    }
    Dans le code de mon service :

    La méthode appellée par le code précedent etait comme suit :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
     
    	@SuppressWarnings("finally")
    	@POST
    	@Path("/add")
    	@Produces(MediaType.APPLICATION_JSON)
    	@Consumes(MediaType.APPLICATION_JSON)	
    	public TypeDeMaClasseDeRetour add (MaListe list, @QueryParam("Nom du paramètre 1")  String param1, @QueryParam("Nom du paramètre 2") String param2)
    	{	
    		.....	  
     
    	}
    Ça fonctionnait bien sous Eclipse /Java.

    Désormais ça fonctionne plus du tout.

    J'utilise un code trouvé sur stackOverflow pour HttpURLConnection (parce que je connaissais pas) ici : https://stackoverflow.com/questions/...ver-in-android

    En gros, le code construit un chaîne avec les paramètres (clé / valeur) comme cela :
    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
     
    _parametersBuffer.setLength(0);
     
    int i = 0;
     
    for (String key : params.keySet()) 
    {
    	try 
    	{
    		if (i != 0)
    		{
    			_parametersBuffer.append("&");
    		}
     
    		_parametersBuffer.append(key).append("=").append(URLEncoder.encode(params.get(key), CHARSET));
     
    	} 
    	catch (UnsupportedEncodingException e) 
    	{
    		e.printStackTrace();
    	}
     
    	i++;
    }
    On obtient des String du genre mail=max%40max.com&nickname=Max

    Puis fait un POST comme cela :
    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
     
     try 
     {
    	 _urlObj = new URL(url);
     
    	 _connection = (HttpURLConnection) _urlObj.openConnection();
    	 _connection.setDoOutput(true);
    	 _connection.setRequestMethod("POST");
    	 _connection.setRequestProperty("Accept-Charset", CHARSET);
    	 _connection.setReadTimeout(READ_TIME_OUT);
    	 _connection.setConnectTimeout(CONNECTION_TIME_OUT);
    	 _connection.connect();
     
    	 _wr = new DataOutputStream(_connection.getOutputStream());
    	 _wr.writeBytes(_parametersBuffer != null ?_parametersBuffer.toString(): null);
     
    	 _wr.flush();
    	 _wr.close();
     
     } 
     catch (IOException e) 
     {
    	 e.printStackTrace();
     }
    D'abord dans la déclaration de mon service, je n'ai pas nommé le paramètre liste de type MaListe :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    @SuppressWarnings("finally")
    @POST
    @Path("/add")
    @Produces(MediaType.APPLICATION_JSON)
    @Consumes(MediaType.APPLICATION_JSON)	
    public TypeDeMaClasseDeRetour add (MaListe list, @QueryParam("Nom du paramètre 1")  String param1, @QueryParam("Nom du paramètre 2") String param2)
    {	
    	.....	  
    	
    }
    Les annotations sont soit @QueryParam("Nom du paramètre") ou @FormParam("Nom du paramètre"), je ne sais pas quoi prendre puisque je n'en avais pas besoin avant.

    Ensuite, quand j'appelle mon service j'obtiens une belle exception (que mon paramètre soit nommé, ou pas) :

    java.io.IOException: Server returned HTTP response code: 415 for URL: http://localhost:8080/WebServices/Service/add

    En fait, le code passe la sérialisation JSON de ma liste :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    String jsonList = objectMapper.writeValueAsString(maListe);
    qui ressemble à ça :

    {"_list":[{"_t":"Bouillon","_u":"Fr"},{"_t":"Potage","_u":"Fr"},{"_t":"Marmite","_u":"Fr"},{"_t":"Soupe","_u":"Fr"}],"last":{"_t":"Soupe","_u":"Fr"}}
    dans une chaîne plus vaste de tous les paramètres qui ressemble à ça :
    mail=max%40max.com&nickname=Max&list=%7B%22_list%22%3A%5B%7B%22_t%22%3A%22Bouillon%22%2C%22_u%22%3A%22Fr%22%7D%2C%7B%22_t%22%3A%22Potage%22%2C%22_u%22%3A%22Fr%22%7D%2C%7B%22_t%22%3A%22Marmite%22%2C%22_u%22%3A%22Fr%22%7D%2C%7B%22_t%22%3A%22Soupe%22%2C%22_u%22%3A%22Fr%22%7D%5D%2C%22last%22%3A%7B%22_t%22%3A%22Soupe%22%2C%22_u%22%3A%22Fr%22%7D%7D
    et je pense que c'est pas bon du tout .... mais je ne sais pas comment corriger.

    J'ai besoin d'une aspirine, je suis pas loin d'y arriver avec un coup de pouce

    Merci de votre aide

  6. #6
    Modérateur
    Avatar de grunk
    Homme Profil pro
    Lead dév - Architecte
    Inscrit en
    Août 2003
    Messages
    6 693
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 41
    Localisation : France, Côte d'Or (Bourgogne)

    Informations professionnelles :
    Activité : Lead dév - Architecte
    Secteur : Industrie

    Informations forums :
    Inscription : Août 2003
    Messages : 6 693
    Par défaut
    Va falloir te forcer à passer aux outils Android. C'est pas parce que tu vas tester un truc sous eclipse en desktop que ca va fonctionner sous Android.

    J'ai le sentiment que tu as mis en place un webservice sans vraiment comprendre ce que tu fais et/ou maitriser les notions de base sous jacentes (http, de/serialisation json, etc ...) du coup tu es perdu quand il sagit de consommer ce ws.

    Je connais pas Jackson , donc je pourrais pas t'aider de ce coté là.

    L'url que tu décrit à la fin de ton message c'est juste le json qui est urlencodé , c'est donc normal.
    Mais peut être que ton webservice n'attends pas le json dans des queryparam , peut être qu'il doit être dans le corps de la requête.
    Tu es le seul à savoir ce qu'attends ton ws.

    Si tu as le json , que tu es capable de construire une requete et de l'envoyer , tu as fait le plus dur.

    Il faut juste savoir :
    - La méthode de la requête (POST,GET,PUT, etc ...)
    - Les éventuels paramètres et comment les envoyer (dans l'url, ou le corps)
    - Les eventuels headers nécessaire (si le ws attends du json y'a des chances qu'il faille ajouter quelque chose comme conn.setRequestProperty("Content-Type","application/json"); )
    Pry Framework php5 | N'oubliez pas de consulter les FAQ Java et les cours et tutoriels Java

Discussions similaires

  1. Problème de connexion entre Android et MySQL via les Web Services
    Par amalmanel dans le forum API standards et tierces
    Réponses: 1
    Dernier message: 22/03/2012, 02h36
  2. Dépendance vers org.apache.xerces.
    Par yann2 dans le forum Akrogen
    Réponses: 2
    Dernier message: 14/06/2007, 10h16
  3. Où trouver le package org.apache.xerces ?
    Par Invité dans le forum Eclipse Java
    Réponses: 4
    Dernier message: 28/12/2006, 19h01
  4. Réponses: 2
    Dernier message: 21/09/2006, 17h05
  5. [SAX] Utilisation du package contenant org.apache.xerces.par
    Par Sphost dans le forum Eclipse Java
    Réponses: 1
    Dernier message: 17/01/2005, 11h07

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