问题
在维护一个长时间没更新的项目时,仅升级了 spring-boot-starter-parent
版本至 2.6.x
,导致部分服务调用第三方API(用 openfeign
实现)失效。
项目创建时,以下版本都是最新的:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24
| <parent> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-parent</artifactId> <version>2.2.4.RELEASE</version> <relativePath/> </parent>
<dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-openfeign</artifactId> <version>2.2.4.RELEASE</version> </dependency>
<dependencyManagement> <dependencies> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-dependencies</artifactId> <version>Hoxton.SR3</version> <type>pom</type> <scope>import</scope> </dependency> </dependencies> </dependencyManagement>
|
声明 FeignClient
服务,这个第三方接口是要求表单是 x-www-form-urlencoded
编码的。
这个版本的 Feign
默认并不支持 x-www-form-urlencoded
,通过 LinkedMultiValueMap
将参数放到Body来解决。
1 2 3 4 5 6 7
| @Component @FeignClient(name = "TestService",url = "http://192.168.0.666:8080/oauth2/v2/") public interface TestOAuthAPIServer {
@PostMapping(value = "/token",consumes = MediaType.APPLICATION_FORM_URLENCODED_VALUE) String getAccessToken(@RequestBody LinkedMultiValueMap<String, String> body); }
|
调用服务
1 2 3 4 5
| LinkedMultiValueMap<String, String> body = new LinkedMultiValueMap<>(); body.add("grant_type","xxxxxxxxxxx"); body.add("client_id","xxxxxxxxxxx"); body.add("client_secret","xxxxxxxxxxx"); testOAuthAPIServer.getAccessToken(body);
|
由于 log4j2
的漏洞,紧急将spring-boot-starter-parent
升级到 2.6.x
。
后来发现 openfeign
提交 application/x-www-form-urlencoded
表单的 body
是空的。
解决
查询文档: spring-cloud-openfeign/docs 发现 openfeign
已经更新了很多内容,详细请查看官方文档。
注意:
spring-boot-starter-parent
和 spring-cloud-dependencies
这两个组件的版本最后按照官方的依赖来,请参考:【Table 1. Release train Spring Boot compatibility】
2022年,这里更新所有的组件版本到最新
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24
| <parent> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-parent</artifactId> <version>2.6.2</version> <relativePath/> </parent>
<dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-openfeign</artifactId> <version>3.1.3</version> </dependency>
<dependencyManagement> <dependencies> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-dependencies</artifactId> <version>2021.0.3</version> <type>pom</type> <scope>import</scope> </dependency> </dependencies> </dependencyManagement>
|
声明 FeignClient
服务的Body直接用一个Bean类提交。
1 2 3 4 5 6 7
| @Component @FeignClient(name = "TestService",url = "http://192.168.0.666:8080/oauth2/v2/") public interface TestOAuthAPIServer {
@PostMapping(value = "/token",consumes = MediaType.APPLICATION_FORM_URLENCODED_VALUE) String getAccessToken(@RequestBody MyBody body); }
|
现在的版本已经支持 application/x-www-form-urlencoded
表单,所以声明 Bean类作为表单参数即可。
1 2 3 4 5 6
| @Data public class MyBody { private String grant_type; private String client_id; private String client_secret; }
|