Feign的理解和使用

1 简单说明

简单的说, Feign是一个用于请求http接口的框架, 再java中可以用少量代码, 简单整洁的调用http.

2 使用例子

maven依赖

<!-- feign-core -->
<dependency>
    <groupId>io.github.openfeign</groupId>
    <artifactId>feign-core</artifactId>
    <version>11.0</version>
</dependency>
<!-- jackson编码和解码器 -->
<dependency>
    <groupId>io.github.openfeign</groupId>
    <artifactId>feign-jackson</artifactId>
    <version>11.0</version>
</dependency>

直接从原生feign-core出发, 快速实现一个最简单的接口请求例子

// 写一个接口
public interface TargetTest {
    @RequestLine("POST cluster/asd")
    Map<String, Object> asd();
}

// 测试
void sample() {
	Feign.Builder builder = Feign.builder();
	TargetTest test = builder
			.decoder(new JacksonDecoder())
			.target(TargetTest.class, "http://localhost:8222/api/k8s");
	System.out.println(test.asd());
}

3 自定义使用feign

3.1 Encoder和Decoder

上面例子使用的解码器是feign基于FasterXML/Jackson的解码器, 解码器的使用是根据想要请求的接口返回的格式所决定的, 上面例子的接口返回的是json格式的数据, 所以可以使用JacksonDecoder解析, feign还有其他的编码器, 比如

<!-- gson,json解析 -->
<dependency>
    <groupId>io.github.openfeign</groupId>
    <artifactId>feign-gson</artifactId>
    <version>11.0</version>
</dependency>

<!-- jaxb,xml解析 -->
<dependency>
    <groupId>io.github.openfeign</groupId>
    <artifactId>feign-jaxb</artifactId>
    <version>11.0</version>
</dependency>

当然也可以自定义的实现,类似JacksonDecoder实现Decoder, 实现decode方法

public class JacksonDecoder implements Decoder {
    private final ObjectMapper mapper;

    public JacksonDecoder() {
        this((Iterable)Collections.emptyList());
    }

    public JacksonDecoder(Iterable<Module> modules) {
        this((new ObjectMapper()).configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false).registerModules(modules));
    }

    public JacksonDecoder(ObjectMapper mapper) {
        this.mapper = mapper;
    }

    public Object decode(Response response, Type type) throws IOException {
        if (response.body() == null) {
            return null;
        } else {
            Reader reader = response.body().asReader(Util.UTF_8);
            if (!((Reader)reader).markSupported()) {
                reader = new BufferedReader((Reader)reader, 1);
            }

            try {
                ((Reader)reader).mark(1);
                if (((Reader)reader).read() == -1) {
                    return null;
                } else {
                    ((Reader)reader).reset();
                    return this.mapper.readValue((Reader)reader, this.mapper.constructType(type));
                }
            } catch (RuntimeJsonMappingException var5) {
                if (var5.getCause() != null && var5.getCause() instanceof IOException) {
                    throw (IOException)IOException.class.cast(var5.getCause());
                } else {
                    throw var5;
                }
            }
        }
    }
}

3.2 logger配置

maven依赖

<dependency>
    <groupId>io.github.openfeign</groupId>
    <artifactId>feign-slf4j</artifactId>
    <version>11.0</version>
</dependency>

application.properties

logging.level.root=info
logging.level.feign.Logger=debug

代码

// 写一个接口
public interface TargetTest {
    @RequestLine("POST cluster/asd")
    Map<String, Object> asd();
}

// 测试
void sample() {
	Feign.Builder builder = Feign.builder();
	TargetTest test = builder
			.encoder(new JacksonEncoder())
			.decoder(new JacksonDecoder())
			.logLevel(Logger.Level.FULL)// NONE,BASIC,HEADERS,FULL
			.logger(new Slf4jLogger())
			.target(TargetTest.class, "http://localhost:8222/api/k8s");
	System.out.println(test.asd());
}

输出例子

3.3 重试机制retryer

// 写一个接口
public interface TargetTest {
    @RequestLine("POST cluster/asd")
    Map<String, Object> asd();
}

// 测试
void sample() {
	Feign.Builder builder = Feign.builder();
	TargetTest test = builder
			.encoder(new JacksonEncoder())
			.decoder(new JacksonDecoder())
			.logLevel(Logger.Level.FULL)
			.logger(new Slf4jLogger())
            // 重试间隔,最大间隔,最大重试次数,(默认的重试间隔是根据一定算法变化的)
			.retryer(new Retryer.Default(1000L, TimeUnit.SECONDS.toMillis(10L), 10))
			.target(TargetTest.class, "http://localhost:8222/api/k8s");
	System.out.println(test.asd());
}

3.4 target

target是指定接口类并指定url,也可以不指定url并用(Target.EmptyTarget.create) , 不过要在调用接口方法的时候传入一个URI

之前的例子是指定接口类并指定url, 下面使用Target.EmptyTarget.create方式

// 写一个接口
public interface TargetTest2 {
    @RequestLine("GET /cluster/calcite/test")
    Map<String, Object> get(URI baseUrl);
}

void emptyTargetTest() {
	TargetTest2 test = Feign.builder()
			.decoder(new GsonDecoder())
			.target(Target.EmptyTarget.create(TargetTest2.class));
	Map<String, Object> test2 = test.get(URI.create("http://localhost:8222/api/k8s"));
	System.out.println(test2);
}

3.5 参数的传递

@QueryMap

// 写一个接口
public interface TargetTest2 {
    @RequestLine("GET /cluster/calcite/test")
    Map<String, Object> get(@QueryMap Map<String, Object> queryMap);
}

void emptyTargetTest() {
	TargetTest2 test = Feign.builder()
			.decoder(new GsonDecoder())
			.target(Target.EmptyTarget.create(TargetTest2.class));
	Map<String,Object> query = new HashMap<>();
	query.put("page",1);
	query.put("page_size",4);
	Map<String, Object> test2 = test.get(URI.create("http://localhost:8222/api/k8s"), query);
	System.out.println(test2);
}

@HeaderMap

@Headers("Content-Type: application/json")
public interface TargetTest2 {
    @Headers("Content-Type: application/json")
	@RequestLine("GET /cluster/calcite/test")
    HystrixCommand<HttpJsonResponse> get(@Param("url") String url, @HeaderMap Map<String, String> headerMap, @QueryMap Map<String, Object> request);
}

等等.上面都是一些很简单的应用,是参考下面的文章记录的

https://www.cnblogs.com/chenkeyu/p/9017996.html

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值