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

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

相关推荐
浅念同学1 小时前
算法-常见数据结构设计
java·数据结构·算法
杰哥在此3 小时前
Java面试题:讨论持续集成/持续部署的重要性,并描述如何在项目中实施CI/CD流程
java·开发语言·python·面试·编程
咖啡煮码3 小时前
深入剖析Tomcat(十五、十六) 关闭钩子,保证Tomcat的正常关闭
java·tomcat
C.C3 小时前
java IO流(1)
java·开发语言
MasterSpring4 小时前
spring cloud gateway客户端websocket断开连接,服务侧连接没有关闭的问题处理
websocket·spring cloud·gateway
刘铸纬5 小时前
Golang中defer和return顺序
开发语言·后端·golang
黑头!5 小时前
Tomcat注册为服务之后 运行时提示JVM异常
java·jvm·tomcat
袁震5 小时前
Java---Mybatis详解二
java·开发语言·mybatis
《黑巧克力》5 小时前
【JavaEE】多线程进阶
java·spring·java-ee·maven·dubbo·idea
idealzouhu6 小时前
函数式接口的定义及常见类型
java