Пример Spring Boot Restful Client c RestTemplate
View more Tutorials:
Статья основана на:
-
Spring Boot 2.x
-
RestTemplate
-
Eclipse 3.7
В данной статье я покажу вам как создать приложение Restful Client используя Spring Boot. С 4 функциями:
- Создать request с методом GET, отправить к Restful Web Service чтобы получить список сотрудников (employee), или информацию сотрудника. Полученные данные будут иметь формат XML или JSON.
- Создать request с методом PUT, отправить к Restful Web Service, чтобы запросить изменить информацию сотрудника, данные прикрепленные к request имеют формат XML или JSON.
- Создать request с методом POST, отправить к Restful Web Service чтобы добавить нового сотрудника, данные прикрепленные к request имеют формат XML или JSON.
- Создать request с методом DELETE, отправить к Restful Web Service чтобы удалить сотрудника.
Данная статья использует Restful Web Service созданные из следующего примера:
Класс RestTemplate является центральным классом в Spring Framework для синхронических вызовов (synchronous calls) сделанных с помощью Client для доступа к RESTful Web Service. Данный класс предоставляет функции для легкого потребления REST Services. При использовании вышеупомянутого класса, пользователь должен предоставить URL, параметры (если есть) и извлечь полученные результаты. RestTemplate контролирует соединения HTTP (HTTP Connection).
На Eclipse, создать Spring Boot project.




OK, project создан.

Данный Project должен использовать библиотеки Spring Restful Client. Поэтому у вас есть 2 выбора:
- spring-boot-starter-web
- spring-boot-starter-data-rest
spring-boot-starter-web
spring-boot-starter-web включает библиотеки для построения веб приложения используя Spring MVC, и использовать tomcat как Web Container по умолчанию. Включает библиотеки для приложения 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 включает библиотеки для работы с 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
Оба "Starter" выше содержат библиотеку jackson-databind, поддерживающую конвертацию объекта Java в JSON и наоборот.
Java <==> XML
Spring использует JAXB (готовый в JDK) для конвертации объекта Java в XML и наоборот. Но классы Java должны быть аннотированы (annotate) с помощью @XmlRootElement,... Поэтому мой совет это вам стоит использовать jackson-dataformat-xml как библиотеку для конвертации XML и Java. Чтобы использовать jackson-dataformat-xml вам нужно его объявить в файле pom.xml:
jackson-dataformat-xml
<dependency> <groupId>com.fasterxml.jackson.dataformat</groupId> <artifactId>jackson-dataformat-xml</artifactId> </dependency>
OK, у вас есть 2 выбора для объявления в 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>
Необходимая библиотека Apache Commons Codec для кодирования (encode) username/password, в случае если вы используете Rest Client чтобы иметь доступ к ресурсам защищенным с помощью Basic Authentication.
<!-- https://mvnrepository.com/artifact/commons-codec/commons-codec --> <dependency> <groupId>commons-codec</groupId> <artifactId>commons-codec</artifactId> </dependency>
Полное содержание файла 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>

Использовать метод getForObject чтобы отправить запрос (request) к Restful Service, и получить возвращенные данные. Ниже являются самые простые примеры, возвращенные данные являются String.
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); } }

Запросы отправленные к Restful Service должны кастомизировать информацию Headers чтобы сказать Restful Service вид формата данных, который вы хотите получить (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); } }

Данные возвращенные от Restful Serivce имеют формат XML или JSON, которые могут быть конвертированы (Convert) автоматически в объект 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()); } } } }

Использование метода exchange также поможет вам отправить request к Restful Service, возвращенный результат это объект ResponseEntity, данный объект содержит много иноформации заслуживающего внимания, как 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()); } } } } }

Для ресурсов данных (resource) защищенных с помощью Basic Authentication, запросы (request) которые вы отправляете на REST Service должны прикреплять username/password. Информация username/password должна быть кодирована (encode) используя алгоритм Base64 перед тем как прикреплять с request.

Смотрите так же:
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); } }
Метод postForObject используется для отправки request к Restful Service чтобы создать ресурс данных (resource), одновременно возвращает только что созданные ресурсы данных.
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!"); } } }

Метод postForEntity использованные для отправления request к Restful Service чтобы создать ресурс данных (resource). Данный метод возвращает объект ResponseEntity, этот объект содержит только что созданный ресурс данных, и другую важную информацию, например 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()); } } }
Метод put класса RestTemplate используется для отправления request к Restful Service чтобы поменять ресурс данных (resource). Данный метод ничего не возвращает.
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()); } } }
Пример использования метода exchange класса RestTemplate для отправления request к Restful Service чтобы поменять ресурс данных.
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()); } } }

Использовать метод delete класса RestTemplate чтобы отправить request к Restful Service для удаления ресурса данных.
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!"); } } }