Spring Boot RestTemplate - 使用 RestTemplate 创建同步 HTTP 请求

位置:首页>文章>详情   分类: Java教程 > 编程技术   阅读(475)   2023-06-26 07:54:18

Spring Boot RestTemplate 教程展示了如何使用 RestTemplate 在 Spring 应用程序中创建同步 HTTP 请求。

春天 是一个流行的 Java 应用程序框架,弹簧贴 是 Spring 的演变,有助于创建独立的、生产级的基于 Spring 的应用程序容易地。

休息模板

RestTemplate 是执行 HTTP 请求的同步客户端。它在底层 HTTP 客户端库(例如 JDK HttpURLConnection、Apache HttpComponents 等)上使用简单的模板方法 API。

自 Spring 5.0 以来,一个新的客户端 WebClient 可用,可用于创建同步和异步请求。在未来的版本中,RestTemplate 将被弃用,取而代之的是 WebClient

Spring Boot RestTemplate 示例

在以下应用程序中,我们创建了一个生成 JSON 数据的自定义测试服务器,并使用 RestTemplate 生成 HTTP 请求并使用返回的 JSON 数据。

创建 JSON 服务器

我们使用 Node 为我们的目的创建一个 JSON 测试服务器。

$ node --version
v11.2.0

我们展示了 Node.js 的版本。

$ npm init    
$ npm i -g json-server
$ npm i faker fs

我们初始化一个 Node 项目并安装 json-serverfakerfs 模块。 json-server用于创建测试JSON服务器,faker用于生成测试数据,fs 在 JavaScript 中使用文件系统。

generate_fake_users.js
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'));

使用 faker,我们生成了 100 个具有 ID、名字、姓氏和电子邮件属性的用户。数据被写入 data.json 文件。该文件由 json-server 使用。

$ node generate_fake_users.js

我们产生了一百个假用户。

$ 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 资源的请求,以获取 100 个 JSON 用户。

Spring Boot 应用程序

我们创建一个 Spring Boot 应用程序。我们需要以下 Maven 依赖项和插件:spring-boot-starterspring-webjackson-数据绑定spring-boot-starter-testspring-boot-maven-plugin

application.properties
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 横幅,将日志记录级别设置为信息,并设置控制台日志记录模式。我们还设置了一个指向用户资源的 URL 属性。稍后将使用 @Value 检索该属性。

User.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
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。它设置了 RestTemplateSimpleClientHttpRequestFactory 用于设置连接和读取超时。

AppConfig.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
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 测试服务器获取所有用户。

@Autowired
private RestTemplate myRestTemplate;

我们注入 RestTemplate bean。

@Value("${myrest.url}")
private String restUrl;

从配置中,我们使用 @Value 注释获取 URL。

var users = myRestTemplate.getForObject(restUrl, User[].class);

我们使用 getForObject() 方法来生成请求。因为我们需要一个对象数组,所以我们使用 User[].class 语法。

MyRunner.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 获取用户。我们向控制台显示前 10 个用户。

Application.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
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 数据不为空并且包含一百个元素。

@RestClientTest(value={MyRestService.class, AppConfig.class})

@RestClientTest 注释用于测试 Spring 休息客户端。它禁用完全自动配置并仅应用与其余客户端测试相关的配置。

$ 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'}
...

我们运行应用程序。

在本教程中,我们展示了如何使用 RestTemplate 在 Spring 应用程序中创建同步请求。 REST 数据来自 Node.js 创建的测试 JSON 服务器。

地址:https://www.cundage.com/article/springboot-resttemplate.html

相关阅读

Spring Boot Vue.js 教程展示了如何使用 Vue.js 框架创建一个简单的 Spring Boot。 Vue.js Vue.js 是一个用于构建用户界面的 JavaScript ...
JavaScript 是否已经取代 Java 成为新的“一次编写,随处运行”的编程语言?这完全取决于您的观点。随着 WebAssembly 等技术的出现,Java 可以在新奇的“一次编写,随处编...
Usage of TypeScript,微软基于 JavaScript 的强类型语言, has soared compared to six years ago, according to th...
云莓将基于 Spring 构建的 Java 后端与使用 Lit 构建的 TypeScript 前端相结合,一个快速、响应式的 JavaScript 框架。基于 Vaadin Fusion 的 H...
本博客严重偏向于 GWT(和基于 GWT 的框架),但我们牢记 GWT 将来可能会被其他技术接管,因此我们始终对探索其他平台/框架持开放态度。正如他们所说,多元化可以降低风险。每种编程语言,即使...
Java JSON 教程展示了如何使用 JSON-Java 在 Java 中进行 JSON 序列化和反序列化。 JSON(JavaScript 对象显示法) 是一种轻量级数据交换格式。人类易于读...
JHipster 是一个长期存在且雄心勃勃的混合 Java 和 JavaScript 项目,致力于使用现代反应式前端简化全栈 Java 应用程序的开发。 JHipster 开发团队不断发布新版本...
解析器是强大的工具,使用 ANTLR 可以编写可用于多种不同语言的各种解析器。 在这个完整的教程中,我们将: 解释基础:什么是解析器,它可以用来做什么 查看如何设置 ANTLR 以便在 Java...
Spring Boot JSON 教程展示了如何在 Spring Boot 注释中提供 JSON 数据。 春天 是一个流行的 Java 应用程序框架,弹簧贴 是 Spring 的演变,有助于创建...
根据最近一项全球开发人员调查,在开发人员偏好方面,JavaScript 和 Python 保持了持久力,而 锈 的使用率正在上升. 5 月 4 日的一份题为“开发者国家情况,第 22nd 版”的...