FeignClient中通过API调用Gitlab中文件路径等问题的解决方案

通过API调用Gitlab中文件路径等问题的解决方案

一、前言

通过gitlab的API获取gitiab文件相关操作时,例如,通过API访问gitlab仓库中某个文件夹下面的文件(例:xx仓库/app/text.js)。通过gitiab官方API文档要求文件路径需进行url编码,即url中的/编码为%2F,.编码为%2E,以此和url请求路径区分开(如:projects/280 repository/files/app%2Ftext%2Ejs)

获取gitlab仓库中文档的api

GET /projects/:id/repository/files/:file_path/raw

官方文档的步骤来,使用curl命令在控制台中测试一下,看该命令是否生效

curl --header "PRIVATE-TOKEN: <your_access_token>" "https://gitlab.example.com/api/v4/projects/13083/repository/files/app%2Fmodels%2Fkey%2Erb/raw?ref=master"

但是,在微服务的开发中,通常会使用FeignClient的方式来调用其他服务。

调用的时候会将文件路经flePath参数使用@PathVariable注解用于URL占位,filePath= app%2Ftext.js 如下所示:

GetMapping(value="/projects/{projectId}/repository/files/{file_path}/raw")
GitlabFileDTO getRawFile(@PathVariable(value = "projectid") String projectid,
@PathVariable(value = "file_path") String filePath, @RequestParam(value = "access_token") String token, @RequestParam(value = "ref") String ref);

我在feignClient把相关接口写好之后,测试了半天,一直给我报错。一步一步debug。先是在控制台中使用curl测试没有问题,于是怀疑是不是路径出了问题。
于是把feignClient的调用日志打开.

FeignClient打印请求日志可以看看这里。

c语言,坑啊。

查看调用日志,打印URL为:

projects/280/repository/fles/app/text.js?ref=master

这就是说,之前给/,. 编码,但是经过feignclient之后,feignClient又给我解码了。

(@RequestParam注解却不会将%2F解码为/,下文解释原因),因此调用这个查看文件的api会失败,通过查看Feign源码,我们很容易解决这个疑惑。

二、解决方案

Feign RequestTemplate 中 resolve 方法在构建uri时,首先处理ur中占位符参数,即@PathVariable定义的,其中uriTemplate.expand(variables)方法中 expanded.replaceAll("%2F","/")%2F转成/。因此路经中的%2F会自动解码。接着再解析query参数,即URL?后面通过@RequestParam定义的参数,URL再通过字符串拼接连接在一起,因此@RequestParam参数不会自动解码。

有一种简单的解决方案可以在调用Feign client之前将/换成%2f(F小写),通过以上代码可知可以跳过这里的替换,但是下面提供了更好的方法解决这个问题。

通过查看源码我们可以发现,只有当this.encodeSlash=true时会进行替换,因此通过设置encodeslash/decodeSlash这两个标志的值可以控制url path变量是否需要解码。控制这两个标志只有使用Feign原生的@RequestLine注解。
Feign默认使用的是Springmvc注解(就是RequestMapping 之类的 ,所以需要通过新增一个配置类来修改其“契约”,以便调用Feign原生的注解。

public class GitlabFileFeignclientConfig {
@Bean
public Contract feignContract(){
return new Contract.Default();
}

配置完成后即可使用@RequestLine注解,写法如下例所示:

@RequestLine(value="GET/projects/{projectId}/repository/files/{file_path}?access_token={access_token}&ref={ref)", decodeSlash = false)

说明:

  1. 请求方法GET后有空格;
  2. 不能使用Spring注解@RequestHeader,@PathVariable,@RequestParam等,可使用Feign注解@Param,@Headers等
  3. 一定要设置decodeSlash为false才不会进行解码;
  4. 因为用了不同的“契约”,需要新写一个类使用@RequestLine,并进行配置
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值