devstory

Exemple Spring Boot Restful Client avec RestTemplate

1- Objectif de l'exemple

Le document est basé sur :
  • Spring Boot 2.x

  • RestTemplate

  • Eclipse 3.7

Dans cette publiection, je vous donnerai des instructions de la création d'une application Restful Client à l'adie de Spring Boot. Avec les 4 fonctions :
  1. Créer une requête avec la méthode GET, et l'envoyer au Restful Web Service pour obtenir une liste des employés (employee), ou l'information d'un employé. Les données recues sont sous forme de XML ou JSON.
  2. Créer une requête avec la méthode PUT, et l'envoyer au Restful Web Service afin de modifier l'information d'un employé. Les données attchées sont sous format de XML ou JSON.
  3. ​​​​​​​Créer une requête avec la méthode POST, et l'envoyer au Restful Web Service pour créer un nouvel employé. Les données attchées sont sous format de XML ou JSON.
  4. Créer une requête avec la méthode DELETE, et l'envoyer au Restful Web Service afin de supprimer un employé.
Cet article utilise le Restful Web Service créé dans l'exemple ci-dessous :
La classe RestTemplate est la classe principale du Spring Framework cho các cuộc gọi đồng bộ (synchronous calls) bởi Client để truy cập vào RESTful Web Service. Lớp này cung cấp các chức năng để tiêu thụ REST Services một cách dễ dàng. Khi sử dụng lớp nói trên, người dùng chỉ phải cung cấp URL, các tham số (nếu có) và trích xuất các kết quả nhận được. RestTemplate quản lý các kết nối HTTP (HTTP Connection).

2- Créer le projet Spring Boot

Sur Eclipse, créez un projet Spring Boot.
OK, le projet a été créé.

3- Configurer le fichier pom.xml

Ce projet a besoin d'utiliser des bibliothèques Spring Restful Client. Par conséquent, vous avez deux choix :
  1. spring-boot-starter-web
  2. spring-boot-starter-data-rest

spring-boot-starter-web

spring-boot-starter-web comprend des bibliothèques pour construire une application web à l'aide de Spring MVC, en utilisant tomcat comme un Web Container par défaut dans lequel il est enfoncé (embedded). Il contient des bibliothèques de l'application RESTful.
spring-boot-starter-web
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-web</artifactId>
</dependency>

spring-boot-starter-data-rest

spring-boot-starter-data-rest comprend des bibliothèques pour travailler avec Spring RESTful.
spring-boot-starter-data-rest
<!-- https://mvnrepository.com/artifact/org.springframework.boot/spring-boot-starter-data-rest -->
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-data-rest</artifactId>            
</dependency>

Java <==> JSON

Tous les deux "Starter" ci-dessus comprennent une bibliothèque jackson-databind qui fournit la conversion d'un objet Java en JSON et vice versa.

Java <==> XML

Spring utilise JAXB (Disponible dans JDK) pour convertir l'objet Java en XML et vice versa. Pourtant, des classes Java doivent être annotées (annotate) par @XmlRootElement,... Donc, mon conseil est que vous utilisiez jackson-dataformat-xml comme une bibliothèque de conversion XML et Java. Pour utiliser jackson-dataformat-xml vous devez le déclarer dans le fichier pom.xml:
jackson-dataformat-xml
<dependency>
    <groupId>com.fasterxml.jackson.dataformat</groupId>
    <artifactId>jackson-dataformat-xml</artifactId>
</dependency>
OK, vous avez deux choix pour déclarer dans le fichier pom.xml:
** pom.xml (Option 1) **
<dependencies>
     ......

    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-data-rest</artifactId>            
    </dependency>

    <dependency>
        <groupId>com.fasterxml.jackson.dataformat</groupId>
        <artifactId>jackson-dataformat-xml</artifactId>
    </dependency>
    
        .....
</dependencies>
** pom.xml (Option 2) **
<dependencies>
     ......

    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-web</artifactId>            
    </dependency>

    <dependency>
        <groupId>com.fasterxml.jackson.dataformat</groupId>
        <artifactId>jackson-dataformat-xml</artifactId>
    </dependency>
    
        .....
</dependencies>
La bibliothèque Apache Commons Codec nécessite un codage (encode) un nom d'utilisateur / le mot de passe, dans le cas où vous utilisez Rest Client pour accéder aux ressources de données sécurisées par Basic Authentication.
<!-- https://mvnrepository.com/artifact/commons-codec/commons-codec -->
<dependency>
    <groupId>commons-codec</groupId>
    <artifactId>commons-codec</artifactId>
</dependency>
Le contenu complet du fichier pom.xml:
pom.xml
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://maven.apache.org/POM/4.0.0
    http://maven.apache.org/xsd/maven-4.0.0.xsd">
    
    <modelVersion>4.0.0</modelVersion>

    <groupId>org.o7planning</groupId>
    <artifactId>SpringBootRestfulClient</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <packaging>jar</packaging>

    <name>SpringBootRestfulClient</name>
    <description>Spring Boot + Restful Client</description>

    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.0.0.RELEASE</version>
        <relativePath/> <!-- lookup parent from repository -->
    </parent>

    <properties>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
        <java.version>1.8</java.version>
    </properties>

    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter</artifactId>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>
        
        
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-data-rest</artifactId>            
        </dependency>

        <dependency>
            <groupId>com.fasterxml.jackson.dataformat</groupId>
            <artifactId>jackson-dataformat-xml</artifactId>
        </dependency>
        
        <!-- https://mvnrepository.com/artifact/commons-codec/commons-codec -->
        <dependency>
            <groupId>commons-codec</groupId>
            <artifactId>commons-codec</artifactId>
        </dependency>
        
    </dependencies>

    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
        </plugins>
    </build>

</project>

4- GET - getForObject

Utilisez la méthode getForObject pour envoyer une demande (request) au Restful Service, et obtenir des données envoyées. Ci-dessous est le plus simple exemple. Les données renvoient une chaine.
SimplestGetExample.java
package org.o7planning.sbrestfulclient.get;

import org.springframework.web.client.RestTemplate;

public class SimplestGetExample {

	static final String URL_EMPLOYEES = "http://localhost:8080/employees";

	static final String URL_EMPLOYEES_XML = "http://localhost:8080/employees.xml";
	static final String URL_EMPLOYEES_JSON = "http://localhost:8080/employees.json";

	public static void main(String[] args) {

		RestTemplate restTemplate = new RestTemplate();

		// Send request with GET method and default Headers.
		String result = restTemplate.getForObject(URL_EMPLOYEES, String.class);

		System.out.println(result);
	}

}
Các yêu cầu gửi đến Restful Service cần phải tùy biến thông tin Headers để nói với Restful Service kiểu định dạng dữ liệu mà bạn muốn nhận được (JSON, XML, ...)
GetWithHeaderExample.java
package org.o7planning.sbrestfulclient.get;

import java.util.Arrays;

import org.springframework.http.HttpEntity;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpMethod;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.web.client.RestTemplate;

public class GetWithHeaderExample {

	static final String URL_EMPLOYEES = "http://localhost:8080/employees";

	public static void main(String[] args) {

		// HttpHeaders
		HttpHeaders headers = new HttpHeaders();

		headers.setAccept(Arrays.asList(new MediaType[] { MediaType.APPLICATION_JSON }));
		// Request to return JSON format
		headers.setContentType(MediaType.APPLICATION_JSON);
		headers.set("my_other_key", "my_other_value");

		// HttpEntity<String>: To get result as String.
		HttpEntity<String> entity = new HttpEntity<String>(headers);

		// RestTemplate
		RestTemplate restTemplate = new RestTemplate();

		// Send request with GET method, and Headers.
		ResponseEntity<String> response = restTemplate.exchange(URL_EMPLOYEES, //
				HttpMethod.GET, entity, String.class);

		String result = response.getBody();

		System.out.println(result);
	}

}
Les données renvoyées de Restful Serivce qui sont sous format de XML ou JSON peuvent être converties (Convert) en un objet Java.
Employee.java
package org.o7planning.sbrestfulclient.model;

public class Employee {

    private String empNo;
    private String empName;
    private String position;

    public Employee() {

    }

    public Employee(String empNo, String empName, String position) {
        this.empNo = empNo;
        this.empName = empName;
        this.position = position;
    }

    public String getEmpNo() {
        return empNo;
    }

    public void setEmpNo(String empNo) {
        this.empNo = empNo;
    }

    public String getEmpName() {
        return empName;
    }

    public void setEmpName(String empName) {
        this.empName = empName;
    }

    public String getPosition() {
        return position;
    }

    public void setPosition(String position) {
        this.position = position;
    }

}
SimplestGetPOJOExample.java
package org.o7planning.sbrestfulclient.get;

import org.o7planning.sbrestfulclient.model.Employee;
import org.springframework.web.client.RestTemplate;

public class SimplestGetPOJOExample {

	static final String URL_EMPLOYEES = "http://localhost:8080/employees";

	static final String URL_EMPLOYEES_XML = "http://localhost:8080/employees.xml";
	static final String URL_EMPLOYEES_JSON = "http://localhost:8080/employees.json";

	public static void main(String[] args) {

		RestTemplate restTemplate = new RestTemplate();

		// Send request with GET method and default Headers.
		Employee[] list = restTemplate.getForObject(URL_EMPLOYEES, Employee[].class);

		if (list != null) {
			for (Employee e : list) {
				System.out.println("Employee: " + e.getEmpNo() + " - " + e.getEmpName());
			}
		}

	}

}

5- GET - exchange

L'utilisation de la méthode exchange vous aide également à envoyer une demande au Restful Service. Le résultat renvoyé est l'objet ResponseEntity. L'objet comprend plusieurs informations remarqueble, telles que HttpStatus,...
GetPOJOWithHeaderExample.java
package org.o7planning.sbrestfulclient.get;

import java.util.Arrays;

import org.o7planning.sbrestfulclient.model.Employee;
import org.springframework.http.HttpEntity;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpMethod;
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.web.client.RestTemplate;

public class GetPOJOWithHeaderExample {

	static final String URL_EMPLOYEES = "http://localhost:8080/employees";

	public static void main(String[] args) {

		// HttpHeaders
		HttpHeaders headers = new HttpHeaders();

		headers.setAccept(Arrays.asList(new MediaType[] { MediaType.APPLICATION_XML }));
		// Request to return XML format
		headers.setContentType(MediaType.APPLICATION_XML);
		headers.set("my_other_key", "my_other_value");

		// HttpEntity<Employee[]>: To get result as Employee[].
		HttpEntity<Employee[]> entity = new HttpEntity<Employee[]>(headers);

		// RestTemplate
		RestTemplate restTemplate = new RestTemplate();

		// Send request with GET method, and Headers.
		ResponseEntity<Employee[]> response = restTemplate.exchange(URL_EMPLOYEES, //
				HttpMethod.GET, entity, Employee[].class);

		HttpStatus statusCode = response.getStatusCode();
		System.out.println("Response Satus Code: " + statusCode);

		// Status Code: 200
		if (statusCode == HttpStatus.OK) {
			// Response Body Data
			Employee[] list = response.getBody();

			if (list != null) {
				for (Employee e : list) {
					System.out.println("Employee: " + e.getEmpNo() + " - " + e.getEmpName());
				}
			}
		}

	}

}

6- GET - Basic Authentication

Avec les ressources (resource) de données sont sécuriées par Basic Authentication, les demandes (requests) que vous envoyez au REST Service doivent être attachées username/password. L'information de username/password doivent être codées (encode) en utilisant l'algorithme Base64 avant d'être attachées avec le request.
Voir plus :
GetWithBasicAuthExample.java
package org.o7planning.sbrestfulclient.get;

import java.nio.charset.Charset;
import java.util.Arrays;

import org.springframework.http.HttpEntity;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpMethod;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.web.client.RestTemplate;
import org.apache.commons.codec.binary.Base64;

public class GetWithBasicAuthExample {

	public static final String USER_NAME = "tom";
	public static final String PASSWORD = "123";

	static final String URL_EMPLOYEES = "http://localhost:8080/employees";

	public static void main(String[] args) {

		// HttpHeaders
		HttpHeaders headers = new HttpHeaders();

		// 
		// Authentication
		// 
		String auth = USER_NAME + ":" + PASSWORD;
		byte[] encodedAuth = Base64.encodeBase64(auth.getBytes(Charset.forName("US-ASCII")));
		String authHeader = "Basic " + new String(encodedAuth);
		headers.set("Authorization", authHeader);
		// 
		headers.setAccept(Arrays.asList(new MediaType[] { MediaType.APPLICATION_JSON }));
		// Request to return JSON format
		headers.setContentType(MediaType.APPLICATION_JSON);
		headers.set("my_other_key", "my_other_value");

		// HttpEntity<String>: To get result as String.
		HttpEntity<String> entity = new HttpEntity<String>(headers);

		// RestTemplate
		RestTemplate restTemplate = new RestTemplate();

		// Send request with GET method, and Headers.
		ResponseEntity<String> response = restTemplate.exchange(URL_EMPLOYEES, //
				HttpMethod.GET, entity, String.class);

		String result = response.getBody();

		System.out.println(result);
	}

}

7- POST - postForObject

La méthode postForObject sert à envoyer une demande au Restful Service pour créer une ressource (resource) de données et à renvoyer la ressource de données qui ont juste été créée.
Post_postForObject_Example.java
package org.o7planning.sbrestfulclient.post;

import org.o7planning.sbrestfulclient.model.Employee;
import org.springframework.http.HttpEntity;
import org.springframework.http.HttpHeaders;
import org.springframework.http.MediaType;
import org.springframework.web.client.RestTemplate;

public class Post_postForObject_Example {

   static final String URL_CREATE_EMPLOYEE = "http://localhost:8080/employee";

   public static void main(String[] args) {

      String empNo = "E11";

      Employee newEmployee = new Employee(empNo, "Tom", "Cleck");

      HttpHeaders headers = new HttpHeaders();
      headers.add("Accept", MediaType.APPLICATION_XML_VALUE);
      headers.setContentType(MediaType.APPLICATION_XML);

      RestTemplate restTemplate = new RestTemplate();

      // Data attached to the request.
      HttpEntity<Employee> requestBody = new HttpEntity<>(newEmployee, headers);

      // Send request with POST method.
      Employee e = restTemplate.postForObject(URL_CREATE_EMPLOYEE, requestBody, Employee.class);

      if (e != null && e.getEmpNo() != null) {

         System.out.println("Employee created: " + e.getEmpNo());
      } else {
         System.out.println("Something error!");
      }

   }

}

8- POST - postForEntity

La méthode postForEntity est utilisé à envoyer une demande au Restful Service pour créer une ressource (resource) de données. Cette méthode renvoie l'objet ResponseEntity. Cet objet contient la source de données qui a été juste créé et autres informations remarquables, telles que HttpStatus, ...
Post_postForEntity_Example.java
package org.o7planning.sbrestfulclient.post;

import org.o7planning.sbrestfulclient.model.Employee;
import org.springframework.http.HttpEntity;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.client.RestTemplate;

public class Post_postForEntity_Example {

	static final String URL_CREATE_EMPLOYEE = "http://localhost:8080/employee";

	public static void main(String[] args) {

		Employee newEmployee = new Employee("E11", "Tom", "Cleck");

		RestTemplate restTemplate = new RestTemplate();

		// Data attached to the request.
		HttpEntity<Employee> requestBody = new HttpEntity<>(newEmployee);

		// Send request with POST method.
		ResponseEntity<Employee> result 
		     = restTemplate.postForEntity(URL_CREATE_EMPLOYEE, requestBody, Employee.class);

		System.out.println("Status code:" + result.getStatusCode());

		// Code = 200.
		if (result.getStatusCode() == HttpStatus.OK) {
			Employee e = result.getBody();
			System.out.println("(Client Side) Employee Created: "+ e.getEmpNo());
		}

	}

}

9- PUT - Exemple simple

Ma méthode put de la classe RestTemplate sert à envoyer une demande au Restful Service pour changer une ressource (resource) de données. La méthode ne renvoie rien.
PutSimpleExample.java
package org.o7planning.sbrestfulclient.put;

import org.o7planning.sbrestfulclient.model.Employee;
import org.springframework.http.HttpEntity;
import org.springframework.http.HttpHeaders;
import org.springframework.http.MediaType;
import org.springframework.web.client.RestTemplate;

public class PutSimpleExample {

	static final String URL_UPDATE_EMPLOYEE = "http://localhost:8080/employee";
	static final String URL_EMPLOYEE_PREFIX = "http://localhost:8080/employee";

	public static void main(String[] args) {

		String empNo = "E01";

		Employee updateInfo = new Employee(empNo, "Tom", "Cleck");

		HttpHeaders headers = new HttpHeaders();
		headers.add("Accept", MediaType.APPLICATION_JSON_VALUE);

		RestTemplate restTemplate = new RestTemplate();

		// Data attached to the request.
		HttpEntity<Employee> requestBody = new HttpEntity<>(updateInfo, headers);

		// Send request with PUT method.
		restTemplate.put(URL_UPDATE_EMPLOYEE, requestBody, new Object[] {});

		String resourceUrl = URL_EMPLOYEE_PREFIX + "/" + empNo;

		Employee e = restTemplate.getForObject(resourceUrl, Employee.class);

		if (e != null) {
			System.out.println("(Client side) Employee after update: ");
			System.out.println("Employee: " + e.getEmpNo() + " - " + e.getEmpName());
		}
	}

}

10- PUT - exchange

L'exemple de l'utilisation la méthode exchange de la classe RestTemplate sert à envoyer une demande au Restful Service afin de changer une ressource de données.
PutWithExchangeExample.java
package org.o7planning.sbrestfulclient.put;

import org.o7planning.sbrestfulclient.model.Employee;
import org.springframework.http.HttpEntity;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpMethod;
import org.springframework.http.MediaType;
import org.springframework.web.client.RestTemplate;

public class PutWithExchangeExample {

	static final String URL_UPDATE_EMPLOYEE = "http://localhost:8080/employee";
	static final String URL_EMPLOYEE_PREFIX = "http://localhost:8080/employee";

	public static void main(String[] args) {

		String empNo = "E01";

		Employee updateInfo = new Employee(empNo, "Tom", "Cleck");

		HttpHeaders headers = new HttpHeaders();
		headers.add("Accept", MediaType.APPLICATION_JSON_VALUE);

		RestTemplate restTemplate = new RestTemplate();

		// Data attached to the request.
		HttpEntity<Employee> requestBody = new HttpEntity<>(updateInfo, headers);

		// Send request with PUT method.
		restTemplate.exchange(URL_UPDATE_EMPLOYEE, HttpMethod.PUT, requestBody, Void.class);

		String resourceUrl = URL_EMPLOYEE_PREFIX + "/" + empNo;

		Employee e = restTemplate.getForObject(resourceUrl, Employee.class);

		if (e != null) {
			System.out.println("(Client side) Employee after update: ");
			System.out.println("Employee: " + e.getEmpNo() + " - " + e.getEmpName());
		}
	}

}

11- DELELE

L'utilisation la méthode delete de la classe RestTemplate sert à envoyer une demande au Restful Service pour supprimer une ressource de données.
DeleteSimpleExample.java
package org.o7planning.sbrestfulclient.delete;

import org.o7planning.sbrestfulclient.model.Employee;
import org.springframework.web.client.RestTemplate;

public class DeleteSimpleExample {

	public static void main(String[] args) {

		RestTemplate restTemplate = new RestTemplate();

		// empNo="E01"
		String resourceUrl = "http://localhost:8080/employee/E01";

		// Send request with DELETE method.
		restTemplate.delete(resourceUrl);

		// Get 
		Employee e = restTemplate.getForObject(resourceUrl, Employee.class);

		if (e != null) {
			System.out.println("(Client side) Employee after delete: ");
			System.out.println("Employee: " + e.getEmpNo() + " - " + e.getEmpName());
		} else {
			System.out.println("Employee not found!");
		}
	}

}
DeleteExample2.java
package org.o7planning.sbrestfulclient.delete;

import org.o7planning.sbrestfulclient.model.Employee;
import org.springframework.web.client.RestTemplate;

public class DeleteExample2 {

   public static void main(String[] args) {

      RestTemplate restTemplate = new RestTemplate();

      // URL with URI-variable
      String resourceUrl = "http://localhost:8080/employee/{empNo}";

      Object[] uriValues = new Object[] { "E01" };

      // Send request with DELETE method.
      restTemplate.delete(resourceUrl, uriValues);

      Employee e = restTemplate.getForObject(resourceUrl, Employee.class);

      if (e != null) {
         System.out.println("(Client side) Employee after delete: ");
         System.out.println("Employee: " + e.getEmpNo() + " - " + e.getEmpName());
      } else {
         System.out.println("Employee not found!");
      }
   }

}
Peut-être que vous êtes intéressé

Voici des leçons en ligne à part du site web o7planning que nous recommandons. La liste comprend des leçons en ligne et celles en promo.