千家信息网

Spring Cloud Feign怎么实现动态URL

发表于:2026-11-03 作者:千家信息网编辑
千家信息网最后更新 2026年11月03日,这篇"Spring Cloud Feign怎么实现动态URL"文章的知识点大部分人都不太理解,所以小编给大家总结了以下内容,内容详细,步骤清晰,具有一定的借鉴价值,希望大家阅读完这篇文章能有所收获,下
千家信息网最后更新 2026年11月03日Spring Cloud Feign怎么实现动态URL

这篇"Spring Cloud Feign怎么实现动态URL"文章的知识点大部分人都不太理解,所以小编给大家总结了以下内容,内容详细,步骤清晰,具有一定的借鉴价值,希望大家阅读完这篇文章能有所收获,下面我们一起来看看这篇"Spring Cloud Feign怎么实现动态URL"文章吧。

需求描述

动态URL的需求场景:

有一个异步服务S,它为其他业务(业务A,业务B...)提供异步服务接口,在这些异步接口中执行完指定逻辑之后需要回调相应业务方的接口。

这在诸如风控审核,支付回调等场景中挺常见的。

那么,这个回调业务方接口该怎么实现呢?
首先,需要约定好回调这些业务方接口时的请求方法(通常为POST请求),请求参数格式(通常为JSON格式,方便扩展)和响应消息格式(通常为JSON格式)。

具体调用业务方接口时有2种办法来实现:
1.在服务S的每一个异步接口中都独立写一套回调的逻辑
2.因为回调的方法类型和参数格式是约定好的,所以可以写一个统一的公共回调方法即可

方法1显然不是最优选择,这样做会带来大量重复的代码逻辑,而且非常不利用后期维护和升级。
方法2的实现更加灵活一些,便于扩展。

如下将阐述如何使用Feign框架定义一个公共的回调方法。

具体实现

在Feign中能实现动态URL的基础是框架本身就支持,只需要在接口方法中包含一个java.net.URI参数,Feign就会将该参数值作为目标主机地址,详见Interface Annotations一节中的"Overriding the Request Line"部分。

如下将分别阐述独立使用Feign和使用Spring Cloud OpenFeign实现定义统一的回调方法。

使用Feign定义统一回调方法

定义统一回调方法:

public interface CallbackAPI {    /**     * 统一回调接口方法,请求消息体格式为JSON,响应消息体格式也为JSON     * @param host 接口主机地址,如:http://localhost:8080,该参数是实现动态URL的关键     * @param path 接口路径,如:/test/hello     * @param queryMap 动态URL参数集合     * @param body 请求消息体对象     * @return     */    @RequestLine("POST {path}")    @Headers({        "Content-Type: application/json",        "Accept: application/json"    })    Object callback(URI host, @Param("path") String path, @QueryMap Map queryMap, Subject body);   /**     * 统一回调接口方法,请求消息体格式为JSON,响应消息体格式也为JSON     * @param uri 完整的请求路径地址,如:http://localhost:8080/test/hello     * @param queryMap 动态URL参数集合     * @param body 请求消息体对象     * @return     */    @RequestLine("POST")    @Headers({        "Content-Type: application/json",        "Accept: application/json"    })    Object callback(URI uri, @QueryMap Map queryMap, Subject body);}

调用回调方法:

CallbackAPI callbackAPI = Feign.builder()        .encoder(new GsonEncoder())        .decoder(new GsonDecoder())        .logger(new Slf4jLogger())        .logLevel(Logger.Level.FULL)        .target(CallbackAPI.class, "EMPTY"); // 注意:这里的url参数不能为空字符串,但是可以设置为任意字符串值,在这里设置为"EMPTY"String uri = "http://localhost:8080";Map queryMap = new HashMap<>(0);queryMap.put("k", "v");Subject body = Subject.builder().id(10).build();// 请求主机地址与路径分开传递callbackAPI.callback(URI.create(uri), "/test/simple/post/json", queryMap, body);// 直接将完整请求完整路径作为uri类型参数callbackAPI.callback(URI.create("http://localhost:8080/test/simple/post/json"), queryMap, body);

详细请求日志如下:

2022-02-14 15:32:13,118 DEBUG [main] f.Logger [Slf4jLogger.java:72] [CallbackAPI#callback] ---> POST http://localhost:8080/test/simple/post/json?k=v HTTP/1.1
2022-02-14 15:32:13,118 DEBUG [main] f.Logger [Slf4jLogger.java:72] [CallbackAPI#callback] Accept: application/json
2022-02-14 15:32:13,118 DEBUG [main] f.Logger [Slf4jLogger.java:72] [CallbackAPI#callback] Content-Length: 14
2022-02-14 15:32:13,118 DEBUG [main] f.Logger [Slf4jLogger.java:72] [CallbackAPI#callback] Content-Type: application/json
2022-02-14 15:32:13,118 DEBUG [main] f.Logger [Slf4jLogger.java:72] [CallbackAPI#callback]
2022-02-14 15:32:13,118 DEBUG [main] f.Logger [Slf4jLogger.java:72] [CallbackAPI#callback] {
"id": 10
}
2022-02-14 15:32:13,118 DEBUG [main] f.Logger [Slf4jLogger.java:72] [CallbackAPI#callback] ---> END HTTP (14-byte body)
2022-02-14 15:32:13,153 DEBUG [main] f.Logger [Slf4jLogger.java:72] [CallbackAPI#callback] <--- HTTP/1.1 200 (32ms)
2022-02-14 15:32:13,153 DEBUG [main] f.Logger [Slf4jLogger.java:72] [CallbackAPI#callback] connection: keep-alive
2022-02-14 15:32:13,153 DEBUG [main] f.Logger [Slf4jLogger.java:72] [CallbackAPI#callback] content-length: 9
2022-02-14 15:32:13,153 DEBUG [main] f.Logger [Slf4jLogger.java:72] [CallbackAPI#callback] content-type: application/json
2022-02-14 15:32:13,153 DEBUG [main] f.Logger [Slf4jLogger.java:72] [CallbackAPI#callback] date: Mon, 14 Feb 2022 07:32:13 GMT
2022-02-14 15:32:13,153 DEBUG [main] f.Logger [Slf4jLogger.java:72] [CallbackAPI#callback] keep-alive: timeout=60
2022-02-14 15:32:13,153 DEBUG [main] f.Logger [Slf4jLogger.java:72] [CallbackAPI#callback]
2022-02-14 15:32:13,153 DEBUG [main] f.Logger [Slf4jLogger.java:72] [CallbackAPI#callback] {"id":10}
2022-02-14 15:32:13,153 DEBUG [main] f.Logger [Slf4jLogger.java:72] [CallbackAPI#callback] <--- END HTTP (9-byte body)

显然,动态设置目标主机和接口路径已经成功了。

使用Spring Cloud Feign定义统一回调方法

在Spring Cloud Feign中实现定义统一回调接口方法可以直接使用注解进行标注,非常简洁。

定义统一回调方法:

// 注意:这里的url属性值不能为空字符串,但是可以设置为任意字符串值,在这里设置为"EMPTY"@FeignClient(value = "CallbackAPI", url = "EMPTY", configuration = CallbackConfiguration.class)public interface CallbackAPI {    /**     * 统一回调接口方法,请求消息体格式为JSON,响应消息体格式也为JSON     * @param host 接口主机地址,如:http://localhost:8080     * @param path 接口路径,如:/test/hello     * @param queryMap 动态URL参数集合     * @param body 请求消息体对象     * @return     */    @RequestMapping(value = "{path}", method = RequestMethod.POST, consumes = MediaType.APPLICATION_JSON_VALUE, produces = MediaType.APPLICATION_JSON_VALUE)    Object callback(URI host,                    @PathVariable("path") String path,                    @SpringQueryMap Map queryMap,                    @RequestBody Object body);    /**     * 统一回调接口方法,请求消息体格式为JSON,响应消息体格式也为JSON     * @param uri 完整的请求路径地址,如:http://localhost:8080/test/hello     * @param queryMap 动态URL参数集合     * @param body 请求消息体对象     * @return     */    @RequestMapping(method = RequestMethod.POST, consumes = MediaType.APPLICATION_JSON_VALUE, produces = MediaType.APPLICATION_JSON_VALUE)    Object callback(URI uri,                    @SpringQueryMap Map queryMap,                    @RequestBody Object body);}// 回调接口配置public class CallbackConfiguration {    @Bean    public Encoder feignEncoder() {        return new GsonEncoder();    }    @Bean    public Decoder feignDecoder() {        return new GsonDecoder();    }    @Bean    public Retryer feignRetryer() {        return new Retryer.Default();    }    @Bean    public Logger feignLogger() {        return new Slf4jLogger();    }    @Bean    public Logger.Level feignLoggerLevel() {        return Logger.Level.FULL;    }}

调用回调方法:

@AutowiredCallbackAPI callbackAPI;String uri = "http://localhost:8080";Map queryMap = new HashMap<>(0);queryMap.put("k", "v");Subject subject = Subject.builder().id(10).build();// 请求主机地址与路径分开传递this.callbackAPI.callback(URI.create(uri), "/test/simple/post/json", queryMap, subject);// 直接将完整请求完整路径作为uri类型参数this.callbackAPI.callback(URI.create("http://localhost:8080/test/simple/post/json"), queryMap, subject);

详细请求日志如下:

2022-02-14 15:38:38.908 DEBUG 20184 --- [ main] feign.Logger : [CallbackAPI#callback] ---> POST http://localhost:8080/test/simple/post/json?k=v HTTP/1.1
2022-02-14 15:38:38.908 DEBUG 20184 --- [ main] feign.Logger : [CallbackAPI#callback] Accept: application/json
2022-02-14 15:38:38.908 DEBUG 20184 --- [ main] feign.Logger : [CallbackAPI#callback] Content-Length: 14
2022-02-14 15:38:38.908 DEBUG 20184 --- [ main] feign.Logger : [CallbackAPI#callback] Content-Type: application/json
2022-02-14 15:38:38.908 DEBUG 20184 --- [ main] feign.Logger : [CallbackAPI#callback]
2022-02-14 15:38:38.908 DEBUG 20184 --- [ main] feign.Logger : [CallbackAPI#callback] {
"id": 10
}
2022-02-14 15:38:38.908 DEBUG 20184 --- [ main] feign.Logger : [CallbackAPI#callback] ---> END HTTP (14-byte body)
2022-02-14 15:38:38.924 DEBUG 20184 --- [ main] s.n.www.protocol.http.HttpURLConnection : sun.net.www.MessageHeader@539c48307 pairs: {POST /test/simple/post/json?k=v HTTP/1.1: null}{Accept: application/json}{Content-Type: application/json}{User-Agent: Java/1.8.0_271}{Host: localhost:8080}{Connection: keep-alive}{Content-Length: 14}
2022-02-14 15:38:38.945 DEBUG 20184 --- [ main] s.n.www.protocol.http.HttpURLConnection : sun.net.www.MessageHeader@681e913c6 pairs: {null: HTTP/1.1 200}{Content-Type: application/json}{Content-Length: 9}{Date: Mon, 14 Feb 2022 07:38:38 GMT}{Keep-Alive: timeout=60}{Connection: keep-alive}
2022-02-14 15:38:38.952 DEBUG 20184 --- [ main] feign.Logger : [CallbackAPI#callback] <--- HTTP/1.1 200 (37ms)
2022-02-14 15:38:38.952 DEBUG 20184 --- [ main] feign.Logger : [CallbackAPI#callback] connection: keep-alive
2022-02-14 15:38:38.952 DEBUG 20184 --- [ main] feign.Logger : [CallbackAPI#callback] content-length: 9
2022-02-14 15:38:38.952 DEBUG 20184 --- [ main] feign.Logger : [CallbackAPI#callback] content-type: application/json
2022-02-14 15:38:38.952 DEBUG 20184 --- [ main] feign.Logger : [CallbackAPI#callback] date: Mon, 14 Feb 2022 07:38:38 GMT
2022-02-14 15:38:38.953 DEBUG 20184 --- [ main] feign.Logger : [CallbackAPI#callback] keep-alive: timeout=60
2022-02-14 15:38:38.953 DEBUG 20184 --- [ main] feign.Logger : [CallbackAPI#callback]
2022-02-14 15:38:38.955 DEBUG 20184 --- [ main] feign.Logger : [CallbackAPI#callback] {"id":10}
2022-02-14 15:38:38.955 DEBUG 20184 --- [ main] feign.Logger : [CallbackAPI#callback] <--- END HTTP (9-byte body)

从日志详情看,在Spring Cloud Feign中同样实现动态URL的效果。

以上就是关于"Spring Cloud Feign怎么实现动态URL"这篇文章的内容,相信大家都有了一定的了解,希望小编分享的内容对大家有帮助,若想了解更多相关的知识内容,请关注行业资讯频道。

接口 方法 格式 消息 动态 参数 统一 路径 业务 地址 主机 内容 对象 日志 类型 逻辑 服务 场景 字符 字符串 数据库的安全要保护哪些东西 数据库安全各自的含义是什么 生产安全数据库录入 数据库的安全性及管理 数据库安全策略包含哪些 海淀数据库安全审计系统 建立农村房屋安全信息数据库 易用的数据库客户端支持安全管理 连接数据库失败ssl安全错误 数据库的锁怎样保障安全 互联网科技产业 苏州找大状互联网科技有限公司 互联网科技公司税收优惠 互联网金融 金融科技 互联网科技小贷 广州凡科互联网科技 无锡溥仪互联网科技有限公司 哈尔滨秒房互联网科技有限公司 云创客互联网科技公司 中化能源互联网科技招聘 南山科技园互联网公司有哪些 科技类公司包括互联网吗 互联网金融科技名词解释 中和天地互联网科技有限公司 恒生互联网科技业指数调整周期 高科技互联网套路 风投北京互联网科技 江苏互联网智能科技产品出厂价 互联网高科技绘画 武汉亿视互联网科技有限公司 为想互联网科技怎么样 善班互联网科技有限公司 掌上梦互联网科技 厦门比较好的科技互联网公司 上海宁丞科技互联网 卓翼科技产业互联网合作 杭州披云加互联网科技有限公司 国产互联网科技公司 科技和互联网行业的特点 玉溪新华互联网科技怎么选
0