SpringCloud OpenFeign 踩坑总结

目录

一、OpenFeign的基本使用

1、配置依赖

2、编写接口

3、服务调用者添加启用注解

4、在服务调用者里调用

[二、踩坑一:401 认证错误](#二、踩坑一:401 认证错误)

[三、踩坑二:403 请求方式错误](#三、踩坑二:403 请求方式错误)

四、踩坑三:List不能正常传参


一、OpenFeign的基本使用

1、配置依赖

XML 复制代码
         <!--OpenFeign-->
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-openfeign</artifactId>
        </dependency>


        <!--web服务器依赖  可选-->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>

2、编写接口

一般OpenFeign的调用逻辑是:服务提供者编写好restful访问接口,如:

java 复制代码
    @GetMapping("/pub/x")
    public String test() {
        return "OK";
    }

    @GetMapping("/publicList")
    public R<List<SysUser>> queryPublicList(@RequestParam List<String> ids, 
    @RequestHeader("Authorization") String token) {
        return R.ok(sysUserService.queryPublicList(ids));
    }

注:服务提供者不需要引入OpenFeign

服务调用者了书写Feign的接口, 如:

java 复制代码
@FeignClient(name = ServerNameConstants.SYSTEM_SERVER, path = "/sysUsers")
public interface SysUserFeign {
    @GetMapping("/publicList")
    R<List<SysUserDto>> queryPublicList(@RequestParam("ids") List<String> ids, @RequestHeader("Authorization") String token);

    @GetMapping("/pub/x")
    String test();
}

只得注意的是:feign接口应与提供者的controller接口完全对应。

3、服务调用者添加启用注解

在服务调用者的启动类上添加注解:

java 复制代码
@EnableFeignClients

4、在服务调用者里调用

在组件里引用:

java 复制代码
    @Autowired
    private SysUserFeign sysUserFeign;
java 复制代码
R<List<SysUserDto>> res = sysUserFeign.queryPublicList(Collections.singletonList(String.valueOf(ids)), token);
java 复制代码
sysUserFeign.test()

这样调用就可以在服务器通过restful http请求的方式ribbon负载均衡访问到对应接口了。

二、踩坑一:401 认证错误

由于我的微服务配置了Oauth2来进行权限访问,直接访问认证后才能访问的接口会报401未授权。

最终,我的解决方法是通过在接口上加上@RequestHeader("Authorization") String token来解决问题:每次调用feign接口时我都将访问携带的请求头给他加上,这样成功解决了认证问题。

三、踩坑二:403 请求方式错误

在我刚解决401后,服务器又报403请求方式错误,这不搞心态吗。解决方案:Feign接口会将接口转换成http形式,这就要我们注意接口上的@RequestParam、@RequestBody这些参数不能少,准确使用。

四、踩坑三:List<Long>不能正常传参

原本的服务提供者需要的参数为 @RequestParam List<Long> ids,但在服务调用者调用此feign接口时出现情况如下:

传入的List数据将接口参数变为这样:

http://my-server/xxxx?ids=100\&ids=101\&ids=102

这个问题就很离谱,理论上应该是这个格式:

http://my-server/xxxx?ids=100,101,102

最终,我的解决方案是将List<Long>直接改为List<String>

feign传参时也只传长度为1的List参数合并参数:

java 复制代码
    for (MGPltTenderComment comment : comments) {
            if (ids.toString().equals("")) {
                ids = new StringBuilder(myId);
            } else {
                ids.append(",").append(myId);
            }
        }

        R<List<SysUserDto>> res =      sysUserFeign.queryPublicList(Collections.singletonList(String.valueOf(ids)), token);

关键:Collections.singletonList(String.valueOf(ids))

至此,总结完毕,问题也全部解决!

相关推荐
来自旧金山的勇士12 分钟前
WSL->Ubunut安装Redis
后端
大葱白菜14 分钟前
Java Set 集合详解:从基础语法到实战应用,彻底掌握去重与唯一性集合
java·后端
大葱白菜15 分钟前
Java Map 集合详解:从基础语法到实战应用,彻底掌握键值对数据结构
java·后端
添乱15 分钟前
「Java案例」判断是否是闰年的方法
java
FG.20 分钟前
Day22
java·面试
小猪乔治爱打球21 分钟前
[Golang修仙之路] 算法专题:回溯(递归)
后端·面试
菜鸟的迷茫22 分钟前
Redis 缓存雪崩、穿透、击穿面试题深度解析与 Spring Boot 实战代码示例
java
小马爱打代码27 分钟前
微服务中token鉴权设计的4种方式
微服务·云原生·架构
昵称为空C29 分钟前
SpringBoot数据存储时区选择,符合国际化和特定时区方案
spring boot·后端
曾经的三心草31 分钟前
微服务的编程测评系统3-加密-日志-apifox-nacos-全局异常
微服务·云原生·架构