TP nº5: Application REST

Objectif

L'objectif de ce TP est de développer une application cliente riche pour Twitter. En particulier, cette application utilise Swing et l'API REST de Twitter pour poster et récupérer les messages de ses contacts. Si vous n'avez pas de compte Twitter, c'est l'occasion d'en créer un sur twitter.com. Vous pouvez utiliser Netbeans pour développer cette application mais vous pouvez également utiliser Eclipse selon vos affinités (le TP a été testé sous Netbeans 6.9.1).

Définir l'interface graphique

Cette partie se concentre sur la modélisation de l'interface graphique pour l'utilisateur en utilisant Swing. Nous utilisons pour ça une JFrame, vous être libres d'organiser et d'ajouter des éléments comme vous le souhaitez:
  1. Commencez par créer un nouveau projet ("New project... > Java > Java application" sous Netbeans) que vous nommerez TwitterClient. Désactivez la création de la classe principale.
  2. Placez vous dans le nouveau projet créé. Créez un nouveau formulaire JFrame ("Nouveau > Formulaire JFrame") que nous nommerez TwitterFrame (package twitter.client).
  3. Utilisez l'éditeur graphique en vue design pour insérer les composants Swing suivants:
  • Un bouton jButton1 que vous placerez en bas à droite de la fenêtre et dont le label sera "Update".
  • Un label texte (jLabel1) en bas à gauche qui sera utilisé pour afficher l'icone de l'utilisateur. Changez LES propriétés de taille du composant en 48x48 pixels.
  • Un champ texte (jTextField1) entre les deux composants précédents qui servira à saisir le statut de l'utilisateur.
  • Un scroll pane (jScrollPane2) qui occupera toute la partie supérieure de la fenêtre.
  • Une liste (jList1) que vous insérerez dans le scroll pane.

Afficher votre statut

Il s'agit désormais de créer une méthode permettant de récupérer les informations nécessaires en utilisant la méthode Twitter getUserTimeline(). Cette méthode vous retourne votre icone utilisateur et votre statut courant et vous permettra d'alimenter les différents composants de votre interface graphique. Pour ce faire:
  1. Générez un nouveau client RESTful ("New file... > Web Services > RESTful Java Client" sous Netbeans) que vous nommerez TimelineClient. Sélectionnez la ressource [Twitter OAuth] > [statuses] > [user_timeline.{format}] et demandez à générer les objets Java à partir du fichier WADL importé.
  2. Basculez dans la vue source de l'éditeur et ajoutez une nouvelle méthode initUserInfo(). Appelez cette méthode à la fin du constructeur de la classe.
  3. Complétez le code généré pour mettre à jour les composants Swing avec les données retournées par la méthode getUserTimeline() après avoir invoqué les méthodes login() et initOAuth().

Récupérer les clés d'authentification pour Twitter

  1. Pour pouvoir invoquer les services REST de Twitter, il est nécessaire de s'authentifier en utilisant la méthode OAuth et en récupérant les clés CUSTOMER et CUSTOMER_SECRET. Il donc nécessaire d'enregistrer une application dans Twitter pour pouvoir récupérer ces clés:
  2. Connectez vous avec votre compte Twitter et créez une nouvelle application (http://twitter.com/apps/new) en renseignant les différents champs et en prenant soin de spécifier qu'il s'agit d'une application cliente qui bénéficie d'un accès lecture/écriture.
  3. Copiez la valeur des clés récupérés dans les attributs de la classe TimelineClient prévus pour ça.

Exécuter l'application cliente

  1. Compilez et exécuter l'application (n'oubliez pas les propriétés -Dhttp.proxyHost=server et -Dhttp.proxyPort=port pour le proxy).
  2. Une fenêtre de navigateur va s'ouvrir pour vous demander l'autorisation d'accéder aux donner. Cliquez sur autoriser.
  3. La fenêtre va alors afficher un code PIN que vous allez copier et coller dans la console de Netbeans.
  4. Votre application cliente doit désormais s'afficher.

Appeler plusieurs services.

Nous allons maintenant développer une version plus aboutie du client Twitter qui va notamment utiliser plusieurs ressources, à savoir : user_timeline.{format}, update.{format} et friends_timeline.{format}. Les appels à ces services doivent donc partager le même client pour utiliser une authentification unique:
  1. Dans un premier temps, générez deux classes clientes pour accéder aux ressources update.{format} et friends_timeline.{format}.
  2. Copiez ensuite les méthodes getFriendsTimeline() et updateStatus() générées pour ces deux nouvelles classe dans la classe du client TimelineClient (que vous pouvez renommer au passage en RESTfulClient).
  3. Supprimez le paramètre du constructeur de la classe RESTfulClient et affectez la valeur "statuses" à la variable resourcePath du constructeur. Supprimez également le paramètre lors de l'appel au constructeur dans la méthode initUserInfo().
  4. Dans la méthode getUserTimeline(), insérez l'appel à la méthode path("user_timeline.xml") avant l'appel à webResource.queryParams(...).
  5. Faîtes de même avec les méthodes getFriendsTimeline() et updateStatus().
  6. Par précaution, commentez la méthode setResourcePath(...)
  7. Supprimer les deux classes que vous avez générées et qui sont désormais inutiles.

Ajouter une action de mise-à-jour

Dans la vue design, double-cliquez sur le bouton Update. L'éditeur bascule alors en mode source dans le corps de la méthode jButton1ActionPerformed(...) dont vous devez implanter le comportement en utilisant le code suivant:

clt.makeOAuthRequestUnique();
try {
    String status = URLEncoder.encode(jTextField1.getText().trim(), "UTF-8");
    clt.updateStatus(String.class, status, null);
} catch(UniformInterfaceException ex) {
    System.out.println("Exception when calling updateStatus = " + ex.getResponse().getEntity(String.class));
} catch (UnsupportedEncodingException ex) {
    Logger.getLogger(TwitterFrame.class.getName()).log(Level.SEVERE, null, ex);
}


Afficher le nom et le statut des amis

Pour mettre à jour le statut des amis, il est nécessaire d'utiliser une activité périodique qui rafraichira la fenêtre avec les nouvelles informations:
Dans un premier temps, ajoutez le code suivant avant l'appel à la méthode initComponents() de la fenêtre principale:

Timer t = new Timer("Twitter Updater`", false);
t.scheduleAtFixedRate(new TimerTask() {
        @Override public void run() {
    }    }, 1500, 75000);


Ensuite, pour afficher la liste des statuts dans la fenêtre graphique, il est nécessaire d'utiliser un objet de type
DefaultListModel que vous devez déclarer comme un attribut de la classe. Insérez le code suivant dans le corps de la méthode run():

try {
    clt.initOAuth();
    Statuses response = clt.getFriendsTimeline(Statuses.class, null, null, null, "10");
    statusesListModel.clear();
    for (final StatusType st : response.getStatus()) {
        SwingUtilities.invokeLater(new Runnable() {
            public void run() {
                statusesListModel.addElement(st);
        }    });
    }
} catch (UniformInterfaceException ex) {
    System.out.println("Exception when calling getFriendsTimeline = " + ex.getResponse().getEntity(String.class));
}


Le modèle est désormais régulièrement mis-à-jour à partir des données retournées par la méthode
getFriendsTimeline(). La prochaine étape consiste donc à rafraichir la fenêtre avec ces nouvelles données:

Créez ensuite un nouveau formulaire JPanel que vous nommerez
Item. ajoutez-y un label et un text pane pour décrire les informations que nous afficherons à partir du modèle. Basculez dans le mode source pour que la classe Item implante l'interface ListCellRenderer. et ajouter le code suivant dans le corps de la méthode getListCellRendererComponent():

StatusType st = (StatusType) value;
jTextPane1.setText(st.getText());
jLabel1.setText("<html>" + st.getUser().getScreenName() + "</html>");
return this;


Revenez sur la fenêtre principale de votre client Twitter et spécifiez que le modèle de votre JList est le code statusesListModel, spécifiez également que le cellRenderer à utiliser est un "new Item()".

Vous pouvez de nouveau lancer votre application, les statuts doivent désormais se mettre à jour automatiquement.