Redian新闻
>
替换OpenFeign,Spring 新版本自带的 HTTP 客户端工具来了!

替换OpenFeign,Spring 新版本自带的 HTTP 客户端工具来了!

公众号新闻

点击上方“芋道源码”,选择“设为星标

管她前浪,还是后浪?

能浪的浪,才是好浪!

每天 10:33 更新文章,每天掉亿点点头发...

源码精品专栏

 
来源:Java知音


我们在日常开发中,经常会需要远程调用其他服务提供的接口,比较常用的 HTTP 远程代理框架有OpenFeign、Retrofit以及一些第三方封装工具类,例如Hutool提供的HttpUtil。

11月24日,Spring Boot 3正式发布,Spring官方已经自身支持使用声明式服务调用的方式来调用远程接口。

虽然类似的远程调用框架如OpenFeign和Retrofit仍然可以使用,但HttpServiceProxyFactory增加了对 Spring 框架的原生支持。如果Spring本身可以做到远程调用的话,这些大量的第三方库应该很快会被原生方法取代,我们今天来了解一下这个新特征。

声明式 Http 接口

声明性 HTTP 接口可以让你像定义Java接口那样定义HTTP服务,用法和你平时写Controller中方法完全一致。

引入

声明性 HTTP 接口功能是spring-web依赖项的一部分,使用前必须引入如下依赖包:

<dependency>
  <groupId>org.springframework.boot</groupId>
  <artifactId>spring-boot-starter-web</artifactId>
</dependency>
<!-- For reactive support -->
<dependency>
  <groupId>org.springframework.boot</groupId>
  <artifactId>spring-boot-starter-webflux</artifactId>
</dependency>

创建 HTTP 服务接口

在 Spring 中,HTTP 服务接口是一个带有@HttpExchange方法的 Java 接口。注释方法被视为 HTTP 端点,细节通过注释属性和输入方法参数类型静态定义。

支持的注解类型

  • @HttpExchange :是用于指定 HTTP 端点的通用注释。在接口级别使用时,它适用于所有方法。
  • @GetExchange :为 HTTP GET请求指定@HttpExchange
  • @PostExchange :为 HTTP POST请求指定@HttpExchange
  • @PutExchange :为 HTTP PUT请求指定@HttpExchange
  • @DeleteExchange :为 HTTP DELETE请求指定@HttpExchange
  • @PatchExchange :为 HTTP PATCH请求指定@HttpExchange

方法参数

返回值

声明性 HTTP 接口支持以下返回值:

使用示例

@PutExchange
void update(@PathVariable Long id, @RequestBody User user);

完整使用案例

我们以一个简单的用户信息请求为例

0、构建HttpServiceProxyFactory

HttpServiceProxyFactory是一个从 HTTP 服务接口创建客户端代理的工厂类。使用HttpServiceProxyFactory.builder(client).build()方法来获取代理 bean 的实例。

import com.fasterxml.jackson.databind.ObjectMapper;
import com.howtodoinjava.app.web.UserClient;
import lombok.SneakyThrows;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.reactive.function.client.WebClient;
import org.springframework.web.reactive.function.client.support.WebClientAdapter;
import org.springframework.web.service.invoker.HttpServiceProxyFactory;
@Configuration
public class WebConfig {
  @Bean
  WebClient webClient(ObjectMapper objectMapper) {
    return WebClient.builder()
        .baseUrl("https://jsonplaceholder.typicode.com/")
        .build();
  }
  @SneakyThrows
  @Bean
  UserClient postClient(WebClient webClient) {
    HttpServiceProxyFactory httpServiceProxyFactory =
        HttpServiceProxyFactory.builder(WebClientAdapter.forClient(webClient))
            .build();
    return httpServiceProxyFactory.createClient(UserClient.class);
  }
}

1、定义一个简单的用户信息实体类:

public class User {

    private int id;

    private String username;

    private String password;
  
   // 省略

}

2、请求接口:

import com.howtodoinjava.app.model.User;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.service.annotation.DeleteExchange;
import org.springframework.web.service.annotation.GetExchange;
import org.springframework.web.service.annotation.HttpExchange;
import org.springframework.web.service.annotation.PostExchange;
import org.springframework.web.service.annotation.PutExchange;
import reactor.core.publisher.Flux;
import reactor.core.publisher.Mono;
@HttpExchange(url = "/users", accept = "application/json", contentType = "application/json")
public interface UserClient {
  @GetExchange("/")
  Flux<User> getAll();
  @GetExchange("/{id}")
  Mono<User> getById(@PathVariable("id") Long id);
  @PostExchange("/")
  Mono<ResponseEntity<Void>> save(@RequestBody User user);
  @PutExchange("/{id}")
  Mono<ResponseEntity<Void>> update(@PathVariable Long id, @RequestBody User user);
  @DeleteExchange("/{id}")
  Mono<ResponseEntity<Void>> delete(@PathVariable Long id);
}

3、将UserClient bean 注入应用程序类并调用方法来获取 API 响应:

@Autowired
UserClient userClient;
//Get All Users
userClient.getAll().subscribe(
    data -> log.info("User: {}", data)
);
//Get User By Id
userClient.getById(1L).subscribe(
    data -> log.info("User: {}", data)
);
//Create a New User
userClient.save(new User(null"Lokesh""lokesh""[email protected]"))
    .subscribe(
        data -> log.info("User: {}", data)
    );
//Delete User By Id
userClient.delete(1L).subscribe(
    data -> log.info("User: {}", data)
);

完工,不需要定义方法实现就能进行远程HTTP调用,非常方便!



欢迎加入我的知识星球,一起探讨架构,交流源码。加入方式,长按下方二维码噢

已在知识星球更新源码解析如下:

最近更新《芋道 SpringBoot 2.X 入门》系列,已经 101 余篇,覆盖了 MyBatis、Redis、MongoDB、ES、分库分表、读写分离、SpringMVC、Webflux、权限、WebSocket、Dubbo、RabbitMQ、RocketMQ、Kafka、性能测试等等内容。

提供近 3W 行代码的 SpringBoot 示例,以及超 4W 行代码的电商微服务项目。

获取方式:点“在看”,关注公众号并回复 666 领取,更多内容陆续奉上。

文章有帮助的话,在看,转发吧。

谢谢支持哟 (*^__^*)

微信扫码关注该文公众号作者

戳这里提交新闻线索和高质量文章给我们。
相关阅读
Dunkin 回归Midnight Coffee 并推出全新Brown Butter Toffee Latte 及新年优惠HTTPS 终于搞懂了 !Spring 6 正式“抛弃” feign手撸一个动态Feign,实现一个“万能”接口调用别再自己瞎写工具类了,SpringBoot 内置工具类应有尽有,建议收藏!!从Redis、HTTP协议,看Nett协议设计一周资讯|《新时代的中国绿色发展》白皮书发布;Twitter更新开发者协议禁用第三方客户端;阿里发布2023春节团圆消费报告..Oral-B 电动牙刷替换头8个装,40%折扣,S&S订阅价$28.79!@ AmazonSpring 新特性,正式“抛弃”Feign了Spring for Apache Kafka 3.0 和 Spring for RabbitMQ 3.0 发布下一代生产力工具来了!创业者如何拥抱AIGC热潮? | 榕汇对话【庭院种菜】雪菜怎么腌制?亚硝酸盐从哪里来?别玩ChatGPT了,更酷炫的AI视频创作工具来了天赋“易昺(bǐng)”,创造历史!To Fight Trolls, A Campaign Wants People to Flaunt Pink Hair硬核观察 #891 Twitter 修改开发者协议明确禁止第三方客户端Hadoop/Spark 太重,esProc SPL 很轻名校Offer榜!最新2023 Spring Top Offer!西北大学(全美前十)揭秘HTTP/3优先级畅游法国(36)-葡萄酒之路别的简报|帮你把大白话改成商务邮件的 AI 工具来了HTTP3势头这么猛,它的优势在哪里?面试官问我:一个 TCP 连接可以发多少个 HTTP 请求?我竟然回答不上来通俗大白话,彻底弄懂https原理本质掌握这些技巧的 80% ,你的 HTTPS 稳健如飞!今冬新冠趋势大话 HTTP 协议前世今生说来就来了对话 Spring 大神:Spring 生态系统的新时代来了!高尔夫,未来的“高乐福”Chinese Professor Suspended For Racist, Homophobic Speech历时五年,U-Boot终于提供TCP协议和HTTP支持美股SPAC|HyperloopTT将通过与 SPAC合并成为首家专注于超回路列车的上市公司Vite 4.0发布,下一代的前端工具链WPP收购北美数字机构Fēnom Digital;凯捷旗下The Works公司公布新任命(广告狂人日报)
logo
联系我们隐私协议©2024 redian.news
Redian新闻
Redian.news刊载任何文章,不代表同意其说法或描述,仅为提供更多信息,也不构成任何建议。文章信息的合法性及真实性由其作者负责,与Redian.news及其运营公司无关。欢迎投稿,如发现稿件侵权,或作者不愿在本网发表文章,请版权拥有者通知本网处理。