:: Enseignements :: ESIPE :: E4INFO :: 2015-2016 :: Java Avancé ::
[LOGO]

JSON, reflection et annotations


Ce TD à pour but de comprendre l'intérêt de la reflection et des annotations.

Exercice 1 - JSON Encoder

On souhaite écrire un code qui permet d'afficher un objet au format JSON.
Par exemple pour la classe Person

On peut écrire la méthode toJSON qui prend en paramètre une Person et renvoie une chaine de caractères au format JSON.

Mais si l'on doit dupliquer le code de toJSON à chaque fois que l'on veut transformer en JSON une nouvelle classe, c'est tout de suite moins drole.
A kitten die each time you duplicate a bug !
Pour éviter l'hécatombe, on se propose d'écrire une seule méthode toJSON prenant un Object en paramètre et utilisant la reflection pour trouver les propriétés à écrire au format JSON

  1. Ecrire une méthode toJSON qui prend en paramètre un Object, utilise la reflection pour accéder à l'ensemble des méthodes publiques de la classe de l'objet (java.lang.Class.getMethods), sélectionne les getters, puis affiche les couples nom de propriété, valeur associé.
    Le nom d'une propriété s'obtient à partir du nom du getter en utilisant la fonction suivante
         private static String propertyName(String name) {
           return Character.toLowerCase(name.charAt(3)) + name.substring(4);
         }
        

    Note: il est possible d'écrire la méthode en utilisant un Stream.
    Note2: faites attention à gérer correctement les exceptions lors de l'invocation de méthode (surtout InvocationTargetException).
  2. En fait, la méthode précédente n'affiche pas uniquement le résultat de getFirstName et getLastName car getClass commence aussi par le préfix "get". Il faut donc marquer les méthodes qui feront partie de l'affichage JSON. On se propose d'utiliser une annotation pour cela.
    Déclarez l'annotation JSONProperty visible à l'exécution et permettant d'annoter des méthodes puis modifiez le code de toJSON pour n'utiliser que les propriétés issues de méthodes marquées par l'annotation JSONProperty.
  3. En fait, une propriété JSON peut contenir des caractères comme le '-' qui ne sont pas des caractères valide en tant que nom de méthode Java.
    Faites en sorte que l'on puisse utiliser l'annotation JSONProperty sans rien et dans ce cas le nom de la méthode sera utilisée mais que l'on puisse aussi utiliser l'annotation JSONProperty avec un nom. Ce nom sera alors utilisé au lieu du nom de la méthode.
    Rappel: la valeur d'un attribut d'une annotation ne peut pas être null.
  4. En fait, l'appel getMethods est lent, regardez la signature de cette méthode et la méthode java.lang.reflect.Method.setAccessible() et indiquez pourquoi l'appel ne peut pas être accéléré.
  5. Nous allons donc limiter les appels à getMethods en stockant le résultat de getMethods dans un cache pour éviter l'appel à chaque fois.
    Uitlisez la classe java.lang.ClassValue pour cacher le résultat d'un appel à getMethods pour une classe donnée.
  6. En fait, on peut cacher plus d'informations que juste les méthodes, on peut aussi pré-calculer le nom des propriétés pour éviter d'accéder aux annotations à chaque appel.
    Ecrire le code qui pré-calcule le maximum de chose pour que l'appel à toJSON soit le plus efficace possible.
    Indication: lettre grecque entre kappa et mu.