使用 Feign 实现声明式 REST 调用

使用 Feign 实现声明式 REST 调用

一、基本使用

1、为当前项目引入 Feign

<!-- 声明书 Rest 调用 Feign -->
<dependency>
      <groupId>org.springframework.cloud</groupId>
      <artifactId>spring-cloud-starter-openfeign</artifactId>
</dependency>
<!-- end -->

2、在 application.java 启动类处添加 @EnableFeignClients 注解。

3、编写 ServerClient,例如针对 user-info-server 服务编写 UserInfoServerClient 如下:

@FeignClient(name = "user-info-server")
public interface UserInfoServerClient
{
    /**
     * user-info-server 使用情况
     * @return
     */
    @RequestMapping(value = "/sys/usage",method = RequestMethod.GET)
    public Object usage();
}

4、在项目中直接自动注入 UserInfoServerClient 即可使用该接口中的方法实现远程调用。

二、进阶使用

上述方法只适合于那些不需要权限就能无限制访问的接口,如果遇到需要授权才能访问的接口呢?

1、为当前项目引入 Feign

<!-- 声明书 Rest 调用 Feign -->
<dependency>
      <groupId>org.springframework.cloud</groupId>
      <artifactId>spring-cloud-starter-openfeign</artifactId>
</dependency>
<!-- end -->

2、去掉 @EnableFeignClients 注释 和 @FeignClient(name = "user-info-server")

3、配置 UserInfoServerClientExt 类,代码如下:

package com.zolmk.ms.userregisterserver.rpc.impl;

import com.zolmk.ms.userregisterserver.rpc.UserInfoServerClient;
import feign.Client;
import feign.Contract;
import feign.Feign;
import feign.Logger;
import feign.auth.BasicAuthRequestInterceptor;
import feign.codec.Decoder;
import feign.codec.Encoder;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cloud.openfeign.FeignClientsConfiguration;
import org.springframework.context.annotation.Import;
import org.springframework.stereotype.Component;

/**
 * @author : zolmk
 * @project : user-register-server
 * @date : 2020/11/28 19:48
 **/
@Import(FeignClientsConfiguration.class) // 导入 FeignClient 的默认配置,该配置中自动装载了 Decoder Encoder Client Contract。
@Component	// 将其作为一个组件
public class UserInfoServerClientExt
{
    private UserInfoServerClient userClient; // 不同权限的访问客户端
    private UserInfoServerClient adminClient; // 这里放两个仅作为示例

    @Autowired
    public UserInfoServerClientExt(Decoder decoder, Encoder encoder, Client client, Contract contract)
    {
        this.userClient = Feign.builder().client(client).encoder(encoder).decoder(decoder)
                .logLevel(Logger.Level.FULL).logger(new Logger.ErrorLogger()) //配置日志输出及日志等级
                .contract(contract)
                .requestInterceptor(new BasicAuthRequestInterceptor("user","user")) // 授权用户密码
                .target(UserInfoServerClient.class,"http://user-info-server/"); // 绑定 FeignClient 接口 和 微服务域名
        this.adminClient = Feign.builder().client(client).encoder(encoder).decoder(decoder).contract(contract)
                .logLevel(Logger.Level.FULL).logger(new Logger.ErrorLogger())
                .requestInterceptor(new BasicAuthRequestInterceptor("admin","admin"))
                .target(UserInfoServerClient.class,"http://user-info-server/");
    }
    public UserInfoServerClient getUserClient()
    {
        return this.userClient;
    }
    public UserInfoServerClient getAdminClient()
    {
        return this.adminClient;
    }
}

4、然后在 Controller 中自动装载 UserInfoServerClientExt 使用其中的 UserInfoServer 对象即可访问需要授权的接口。

5、Get 请求多参数的 URL

// 参数少的时候
@RequestMapping(value="/get",method = RequestMethod.GET)
public User get(@RequestParam("id")String id,@RequestParam("name")String name);
// 参数多的时候 使用 map
@RequestMapping(value="/get",method = RequestMethod.GET)
public User get1(@RequestParam Map<String,Object> map);

6、Post 请求多参数

@RequestMapping(value="/post",method=RequestMethod.POST)
public User post(@RequestBody User user);

三、进阶知识

1、Feign 对压缩的支持

需要在 application.yml 中配置 feign.compression.request.enable = true 、feign.compression.response.enable = true

对于请求的压缩,Feign 还提供了更为详细的设置,例如:

feign:
	compression:
		request:
			enable: true
			mime-types: text/xml,application/xml,application/json
			min-request-size: 2048 
			

mime-types 代表请求类型

min-request-size 用于设置请求的最小阈值,默认是 2048

posted @ 2020-12-02 15:06  zolmk  阅读(89)  评论(0编辑  收藏  举报