springboot学习第11期 - @HttpExchange

@HttpExchange 是什么

@HttpExchange 是springboot3提供的声明式发送HTTP请求客户端工具。

使用

第一步:根据第三方服务的接口声明

假如有第三方接口api:http://localhost:8080/api/hello/{id}?name={name},返回String类型。

按照上面的格式,创建第三方Client接口:

java 复制代码
@HttpExchange("/api/hello")
public interface ThirdClient {

    @GetExchange("/{id}")
    String sayHello(@PathVariable("id") int id, 
                    @RequestParam(value = "name", defaultValue = "World") String name
    );

    // 也可以返回 ResponseEntity, 如果想要获取响应其他信息的话
    // @GetExchange("/{id}")
    // ResponseEntity<String> sayHello(@PathVariable("id") int id, 
    //                 @RequestParam(value = "name", defaultValue = "World") String name
    // );

}

第二步:注入实现类

java 复制代码
@Configuration
public class HttpExchangeConfig {

    @Bean
    public ThirdClient thirdClient(RestClient.Builder builder) {
        RestClient restClient = builder
                .baseUrl("http://localhost:8080")
                .build();

        HttpServiceProxyFactory factory = HttpServiceProxyFactory
                .builderFor(RestClientAdapter.create(restClient))
                .build();

        return factory.createClient(ThirdClient.class);
    }
}

第三步:调用

java 复制代码
@Autowired
private ThirdClient thirdClient;


String s = thirdClient.sayHello(1, "aaa");

异常处理

本质上还是引用了RestClient发送请求,所以异常还是和RestClient异常一样。

通用异常是 RestClientException

4xx异常:HttpClientErrorException

5xx异常:HttpServerErrorException

网络错误:ResourceAccessException

重试

可以结合 spring retry 注解达到重试的效果

java 复制代码
@HttpExchange("/api/hello")
public interface ThirdClient {

    @GetExchange("/{id}")
    @Retryable(retryFor = {RestClientException.class}, noRetryFor = {HttpClientErrorException.class}, maxAttempts = 3, backoff = @Backoff(delay = 5000), listeners = {"customRetryListener"})
    ResponseEntity<String> sayHello(@PathVariable("id") int id, @RequestParam(value = "name", defaultValue = "World") String name);

}

这里还注入了一个自定义重试监听器,当执行重试操作的时候,可以打印一些自定义日志。

java 复制代码
@Component
public class CustomRetryListener implements RetryListener {
    private static final Logger log = LoggerFactory.getLogger(CustomRetryListener.class);

    @Override
    public <T, E extends Throwable> boolean open(RetryContext context, RetryCallback<T, E> callback) {
        // 第一次调用前触发
        log.info("开始重试操作 - 方法: {}", context.getAttribute(RetryContext.NAME));
        return true;
    }

    @Override
    public <T, E extends Throwable> void close(RetryContext context, RetryCallback<T, E> callback, Throwable throwable) {
        // 最后一次重试结束后触发(无论成功失败)
        if (throwable != null) {
            log.error("重试结束,最终失败 - 方法: {}, 异常: {}", context.getAttribute(RetryContext.NAME), throwable.toString());
        } else {
            log.info("重试结束,成功 - 方法: {}, 重试次数: {}", context.getAttribute(RetryContext.NAME), context.getRetryCount());
        }
    }

    @Override
    public <T, E extends Throwable> void onError(RetryContext context, RetryCallback<T, E> callback, Throwable throwable) {
        // 每次重试失败后触发
        log.warn("重试失败 - 方法: {}, 第 {} 次重试, 异常: {}",
                context.getAttribute(RetryContext.NAME),
                context.getRetryCount(),
                throwable.toString());
    }
}
相关推荐
RuoyiOffice1 小时前
Spring AI+Vue3 企业知识库设计:让每个答案有依据,让每份资料守住权限
java·spring boot·vue3·rag·企业知识库·spring ai·ruoyi office
凤山老林13 小时前
Spring Boot 接入国密 SM2/SM3/SM4 的一些实践记录
spring boot·后端·python
伯恩bourne14 小时前
Spring Boot Bean 注册的两种方式:@Component 家族 vs @Configuration + @Bean
java·spring boot·后端
省钱兄--zs14 小时前
深圳24小时自助健身房软硬件解决方案实战指南与开发流程详解
java·数据仓库·spring boot·小程序·架构
silvamux_18 小时前
Spring Boot 调用大模型 api 最小可跑教程
java·spring boot·后端
今年下半年18 小时前
【Spring Boot 】通过 OpenFeign 请求第三方接口
java·spring boot·后端·openfeign
三翼鸟数字化技术团队18 小时前
Springboot + WebFlux + Disruptor 实现数据转发
java·spring boot
今年下半年20 小时前
【短信发送】Spring Boot整合多种短信接口的实现(附源码)
java·spring boot·后端·sms·qcloudsms
ly768920 小时前
PostgreSQL JSONB 在 Spring Boot 中的读写边界:从 JDBC 类型映射到 GIN 索引失效
spring boot·postgresql·gin·jsonb·pgjdbc·gin 索引
IT研究室21 小时前
最新计算机毕业设计选题推荐-基于spring boot的美食配送平台-网站-文档指导-Java-springboot
java·spring boot·课程设计