多应用+插件架构,代码干净,二开方便,首家独创一键云编译技术,文档视频完善,免费商用码云13.8K 广告
# Spring Boot `RestTemplate` > 原文: [http://zetcode.com/springboot/resttemplate/](http://zetcode.com/springboot/resttemplate/) Spring Boot `RestTemplate`教程展示了如何在 Spring 应用中使用`RestTemplate`创建同步 HTTP 请求。 Spring 是流行的 Java 应用框架,而 Spring Boot 是 Spring 的演进,可以帮助轻松地创建独立的,生产级的基于 Spring 的应用。 ## `RestTemplate` `RestTemplate`是执行 HTTP 请求的同步客户端。 它在基础 HTTP 客户端库(例如 JDK `HttpURLConnection`,Apache HttpComponents 等)上使用简单的模板方法 API。 从 Spring 5.0 开始,可以使用新客户端`WebClient`创建同步和异步请求。 在将来的版本中,将不推荐使用`RestTemplate`,而推荐使用`WebClient`。 ## Spring Boot `RestTemplate` 示例 在以下应用中,我们创建一个自定义测试服务器,该服务器生成 JSON 数据,并使用`RestTemplate`生成 HTTP 请求并使用返回的 JSON 数据。 ## 创建 JSON 服务器 为此,我们使用 Node 创建一个 JSON 测试服务器。 ```java $ node --version v11.2.0 ``` 我们显示 Node 的版本。 ```java $ npm init $ npm i -g json-server $ npm i faker fs ``` 我们初始化 Node 项目并安装`json-server`,`faker`和`fs`模块。 `json-server`用于创建测试 JSON 服务器,`faker`用于生成测试数据,`fs`用于 JavaScript 中的文件系统。 `generate_fake_users.js` ```java const faker = require('faker') const fs = require('fs') function generateUsers() { let users = [] for (let id=1; id <= 100; id++) { let firstName = faker.name.firstName() let lastName = faker.name.lastName() let email = faker.internet.email() users.push({ "id": id, "first_name": firstName, "last_name": lastName, "email": email }) } return { "users": users } } let dataObj = generateUsers(); fs.writeFileSync('data.json', JSON.stringify(dataObj, null, '\t')); ``` 使用仿造者,我们可以生成具有 ID,名字,姓氏和电子邮件属性的一百个用户。 数据被写入`data.json`文件。 该文件由`json-server`使用。 ```java $ node generate_fake_users.js ``` 我们产生了一百个假用户。 ```java $ json-server --watch data.json \{^_^}/ hi! Loading data.json Done Resources http://localhost:3000/users Home http://localhost:3000 ``` 我们开始`json-server`。 现在,我们可以向`http://localhost:3000/users`资源创建一个请求,以使用 JSON 获得一百个用户。 ## Spring Boot 应用 我们创建一个 Spring Boot 应用。 我们需要以下 Maven 依赖项和插件:`spring-boot-starter`,`spring-web`,`jackson-databind`,`spring-boot-starter-test`和`spring-boot-maven-plugin`。 `application.properties` ```java spring.main.banner-mode=off logging.level.root=INFO logging.pattern.console=%d{dd-MM-yyyy HH:mm:ss} %magenta([%thread]) %highlight(%-5level) %logger.%M - %msg%n myrest.url=http://localhost:3000/users ``` `application.properties`是 Spring Boot 中的主要配置文件。 我们关闭 Spring 横幅,将日志记录级别设置为 info,并设置控制台日志记录模式。 我们还设置了一个指向用户资源的 URL 属性。 稍后将使用`@Value`检索该属性。 `User.java` ```java package com.zetcode.bean; import com.fasterxml.jackson.annotation.JsonProperty; public class User { private int id; private String firstName; private String lastName; private String email; public int getId() { return id; } public void setId(int id) { this.id = id; } public String getFirstName() { return firstName; } @JsonProperty("first_name") public void setFirstName(String firstName) { this.firstName = firstName; } public String getLastName() { return lastName; } @JsonProperty("last_name") public void setLastName(String lastName) { this.lastName = lastName; } public String getEmail() { return email; } public void setEmail(String email) { this.email = email; } @Override public String toString() { final var sb = new StringBuilder("User{"); sb.append("id=").append(id); sb.append(", firstName='").append(firstName).append('\''); sb.append(", lastName='").append(lastName).append('\''); sb.append(", email='").append(email).append('\''); sb.append('}'); return sb.toString(); } } ``` `User` bean 映射到 JSON 用户对象。 Spring 使用 Jackson 库将 JSON 数据绑定到 Java 类。 由于 JSON 属性与 Java 属性不匹配,因此我们使用`@JsonProperty`来解决此问题。 `AppConfig.java` ```java package com.zetcode.config; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.http.client.SimpleClientHttpRequestFactory; import org.springframework.web.client.RestTemplate; @Configuration public class AppConfig { @Bean public RestTemplate restTemplate() { var factory = new SimpleClientHttpRequestFactory(); factory.setConnectTimeout(3000); factory.setReadTimeout(3000); return new RestTemplate(factory); } } ``` 我们创建一个配置 bean。 设置`RestTemplate`。 `SimpleClientHttpRequestFactory`用于设置连接和读取超时。 `AppConfig.java` ```java package com.zetcode.config; import org.springframework.boot.web.client.RestTemplateBuilder; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.web.client.RestTemplate; import java.time.Duration; @Configuration public class AppConfig { @Bean public RestTemplate restTemplate(RestTemplateBuilder builder) { return builder .setConnectTimeout(Duration.ofMillis(3000)) .setReadTimeout(Duration.ofMillis(3000)) .build(); } } ``` 或者,我们可以使用`RestTemplateBuilder`来完成这项工作。 `MyRestService.java` ```java package com.zetcode.service; import com.zetcode.bean.User; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Value; import org.springframework.stereotype.Service; import org.springframework.web.client.RestTemplate; @Service public class MyRestService { @Autowired private RestTemplate myRestTemplate; @Value("${myrest.url}") private String restUrl; public User[] getUsers() { var users = myRestTemplate.getForObject(restUrl, User[].class); return users; } } ``` `MyRestService`是生成 HTTP 请求的服务类。 它从 JSON 测试服务器获取所有用户。 ```java @Autowired private RestTemplate myRestTemplate; ``` 我们注入了`RestTemplate` bean。 ```java @Value("${myrest.url}") private String restUrl; ``` 从配置中,我们使用`@Value`注解获取 URL。 ```java var users = myRestTemplate.getForObject(restUrl, User[].class); ``` 我们使用`getForObject()`方法生成请求。 由于我们期望对象数组,因此我们使用`User[].class`语法。 `MyRunner.java` ```java package com.zetcode; import com.zetcode.service.MyRestService; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.CommandLineRunner; import org.springframework.stereotype.Component; import java.util.Arrays; @Component public class MyRunner implements CommandLineRunner { private static final Logger logger = LoggerFactory.getLogger(MyRunner.class); @Autowired private MyRestService myRestService; @Override public void run(String... args) throws Exception { var users = myRestService.getUsers(); Arrays.stream(users).limit(10).forEach(todo -> logger.info("{}", todo)); } } ``` `MyRunner`使用`MyRestService`获取用户。 我们向控制台显示前十个用户。 `Application.java` ```java package com.zetcode; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; @SpringBootApplication public class Application { public static void main(String[] args) { SpringApplication.run(Application.class, args); } } ``` `Application`是设置 Spring Boot 应用的入口。 `ApplicationTests.java` ```java package com.zetcode; import com.zetcode.config.AppConfig; import com.zetcode.service.MyRestService; import org.junit.Test; import org.junit.runner.RunWith; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.autoconfigure.web.client.RestClientTest; import org.springframework.test.context.junit4.SpringRunner; import static org.assertj.core.api.Assertions.assertThat; @RunWith(SpringRunner.class) @RestClientTest(value={MyRestService.class, AppConfig.class}) public class ApplicationTests { @Autowired private MyRestService service; @Test public void usersNotEmpty() throws Exception { var users = this.service.getUsers(); assertThat(users).isNotEmpty(); } @Test public void hasSizeOneHundred() throws Exception { var users = this.service.getUsers(); assertThat(users).hasSize(100); System.out.println(users); } } ``` 我们测试`getUsers()`服务方法。 我们测试 JSON 数据不为空,并且包含一百个元素。 ```java @RestClientTest(value={MyRestService.class, AppConfig.class}) ``` `@RestClientTest`注解用于测试 Spring rest 客户端。 它禁用完全自动配置,并且仅应用与其余客户端测试相关的配置。 ```java $ mvn -q spring-boot:run ... 27-11-2018 15:33:55 [main] INFO com.zetcode.MyRunner.lambda$run$0 - User{id=1, firstName='Ofelia', lastName='Hintz', email='Gustave.Von43@yahoo.com'} 27-11-2018 15:33:55 [main] INFO com.zetcode.MyRunner.lambda$run$0 - User{id=2, firstName='Brian', lastName='Marvin', email='Marina.Shields@hotmail.com'} 27-11-2018 15:33:55 [main] INFO com.zetcode.MyRunner.lambda$run$0 - User{id=3, firstName='Adah', lastName='Marquardt', email='Osbaldo_Halvorson55@hotmail.com'} 27-11-2018 15:33:55 [main] INFO com.zetcode.MyRunner.lambda$run$0 - User{id=4, firstName='Jaycee', lastName='Kulas', email='Claud85@gmail.com'} ... ``` 我们运行该应用。 在本教程中,我们展示了如何在 Spring 应用中使用`RestTemplate`创建同步请求。 REST 数据来自 Node 创建的测试 JSON 服务器。 您可能也对相关教程感兴趣: [Spring Boot `@RestController`教程](/springboot/restcontroller/), [Spring Boot H2 REST 教程](/articles/springbootresth2/), [Spring Boot RESTFul 应用](/articles/springbootrestsimple/), [Spring Boot REST Data JPA 教程](/articles/springbootrestdatajpa/)和 [Java 教程](/lang/java/)。