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))

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

相关推荐
V+zmm1013423 分钟前
基于微信小程序的乡村政务服务系统springboot+论文源码调试讲解
java·微信小程序·小程序·毕业设计·ssm
Oneforlove_twoforjob1 小时前
【Java基础面试题025】什么是Java的Integer缓存池?
java·开发语言·缓存
xmh-sxh-13141 小时前
常用的缓存技术都有哪些
java
搬码后生仔1 小时前
asp.net core webapi项目中 在生产环境中 进不去swagger
chrome·后端·asp.net
迷糊的『迷』1 小时前
vue-axios+springboot实现文件流下载
vue.js·spring boot
凡人的AI工具箱1 小时前
每天40分玩转Django:Django国际化
数据库·人工智能·后端·python·django·sqlite
AiFlutter1 小时前
Flutter-底部分享弹窗(showModalBottomSheet)
java·前端·flutter
J不A秃V头A2 小时前
IntelliJ IDEA中设置激活的profile
java·intellij-idea
DARLING Zero two♡2 小时前
【优选算法】Pointer-Slice:双指针的算法切片(下)
java·数据结构·c++·算法·leetcode
Lx3522 小时前
Pandas数据重命名:列名与索引为标题
后端·python·pandas