news 2026/3/23 1:15:38

Spring 新声明式 HTTP 客户端:HTTP Interface + RestClient,把“调用外部 API”写成接口

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
Spring 新声明式 HTTP 客户端:HTTP Interface + RestClient,把“调用外部 API”写成接口

1. 核心概念:HTTP Service Clients(HTTP Interface)

它的本质是两件事:(Home)

  1. 用接口定义“我要调用的 HTTP API”(方法上标注@GetExchange等)
  2. HttpServiceProxyFactory基于底层 HTTP 客户端(RestClient/WebClient/RestTemplate)生成代理对象

额外有个很实用的点:如果这个 API 是你们自己的服务,服务端的@Controller甚至可以实现同一份接口,做到“契约复用”。(Home)

2. 版本关系:6、6.1、7 分别带来了什么

  • Spring 6:引入接口式的@HttpExchange声明调用能力(Home)
  • Spring 6.1:引入RestClient(新的同步 HTTP 客户端),API 风格像WebClient,底层复用RestTemplate的 converters、拦截器等基础设施(Home)
  • Spring 7:为了解决“接口多了以后 Bean 配置很重复”的问题,加入Registry + 分组(group)的配置模型,并提供@ImportHttpServices自动注册代理 Bean(Home)

3. 最小闭环:写一个接口 + 生成代理(Spring 6+ 都能用)

3.1 定义接口

importorg.springframework.web.service.annotation.GetExchange;importorg.springframework.web.service.annotation.HttpExchange;importorg.springframework.web.bind.annotation.PathVariable;importorg.springframework.web.bind.annotation.RequestParam;@HttpExchange(url="/api")publicinterfaceTodoClient{@GetExchange("/todos/{id}")TodogetTodo(@PathVariable("id")longid);@GetExchange("/todos")List<Todo>list(@RequestParam("owner")Stringowner);}

Spring 文档明确:@HttpExchange可放在类型上做统一配置,方法上用@GetExchange / @PatchExchange ...补齐具体动作;方法参数支持@PathVariable@RequestHeader@RequestParam等。(Home)

3.2 生成代理(以 RestClient 为底座,同步)

importorg.springframework.context.annotation.Bean;importorg.springframework.context.annotation.Configuration;importorg.springframework.web.client.RestClient;importorg.springframework.web.client.support.RestClientAdapter;importorg.springframework.web.service.invoker.HttpServiceProxyFactory;@ConfigurationpublicclassClientConfig{@BeanpublicTodoClienttodoClient(){RestClientrestClient=RestClient.builder().baseUrl("https://example.com").defaultHeader("Accept","application/json").build();HttpServiceProxyFactoryfactory=HttpServiceProxyFactory.builderFor(RestClientAdapter.create(restClient)).build();returnfactory.createClient(TodoClient.class);}}

这就是官方给出的标准套路:RestClientAdapter/WebClientAdapter/RestTemplateAdapter+HttpServiceProxyFactory。(Home)

4. 返回值怎么选:同步 or 响应式,一眼看懂

Spring 文档对“返回值支持哪些类型”给了一个非常清晰的表:(Home)

  • 当底层是RestClient / RestTemplate(同步)时,你可以返回:

    • T(直接反序列化成对象)
    • ResponseEntity<T>(要状态码、头、body)
    • HttpHeadersvoid
  • 当底层是WebClient时,除了上面的同步返回,还支持响应式:Mono<T>Flux<T>Mono<ResponseEntity<T>>

有个实用补充:RestClientAdapter还额外支持InputStreamResponseEntity<InputStream>,适合下载类场景。(Home)

5. 全局错误处理:别在业务里到处 try/catch

默认 4xx/5xx 会抛异常,但你可以在底层客户端统一定制:

  • RestClient.Builder.defaultStatusHandler(...)
  • WebClient.Builder.defaultStatusHandler(...)
  • RestTemplate.setErrorHandler(...)

文档还给了示例代码框架(推荐你把异常映射做在这里,业务层就干净了)。(Home)

另外,如果你希望“404 不算异常,直接返回空对象/NOT_FOUND”,还可以通过adapter decorator做统一策略(文档提供了现成装饰器思路)。(Home)

6. 规模化:接口多了之后,用 Group + Registry 管起来(Spring 7)

当你接入多个外部系统(比如 GitHub、支付、短信、ERP),如果还按“一个接口写一个@Bean createClient”,配置会爆炸。Spring 7 引入了HTTP Service Registry:按 group 组织接口,框架自动生成代理并注册为 Bean。(Home)

6.1 用@ImportHttpServices声明分组(自动注册代理 Bean)

@ImportHttpServices是 Spring 7 新增(javadoc 标注 Since: 7.0),支持types手动列出接口或按包扫描。(Home)

6.2 每个 group 统一配置底层客户端

Spring 文档给出HttpServiceGroupConfigurer的使用方式:你可以按 group 名字定制clientBuilder,也可以对所有 group 做统一处理。(Home)

更关键的是:Spring Boot 还能基于 group 注入“按组的客户端配置属性”;Spring Security 可以加 OAuth;Spring Cloud 可以加负载均衡。(Home)

如果同一接口在多个 group 里各有一份代理(比如两个不同环境/不同租户的 host),你还可以直接从HttpServiceProxyRegistry按 group 拿到指定代理。(Home)

7. 测试怎么做

如果你底层用RestClient,Spring 官方明确提到:可以通过MockRestServiceServer来测试它的使用方式。(Home)
工程上常见做法是:

  • 单元测试:mock 接口代理(因为它就是个接口)
  • 集成测试:MockRestServiceServer / WireMock(把外部服务模拟出来)
  • 契约测试:把接口当“调用契约”,配合服务端的实现做回归验证(尤其适合内部微服务)

8. 最佳实践清单(我建议你直接照这个落地)

  • 每个外部系统一个 group:统一 baseUrl、超时、鉴权 header、日志拦截器
  • DTO 与接口放在单独 module:让“契约”稳定、可复用、可测试
  • 错误处理集中在底层:defaultStatusHandler统一映射业务异常(别散落在 Service 层)(Home)
  • 同步优先用 RestClient:写起来更短更顺,且它就是为了同步场景提供的现代 API(Home)
  • 需要流式/背压/端到端响应式才用 WebClient:接口返回Mono/Flux,避免“响应式里 block”(Home)
版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/3/21 11:04:11

Docker安装Jenkins

docker镜像拉取 docker pull jenkins/jenkins:2.190.3-centos 创建 /opt/jenkins_home 目录 cd /opt mkdir jenkins_home 授权目录 chmod 777 jenkins_home/ 启动容器 docker run -p 8081:8080 -p 50000:50000 -v /opt/jenkins_home:/var/jenkins_home -d --name jenki…

作者头像 李华
网站建设 2026/3/19 10:52:05

再见Jenkins!这款自动化部署工具更强大,还贼带劲!

今天给大家推荐一款好用的 CI/CD 工具「建木」。这是一款面向 DevOps 领域的极易扩展的图形化工具&#xff0c;帮助用户轻松编排各种 DevOps 流程并分发到不同平台执行。 01 项目介绍 相关地址&#xff1a; Gitee&#xff1a;https://gitee.com/jianmu-dev/jianmu 官网&…

作者头像 李华
网站建设 2026/3/16 1:01:59

从原理到实践:现代办公中的传真机使用完全指南

序言在现代信息技术高度发达的今天&#xff0c;许多人可能认为传真机已经是过时的设备。然而&#xff0c;事实并非如此。传真机在许多行业仍然扮演着不可替代的角色&#xff0c;特别是在金融、法律、医疗、房产交易等需要原件确认的领域。不仅如此&#xff0c;随着互联网传真技…

作者头像 李华