这篇“SpringCloudFeign怎么实现动态URL”文章的知识点大部分人都不太理解,所以小编给大家总结了以下内容,内容详细,步骤清晰,具有一定的借鉴价值,希望大家阅读完这篇文章能有所收获,下面我们一起来看看这篇“SpringCloudFeign怎么实现动态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定义统一回调方法

定义统一回调方法:

publicinterfaceCallbackAPI{/***统一回调接口方法,请求消息体格式为JSON,响应消息体格式也为JSON*@paramhost接口主机地址,如:http://localhost:8080,该参数是实现动态URL的关键*@parampath接口路径,如:/test/hello*@paramqueryMap动态URL参数集合*@parambody请求消息体对象*@return*/@RequestLine("POST{path}")@Headers({"Content-Type:application/json","Accept:application/json"})Objectcallback(URIhost,@Param("path")Stringpath,@QueryMapMap<String,Object>queryMap,Subjectbody);/***统一回调接口方法,请求消息体格式为JSON,响应消息体格式也为JSON*@paramuri完整的请求路径地址,如:http://localhost:8080/test/hello*@paramqueryMap动态URL参数集合*@parambody请求消息体对象*@return*/@RequestLine("POST")@Headers({"Content-Type:application/json","Accept:application/json"})Objectcallback(URIuri,@QueryMapMap<String,Object>queryMap,Subjectbody);}

调用回调方法:

CallbackAPIcallbackAPI=Feign.builder().encoder(newGsonEncoder()).decoder(newGsonDecoder()).logger(newSlf4jLogger()).logLevel(Logger.Level.FULL).target(CallbackAPI.class,"EMPTY");//注意:这里的url参数不能为空字符串,但是可以设置为任意字符串值,在这里设置为“EMPTY”Stringuri="http://localhost:8080";Map<String,Object>queryMap=newHashMap<>(0);queryMap.put("k","v");Subjectbody=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)publicinterfaceCallbackAPI{/***统一回调接口方法,请求消息体格式为JSON,响应消息体格式也为JSON*@paramhost接口主机地址,如:http://localhost:8080*@parampath接口路径,如:/test/hello*@paramqueryMap动态URL参数集合*@parambody请求消息体对象*@return*/@RequestMapping(value="{path}",method=RequestMethod.POST,consumes=MediaType.APPLICATION_JSON_VALUE,produces=MediaType.APPLICATION_JSON_VALUE)Objectcallback(URIhost,@PathVariable("path")Stringpath,@SpringQueryMapMap<String,Object>queryMap,@RequestBodyObjectbody);/***统一回调接口方法,请求消息体格式为JSON,响应消息体格式也为JSON*@paramuri完整的请求路径地址,如:http://localhost:8080/test/hello*@paramqueryMap动态URL参数集合*@parambody请求消息体对象*@return*/@RequestMapping(method=RequestMethod.POST,consumes=MediaType.APPLICATION_JSON_VALUE,produces=MediaType.APPLICATION_JSON_VALUE)Objectcallback(URIuri,@SpringQueryMapMap<String,Object>queryMap,@RequestBodyObjectbody);}//回调接口配置publicclassCallbackConfiguration{@BeanpublicEncoderfeignEncoder(){returnnewGsonEncoder();}@BeanpublicDecoderfeignDecoder(){returnnewGsonDecoder();}@BeanpublicRetryerfeignRetryer(){returnnewRetryer.Default();}@BeanpublicLoggerfeignLogger(){returnnewSlf4jLogger();}@BeanpublicLogger.LevelfeignLoggerLevel(){returnLogger.Level.FULL;}}

调用回调方法:

@AutowiredCallbackAPIcallbackAPI;Stringuri="http://localhost:8080";Map<String,Object>queryMap=newHashMap<>(0);queryMap.put("k","v");Subjectsubject=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的效果。

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