2024年 全新 HTTP 客户端 你用了?

我们平时开发项目的时候,经常会需要远程调用下其他服务提供的接口,于是我们会使用一些 HTTP 工具类比如 Hutool 提供的 HttpUtil。SpringBoot 3.0 出了一个Http Interface的新特性,它允许我们使用声明式服务调用的方式来调用远程接口,今天我们就来聊聊它的使用!

简介

Http Interface让你可以像定义 Java 接口那样定义 HTTP 服务,而且用法和你平时写 Controller 中方法完全一致。它会为这些 HTTP 服务接口自动生成代理实现类,底层是基于 Webflux 的 WebClient 实现的。

使用声明式服务调用确实够优雅,下面是一段使用Http Interface声明的Http服务代码。

图片

使用

在 SpringBoot 3.0 中使用Http Interface是非常简单的,下面我们就来体验下。

依赖集成

  • 首先在项目的pom.xml中定义好 SpringBoot 的版本为3.0.0

<parent><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-parent</artifactId><version>3.0.0</version><relativePath/> <!-- lookup parent from repository -->
</parent>
  • 由于 SpringBoot 最低要求为Java 17,我们需要先安装好 JDK 17,安装完成后配置项目的 SDK 版本为Java 17,JDK 下载地址:https://www.oracle.com/cn/java/technologies/downloads/

图片

  • 由于Http Interface需要依赖 webflux 来实现,我们还需添加它的依赖。

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

基本使用

下面,我们来体验下Http Interface的基本使用。

  • 首先我们准备一个服务来方便远程调用,打开 Swagger 看下,里面有一个登录接口和需要登录认证的商品品牌 CRUD 接口

图片

  • 先在application.yml中配置好服务地址;

remote:baseUrl: http://localhost:8088/
  • 再通过@HttpExchange声明一个 Http 服务,使用@PostExchange注解表示进行 POST 请求;

/*** 定义Http接口,用于调用远程的UmsAdmin服务* Created by macro on 2022/1/19.*/
@HttpExchange
public interface UmsAdminApi {@PostExchange("admin/login")CommonResult<LoginInfo> login(@RequestParam("username") String username, @RequestParam("password") String password);
}
  • 再创建一个远程调用品牌服务的接口,参数注解使用我们平时写Controller 方法用的那些即可;

/*** 定义Http接口,用于调用远程的PmsBrand服务* Created by macro on 2022/1/19.*/
@HttpExchange
public interface PmsBrandApi {@GetExchange("brand/list")CommonResult<CommonPage<PmsBrand>> list(@RequestParam("pageNum") Integer pageNum, @RequestParam("pageSize") Integer pageSize);@GetExchange("brand/{id}")CommonResult<PmsBrand> detail(@PathVariable("id") Long id);@PostExchange("brand/create")CommonResult create(@RequestBody PmsBrand pmsBrand);@PostExchange("brand/update/{id}")CommonResult update(@PathVariable("id") Long id, @RequestBody PmsBrand pmsBrand);@GetExchange("brand/delete/{id}")CommonResult delete(@PathVariable("id") Long id);
}
  • 为方便后续调用需要登录认证的接口,我创建了TokenHolder这个类,把 token 存储到了 Session 中;

/*** 登录token存储(在Session中)* Created by macro on 2022/1/19.*/
@Component
public class TokenHolder {/*** 添加token*/public void putToken(String token) {RequestAttributes ra = RequestContextHolder.getRequestAttributes();HttpServletRequest request = ((ServletRequestAttributes) ra).getRequest();request.getSession().setAttribute("token", token);}/*** 获取token*/public String getToken() {RequestAttributes ra = RequestContextHolder.getRequestAttributes();HttpServletRequest request = ((ServletRequestAttributes) ra).getRequest();Object token = request.getSession().getAttribute("token");if(token!=null){return (String) token;}return null;}}
  • 创建 Java 配置,配置好请求用的客户端 WebClient 及 Http 服务对象即可,由于品牌服务需要添加认证头才能正常访问,所以使用了过滤器进行统一添加;

@Configuration
public class HttpInterfaceConfig {@Value("${remote.baseUrl}")private String baseUrl;@Autowiredprivate TokenHolder tokenHolder;@BeanWebClient webClient() {return WebClient.builder()//添加全局默认请求头.defaultHeader("source", "http-interface")//给请求添加过滤器,添加自定义的认证头.filter((request, next) -> {ClientRequest filtered = ClientRequest.from(request).header("Authorization", tokenHolder.getToken()).build();return next.exchange(filtered);}).baseUrl(baseUrl).build();}@BeanUmsAdminApi umsAdminApi(WebClient client) {HttpServiceProxyFactory factory = HttpServiceProxyFactory.builder(WebClientAdapter.forClient(client)).build();return factory.createClient(UmsAdminApi.class);}@BeanPmsBrandApi pmsBrandApi(WebClient client) {HttpServiceProxyFactory factory = HttpServiceProxyFactory.builder(WebClientAdapter.forClient(client)).build();return factory.createClient(PmsBrandApi.class);}
}
  • 接下来在 Controller 中注入 Http 服务对象,然后进行调用即可;

/*** HttpInterface测试接口* Created by macro on 2022/1/19.*/
@RestController
@Api(tags = "HttpInterfaceController")
@Tag(name = "HttpInterfaceController", description = "HttpInterface测试接口")
@RequestMapping("/remote")
public class HttpInterfaceController {@Autowiredprivate UmsAdminApi umsAdminApi;@Autowiredprivate PmsBrandApi pmsBrandApi;@Autowiredprivate TokenHolder tokenHolder;@ApiOperation(value = "调用远程登录接口获取token")@PostMapping(value = "/admin/login")public CommonResult<LoginInfo> login(@RequestParam String username, @RequestParam String password) {CommonResult<LoginInfo> result = umsAdminApi.login(username, password);LoginInfo loginInfo = result.getData();if (result.getData() != null) {tokenHolder.putToken(loginInfo.getTokenHead() + " " + loginInfo.getToken());}return result;}@ApiOperation("调用远程接口分页查询品牌列表")@GetMapping(value = "/brand/list")public CommonResult<CommonPage<PmsBrand>> listBrand(@RequestParam(value = "pageNum", defaultValue = "1")@ApiParam("页码") Integer pageNum,@RequestParam(value = "pageSize", defaultValue = "3")@ApiParam("每页数量") Integer pageSize) {return pmsBrandApi.list(pageNum, pageSize);}@ApiOperation("调用远程接口获取指定id的品牌详情")@GetMapping(value = "/brand/{id}")public CommonResult<PmsBrand> brand(@PathVariable("id") Long id) {return pmsBrandApi.detail(id);}@ApiOperation("调用远程接口添加品牌")@PostMapping(value = "/brand/create")public CommonResult createBrand(@RequestBody PmsBrand pmsBrand) {return pmsBrandApi.create(pmsBrand);}@ApiOperation("调用远程接口更新指定id品牌信息")@PostMapping(value = "/brand/update/{id}")public CommonResult updateBrand(@PathVariable("id") Long id, @RequestBody PmsBrand pmsBrand) {return pmsBrandApi.update(id,pmsBrand);}@ApiOperation("调用远程接口删除指定id的品牌")@GetMapping(value = "/delete/{id}")public CommonResult deleteBrand(@PathVariable("id") Long id) {return  pmsBrandApi.delete(id);}
}

测试

  • 下面我们通过 Postman 进行测试,首先调用登录接口获取到远程服务返回的 token 了;

图片

  • 再调用下需要登录认证的品牌列表接口,发现可以正常访问。

图片

总结

Http Interface让我们只需定义接口,无需定义方法实现就能进行远程 HTTP 调用,确实非常方便!但是其实现依赖 Webflux 的 WebClient,在我们使用 SpringMVC 时会造成一定的麻烦,如果能独立出来就更好了!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/245090.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

重磅!Salesforce推出UE+无限版餐套,企业如何选择?

孤立的应用程序和脱节的技术堆栈是所有企业的噩梦。目前&#xff0c;市场上产品和服务种类繁多&#xff0c;无缝集成和清晰、直接的购买流程可以决定整体体验的成败。 Salesforce云以及其他应用程序在过去几年中经历了巨大增长。随着越来越多的功能被捆绑在一起&#xff0c;Un…

威联通QNAP NAS结合cpolar内网穿透实现公网远程访问NAS中存储的文件

文章目录 推荐 前言1. 威联通安装cpolar内网穿透2. 内网穿透2.1 创建隧道2.2 测试公网远程访问 3. 配置固定二级子域名3.1 保留二级子域名3.2 配置二级子域名 4. 使用固定二级子域名远程访问 推荐 前些天发现了一个巨牛的人工智能学习网站&#xff0c;通俗易懂&#xff0c;风趣…

Tarjan 算法(超详细!!)

推荐在 cnblogs 上阅读 Tarjan 算法 前言 说来惭愧&#xff0c;这个模板仅是绿的算法至今我才学会。 我还记得去年 CSP2023 坐大巴路上拿着书背 Tarjan 的模板。虽然那年没有考连通分量类似的题目。 现在做题遇到了 Tarjan&#xff0c;那么&#xff0c;重学&#xff0c;开…

“趣味夕阳,乐享生活”小组活动(第二节)

立冬以来&#xff0c;天气日渐寒冷&#xff0c;气温变化较大&#xff0c;各种传染病多发&#xff0c;为进一步增强老年人冬季预防传染病保健意识及科学合理健康的生活方式。近日&#xff0c;1月22日&#xff0c;南阳市人人社工灌涨站开展了“趣味夕阳&#xff0c;乐享生活”小组…

【C++ | 数据结构】从哈希的概念 到封装C++STL中的unordered系列容器

文章目录 一、unordered系列容器的底层结构 - 哈希1. 哈希概念2. 哈希冲突 二、解决哈希冲突方法一&#xff1a;合理设计哈希函数&#x1f6a9;哈希函数设计原则&#x1f6a9;常见哈希函数 方法二&#xff1a;开闭散列&#x1f6a9;闭散列线性探测法&#xff08;实现&#xff0…

gradle打包分离依赖jar

正常打包的jar是包含项目所依赖的jar包资源&#xff0c;而且大多数场景下的依赖资源是不会频繁的变更的&#xff0c;所以实际把项目自身jar和其所依赖的资源分离可以实现jar包瘦身&#xff0c;减小上传的jar包总大小&#xff0c;能实现加速部署的效果 一 原本结构 二 配置buil…

第04章_IDEA的安装与使用(下)(IDEA断点调试,IDEA常用插件)

文章目录 第04章_IDEA的安装与使用&#xff08;下&#xff09;8. 快捷键的使用8.1 常用快捷键8.2 查看快捷键1、已知快捷键操作名&#xff0c;未知快捷键2、已知快捷键&#xff0c;不知道对应的操作名 8.3 自定义快捷键8.4 使用其它平台快捷键 9. IDEA断点调试(Debug)9.1 为什么…

<网络安全>《2 国内主要企业网络安全公司概览(二)》

4 北京天融信科技有限公司(简称天融信) 信息内容LOGO成立日期创始于1995年总部北京市海淀区上地东路1号院3号楼北侧301室背景民营企业是否上市天融信[002212]A股市值99亿主要产品网络安全大数据云服务员工规模6000多人简介天融信科技集团&#xff08;证券代码&#xff1a;0022…

【Chrome】浏览器怎么清除缓存并强制刷新

文章目录 1、正常刷新&#xff1a;正常刷新网页&#xff0c;网页有缓存则采用缓存。 F5 或 刷新键2、强制刷新&#xff1a;忽略缓存刷新&#xff0c;重新下载资源不用缓存。 CtrlF5 或 ShiftF5 或 CtrlShiftR3、在浏览器的设置里面清除所有数据

freeRTOS总结(八)任务相关API函数

1&#xff0c; FreeRTOS任务相关API函数介绍&#xff08;熟悉&#xff09; UBaseType_t uxTaskPriorityGet( const TaskHandle_t xTask ) 获取任务优先级函数 此函数用于获取指定任务的任务优先级&#xff0c;使用该函数需将宏 INCLUDE_uxTaskPriorityGet 置 1 void vTask…

用于垃圾回收的运行时配置选项

反馈 本文内容 指定配置的方法垃圾回收的风格管理资源使用情况大型页面 显示另外 4 个 此页面包含有关 .NET 运行时垃圾回收器 (GC) 设置的信息。 如果你要尝试让正在运行的应用达到最佳性能&#xff0c;请考虑使用这些设置。 然而&#xff0c;在特定情况下&#xff0c;默认…

【动态规划】C++ 算法458:可怜的小猪

作者推荐 视频算法专题 涉及知识点 动态规划 数学 力扣458:可怜的小猪 有 buckets 桶液体&#xff0c;其中 正好有一桶 含有毒药&#xff0c;其余装的都是水。它们从外观看起来都一样。为了弄清楚哪只水桶含有毒药&#xff0c;你可以喂一些猪喝&#xff0c;通过观察猪是否…

精通 Spring REST API:最佳实践

概述 随着数字时代的推进&#xff0c;基于Web的程序已经成为构建交互式应用的关键。客户端与服务器之间的沟通频繁依赖于通过 APIs 获取的网络服务。 使用开源框架Spring&#xff0c;开发者可以有效率地搭建Web服务。本篇文章旨在展示如何利用Spring来构筑一个REST风格的Web服…

基于Java+SpringBoot+vue+element疫情物资捐赠分配系统设计和实现

基于JavaSpringBootvueelement疫情物资捐赠分配系统设计和实现 &#x1f345; 作者主页 央顺技术团队 &#x1f345; 欢迎点赞 &#x1f44d; 收藏 ⭐留言 &#x1f4dd; &#x1f345; 文末获取源码联系方式 &#x1f4dd; &#x1f345; 查看下方微信号获取联系方式 承接各种…

【字符串】【C++算法】828.统计子串中的唯一字符

作者推荐 【动态规划】【map】【C算法】1289. 下降路径最小和 II 本文涉及知识点 子数组&#xff08;串&#xff09; 字符串 LeetCoce828.统计子串中的唯一字符 我们定义了一个函数 countUniqueChars(s) 来统计字符串 s 中的唯一字符&#xff0c;并返回唯一字符的个数。 例…

【pyqt6】用pyqt做一个点菜小程序

用pyqt做一个点菜小程序 前言1.pyqt62. 功能介绍3.程序实现 前言 在本文中&#xff0c;我们将使用 PyQt6&#xff08;Python的GUI库&#xff09;创建一个简单的点菜小程序。该程序允许用户从菜单中选择菜品&#xff0c;将其添加到订单中&#xff0c;并通过点击“下单”按钮查看…

3.postman动态参数、文件上传及断言

一、postman内置动态参数以及自定义的动态参数 postman内置动态参数&#xff1a; {{$timestamp}} 生成当前时间的时间戳 {{$randomint}} 生成0-1000之间的随机数 {{$guid}} 生成随机guid字符串 自定义动态参数&#xff1a; 在请求中pre-req页面下 //手动的获得时间戳 var…

关于鸿蒙系统开源和技术细节的一些探讨

1月18日在深圳举办了“鸿蒙生态千帆启航仪式”&#xff0c;这也是华为鸿蒙开启生态进阶的信号。在政策的叠加下&#xff0c;鸿蒙未来必定是势不可挡的。我们这些程序员也得与时俱进&#xff0c;熟悉鸿蒙的技术和细节&#xff0c;别在经济寒冬里被淘汰了。 官方称 Harmony OS N…

1.24号c++

C绪论 c是c语言的扩充&#xff0c;C包含了C的所有属性&#xff0c;换一句话说&#xff0c;C语言在C中都合法。 C语言编程思想&#xff1a;面向过程 c编程思想&#xff1a;面向对象 可以说在C中一切皆对象。 c的三大属性&#xff1a;封装&#xff0c;继承&#xff0c;多态。…

VMWare扩展Ubuntu LVM卷

当我们在安装程序提示磁盘空间满了时&#xff0c;我们可以通过以下步骤进行空间扩展。 首先是调整虚拟机磁盘大小&#xff0c;注意这里关机后才可编辑 然后是使用df -hl命令&#xff0c;看磁盘占用情况&#xff0c;找到满载的分区 再是使用lsblk查看分区设备名&#xff0c;确定…