目录
[二、踩坑一:401 认证错误](#二、踩坑一:401 认证错误)
[三、踩坑二:403 请求方式错误](#三、踩坑二:403 请求方式错误)
一、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))
至此,总结完毕,问题也全部解决!