Simplification des appels HTTP avec RestTemplate dans Spring

Lors de ma lecture de documents sur Spring Cloud, je suis tombé sur le composant Feign et j'ai découvert qu'il utilisait RestTemplate en interne. Cette découverte a éveillé ma curiosité et j'ai décidé d'explorer son fonctionnement interne. Quelle agréable surprise ! Je ne connaissais pas cette classe et son approche si élégante.

Autrefois, pour effectuer une requête HTTP, nous devions écrire du code assez verbeux. Voici un exemple avec OkHttpClient :

String url = "https://api.exemple.com/donnees";
OkHttpClient client = new OkHttpClient();
MediaType typeMedia = MediaType.parse("application/x-www-form-urlencoded");
Requete requete = new Requete.Builder()
    .get()
    .url(url)
    .build();

try {
    Reponse reponse = client.newCall(requete).execute();
    String donnees = reponse.body().string();
} catch (IOException e) {
    e.printStackTrace();
}

Ou une approche encore plus fastidieuse utilisant URLConnection :

PrintWriter sortie = null;
BufferedReader entree = null;
String resultat = "";

try {
    URL urlDirecte = new URL("https://api.exemple.com/donnees");
    URLConnection connexion = urlDirecte.openConnection();
    
    connexion.setRequestProperty("Content-Type", "application/x-www-form-urlencoded");
    connexion.setRequestProperty("accept", "*/*");
    connexion.setRequestProperty("connection", "Keep-Alive");
    connexion.setRequestProperty("Accept-Charset", "UTF-8");
    connexion.setRequestProperty("user-agent", "Mozilla/4.0");
    
    connexion.setDoOutput(true);
    connexion.setDoInput(true);
    
    sortie = new PrintWriter(connexion.getOutputStream());
    sortie.print(parametres);
    sortie.flush();
    
    entree = new BufferedReader(
        new InputStreamReader(connexion.getInputStream(), "utf-8"));
    
    String ligne;
    while ((ligne = entree.readLine()) != null) {
        resultat += ligne;
    }
} catch (Exception e) {
    System.out.println("Erreur lors de la requête : " + e);
    e.printStackTrace();
} finally {
    try {
        if (sortie != null) sortie.close();
        if (entree != null) entree.close();
    } catch (IOException ex) {
        ex.printStackTrace();
    }
}

Avec RestTemplate, tout devient beaucoup plus simple :

RestTemplate template = new RestTemplate();
MonDTO response = template.getForObject("https://api.exemple.com/donnees", MonDTO.class);

Pour récupérer une liste d'objets, c'est tout aussi élégant :

Personne[] tableauPersonnes = new RestTemplate()
    .getForObject("https://api.exemple.com/utilisateurs", Personne[].class);
List<Personne> listePersonnes = Arrays.asList(tableauPersonnes);

Deux lignes de code seulement ! Cette approche m'a particulièrement séduit, ayant toujours apprécier la concision du style lambda de Java 8.

Examinons maintenant l'implémentation interne. En explorent le code source, on constate que toutes les opérations passent par la méthode execute(), qui délègue elle-même à doExecute(). C'est dans cette dernière que toute la logique de traitement des requêtes HTTP est implémentée.

Voici comment effectuer une requête POST avec des données JSON :

RestTemplate restTemplate = new RestTemplate();
Map<String, Object> corpsRequete = new HashMap<>();
HttpHeaders en-tetes = new HttpHeaders();
en-tetes.setContentType(MediaType.APPLICATION_JSON);

HttpEntity<Map<String, Object>> entite = new HttpEntity<>(corpsRequete, en-tetes);
String reponseString = restTemplate.postForObject(
    "https://api.exemple.com/endpoint", 
    entite, 
    String.class);

JSONObject objetJson = JSON.parseObject(reponseString);

Comme on peut le constater, RestTemplate encapsulate toute la complexité des connexions HTTP. Cette simplicité est exactement dans l'esprit de Spring : abstracts les détails techniques fastidieux pour permettre aux développeurs de se concentrer sur la logique métier. Un code plus élégant rend également le développement plus agréable.

Étiquettes: Spring resttemplate http-client Java spring-boot

Publié le 25 juin à 03h56