什么是RestTemplate?什么是WebClient?有什么区别到底用哪个?

WebClient和RestTemplate确实是Spring框架中用于发送HTTP请求的两种主要工具,但它们在设计理念、使用场景以及性能上有所不同。

1. RestTemplate

RestTemplate是一个较早的、基于阻塞IO的客户端库,用于发送各种类型的HTTP请求。它提供了一种模板化的方式来执行HTTP请求,支持多种HTTP方法(GET, POST, PUT, DELETE等)和多种数据类型(JSON, XML等)。RestTemplate的核心优点在于其简单易用,适合处理较为简单的HTTP请求。

特点:

  • 阻塞式:每次请求都会阻塞直到响应返回,不适合高并发场景。
  • 灵活性:支持多种HTTP方法和媒体类型,可以通过配置自定义消息转换器。
  • 传统API:使用方法链式调用来构建请求,但API设计相对不够流畅。

RestTemplate 代码示例 

首先,确保在配置类中定义一个 RestTemplate bean:

@Configuration
public class AppConfig {

    @Bean
    public RestTemplate restTemplate() {
        return new RestTemplate();
    }
}

使用RestTemplate发送POST 请求调用另一个微服务,并携带请求头 

@RestController
public class UserController {

    private static final Logger log = LoggerFactory.getLogger(UserController.class);

    @Autowired
    private UserService userService;

    @Autowired
    private RestTemplate restTemplate;

    @PutMapping("/insert")
    public User update(@RequestBody User user) {

        // 示例:使用RestTemplate调用另一个微服务,并携带请求头
        HttpHeaders headers = new HttpHeaders();
        headers.setContentType(MediaType.APPLICATION_JSON);
        headers.setBearerAuth("your-token"); // 设置Authorization头

        HttpEntity<User> requestEntity = new HttpEntity<>(user, headers);

        String response = restTemplate.postForObject(
                "http://localhost:8080/user/insert1",
                requestEntity,
                String.class);

        log.debug("Response from insert1: {}", response);

        return user;
    }

    @Transactional
    @PostMapping("/insert1")
    public User update1(@RequestBody User user) {
        userService.updateById(user);
        return user;
    }
}

使用 RestTemplate 发送 GET 请求

@RestController
public class UserController {

    private static final Logger log = LoggerFactory.getLogger(UserController.class);

    @Autowired
    private UserService userService;

    @Autowired
    private RestTemplate restTemplate;

    @PutMapping("/insert")
    public User update(@RequestBody User user) {

        // 示例:使用RestTemplate调用另一个微服务,并携带请求头
        HttpHeaders headers = new HttpHeaders();
        headers.setContentType(MediaType.APPLICATION_JSON);
        headers.setBearerAuth("your-token"); // 设置Authorization头

        HttpEntity<Void> requestEntity = new HttpEntity<>(headers);

        String url = String.format("http://localhost:8080/user/insert1?age=%d&address=%s&name=%s&id=%d",
                user.getAge(), user.getAddress(), user.getName(), user.getId());

        ResponseEntity<String> response = restTemplate.exchange(
                url,
                HttpMethod.GET,
                requestEntity,
                String.class);

        log.debug("Response from insert1: {}", response.getBody());

        return user;
    }

    @Transactional
    @GetMapping("/insert1")
    public User update1(User user) {
        userService.updateById(user);
        return user;
    }
}

 

2. WebClient

WebClient是Spring 5引入的新一代非阻塞的、响应式HTTP客户端,它基于Reactor项目构建。WebClient设计用于异步和响应式编程模型,特别适合微服务架构和高并发场景。

特点:

  • 响应式:基于事件驱动和异步调用,可以处理大量并发请求,减少线程开销。
  • 流式处理:支持数据流处理,能够高效处理大文件或长连接场景。
  • 流畅API:提供了更加流畅的API设计,使得构建复杂的HTTP请求更为直观。
  • 可组合性:请求和响应可以像函数式编程一样组合,易于创建复杂的业务逻辑。

 

WebClient代码示例

第一步 添加依赖

  <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-webflux</artifactId>
            <scope>compile</scope>
        </dependency>

第二步添加配置类

package com.itheima.config;

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.reactive.function.client.WebClient;

@Configuration
public class WebClientConfig {
    @Bean
    public WebClient webClient() {
        return WebClient.create();
    }
}

 使用webClient发送GET请求

@PutMapping("/insert") // 将 HTTP PUT 请求映射到该方法
    public User update(User user) {
        // 记录日志,打印传入的 user 对象
        log.info("update method called with user: {}", user);

        // 使用 WebClient 调用另一个微服务
        webClient.get() // 准备一个 GET 请求
                .uri(uriBuilder -> uriBuilder
                        .scheme("http") // 设置协议为 http
                        .host("localhost") // 设置主机名为 localhost
                        .port(8080) // 设置端口号为 8080
                        .path("/user/insert1") // 设置路径为 /user/insert1
                        // 设置查询参数,使用传入的 user 对象的属性值
                        .queryParam("age", user.getAge())
                        .queryParam("address", user.getAddress())
                        .queryParam("name", user.getName())
                        .queryParam("id", user.getId())
                        .build()) // 构建完整的 URI
                .retrieve() // 发送请求并准备检索响应体
                .bodyToMono(String.class) // 将响应体转换为 Mono<String>
                .timeout(Duration.ofSeconds(5)) // 设置请求超时时间为 5 秒
                .retryWhen(Retry.backoff(3, Duration.ofSeconds(1))) // 设置重试机制,最多重试 3 次,每次间隔 1 秒
                .subscribe(response -> log.info("Response from insert1: {}", response)); // 订阅响应,打印响应日志

        // 返回传入的 user 对象
        return user;
    }
}

  使用webClient发送POST请求

    @PutMapping("/insert")
    public User update(User user){

        // 示例:使用webClient调用另一个微服务
        webClient.post()
                .uri(uriBuilder -> uriBuilder
                        .scheme("http")
                        .host("localhost")
                        .port(8080)
                        .path("/user/insert1")
                        .build())
                .bodyValue(user)
                .retrieve()
                .bodyToMono(String.class)
                .timeout(Duration.ofSeconds(5))
                .retryWhen(Retry.backoff(10, Duration.ofSeconds(1))) // 设置重试机制
                .subscribe(response -> log.debug("Response from insert1: {}", response));

        return user;
    }
    @Transactional
    @PostMapping("/insert1")
    public User update1(@RequestBody User user){
        userService.updateById(user);
        return user;

}

选择建议

  • 如果你的应用是基于传统的同步和阻塞IO模型,且对性能要求不高,RestTemplate可能是一个合适的选择。
  • 如果你的应用需要处理高并发、大数据量的请求,或者你正在构建响应式微服务架构,WebClient将是一个更优的选择。

 

总结

两者都可以发送HTTP请求,但WebClient代表了未来的发展方向,尤其是在响应式编程和微服务领域。随着Spring框架的发展,WebClient的功能和社区支持都在不断加强,成为处理HTTP请求的首选工具。然而,对于不需要响应式特性的简单应用,RestTemplate仍然是一个简单有效的解决方案。

 

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值