Ce TD à pour but de comprendre l'intérêt de la réflexion et des annotations.
Comme pour les TPs précédents, nous allons utiliser Maven comme outil de build.
Dans ce TP, lors des tests, nous avons besoin de vérifier que le JSON produit est correct. Pour cela, nous allons utiliser la bibliothèque
jackson.
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>2.13.3</version>
<scope>test</scope>
</dependency>
Comme cette dépendance est uniquement nécessaire pour les tests, elle est déclarée avec le
scope test.
Comme précédemment, créer un projet Maven en cochant
create simple project au niveau du premier écran,
puis passer à l'écran suivant en indiquant
Next.
Pour ce TP, le groupId est
fr.uge.json , l'artefactId est
json et
la version est
0.0.1-SNAPSHOT. Pour finir, cliquer sur
Finish.
On souhaite écrire un code qui permet d'afficher un objet au format
JSON.
On suppose qu'il existe un record
fr.uge.json.Person avec un prénom
firstName et un nom
lastName :
import static java.util.Objects.requireNonNull;
public record Person(String firstName, String lastName) {
public Person {
requireNonNull(firstName);
requireNonNull(lastName);
}
}
Dans une classe
JSONPrinter, on peut alors écrire la méthode
toJSON qui prend en paramètre une
Person
et renvoie une chaîne de caractères au format
JSON :
package fr.uge.json;
public class JSONPrinter {
public static String toJSON(Person person) {
return """
{
"firstName": "%s",
"lastName": "%s"
}
""".formatted(person.firstName(), person.lastName());
}
public static void main(String[] args) {
var person = new Person("John", "Doe");
System.out.println(toJSON(person));
}
}
Supposons maintenant qu'il existe un record
fr.uge.json.Alien
avec un age
age et une planète
planet :
import static java.util.Objects.requireNonNull;
public record Alien(int age, String planet) {
public Alien {
if (age < 0) {
throw new IllegalArgumentException("negative age");
}
requireNonNull(planet);
}
}
si l'on veut aussi pouvoir afficher un
Alien au format JSON, on va écrire
une autre méthode
toJSON dans la classe
JSONPrinter :
public class JSONPrinter {
...
public static String toJSON(Alien alien) {
return """
{
"age": %s,
"planet": "%s"
}
""".formatted(alien.age(), alien.planet());
}
public static void main(String[] args) {
...
var alien = new Alien(100, "Saturn");
System.out.println(toJSON(alien));
}
}
Si l'on doit dupliquer le code de
toJSON à chaque fois que l'on veut
transformer en
JSON un nouveau record, c'est embêtant...
A kitten dies each time you duplicate a bug !
Pour éviter l'hécatombe, on se propose de modifier la classe
JSONPrinter, de commenter le code des deux méthodes
toJSON
et de les remplacer par une seule méthode
toJSON prenant un
Record en paramètre et
utilisant la réflexion (
reflection en anglais) pour trouver les composants du record à écrire au format
JSON.