您的位置:首页 > 编程语言 > Java开发

springcloud(第八篇)springcloud feign

2016-05-21 13:28 615 查看
# spring cloud feign

introduction

netflix feign
是一个类似
retrofit
进行http调用框架,
Feign makes writing java http clients easier
使得编写
http client
代码更加简单

netflix feign

直接给出一段简单的案例

package com.lkl.netflix.feign;

import feign.*;
import feign.codec.ErrorDecoder;
import feign.codec.Decoder;
import feign.gson.GsonDecoder;

import java.io.IOException;
import java.util.List;

/**
* Created by liaokailin on 16/5/9.
*/
public class GitHubExample {

interface GitHub {  // 1
@RequestLine("GET /repos/{owner}/{repo}/contributors")
List<Contributor> contributors(@Param("owner") String owner, @Param("repo") String repo);
}

public static void main(String... args) {
Decoder decoder = new GsonDecoder();  // 2
GitHub github = Feign.builder()
.decoder(decoder) // 3
.errorDecoder(new GitHubErrorDecoder(decoder))  // 4
.logger(new Logger.ErrorLogger())  // 5
.logLevel(Logger.Level.BASIC)  // 5
.target(GitHub.class, "https://api.github.com");  // 6

System.out.println("Let's fetch and print a list of the contributors to this library.");
List<Contributor> contributors = github.contributors("netflix", "feign");  // 7
for (Contributor contributor : contributors) {
System.out.println(contributor.login + " (" + contributor.contributions + ")");
}

System.out.println("Now, let's cause an error.");
try {
github.contributors("netflix", "some-unknown-project");  // 8
} catch (GitHubClientError e) {
System.out.println(e.getMessage());
}
}

static class Contributor {
String login;
int contributions;
}

static class GitHubClientError extends RuntimeException {  // 4
private String message; // parsed from json

@Override
public String getMessage() {
return message;
}
}

static class GitHubErrorDecoder implements ErrorDecoder {   // 4

final Decoder decoder;
final ErrorDecoder defaultDecoder = new ErrorDecoder.Default();

GitHubErrorDecoder(Decoder decoder) {
this.decoder = decoder;
}

@Override
public Exception decode(String methodKey, Response response) {
try {
return (Exception) decoder.decode(response, GitHubClientError.class);
} catch (IOException fallbackToDefault) {
return defaultDecoder.decode(methodKey, response);
}
}
}

}


1.首先定义接口
GitHub
,使用注解
RequestLine
表明
contributors()
方法为一个
get
请求,请求相对为
/repos/{owner}/{repo}/contributors


2.
Decoder decoder = new GsonDecoder();
创建一个
GsonDecoder
解码器,表明通过
Gson
解析返回数据

3.
decoder()
方法设置解码器

4.
errorDecoder()
指定发生异常时的解码器,需要实现
ErrorDecoder
接口,覆写
decode
方法,通过指定的
Decoder
解析错误信息,这里还是使用
GsonDecoder


5.logger 相关的表示配置日志系你系

6.
target()
方法指定访问url以及返回的类型

7.通过创建的
github
对象调用
contributors
获取结果

8.模拟异常情况

note:
feign
使用起来很简单,其原理和
retrofit
及其类似,通过接口定义访问访问,用jdk的动态代理创建接口的实现类,在类中解析方法上的注解信息用以识别用户配置的http请求信息,然后执行请求;

feign可以通过
ReflectiveFeign
下的
newInstance()
方法看到

return (T) Proxy
.newProxyInstance(target.type().getClassLoader(), new Class<?>[]{target.type()}, handler);


spring cloud feign

spring cloud feign
通过注解的封装使用起来更加简单

package com.lkl.springcloud.feign;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
import org.springframework.cloud.netflix.feign.EnableFeignClients;
import org.springframework.cloud.netflix.feign.FeignClient;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;

import java.util.List;

/**
* Created by liaokailin on 16/5/11.
*/
@Configuration
@EnableAutoConfiguration
@EnableFeignClients
@RestController
public class Application {

@Autowired
GitHub gitHub;
public static void main(String[] args) {
SpringApplication.run(Application.class, args);
}

@FeignClient(url = "https://api.github.com")
interface GitHub {
@RequestMapping(value = "/repos/{owner}/{repo}/contributors", method = RequestMethod.GET)
ResponseEntity<List<Contributor>> contributors(@PathVariable("owner") String owner, @PathVariable("repo") String repo);
}

@RequestMapping("/")
public void test(){
ResponseEntity< List<Contributor>>  responseEntity  =   gitHub.contributors("netflix", "feign");
List<Contributor> contributors = responseEntity.getBody();
for (Contributor contributor : contributors) {
System.out.println(contributor.login + " (" + contributor.contributions + ")");
}
}

static class Contributor {
String login;
int contributions;
}
}


注解
EnableFeignClients
表明需要扫描使用
FeignClient
注解的接口,在代码中定义了
@FeignClient(url = "https://api.github.com")
表明该接口为一个feign接口

通过
url
指定访问路径
RequestMapping
表明相对路径

在代码中注入bean
GitHub
,直接调用其中申明的方法即可。

重点说明下
FeignClient
注解

该注解表示申明创建一个rest client bean,可以直接通过
Autowired
注入使用,如果ribbon在工程中启用,则会使用
load balance
进行后端请求调用,可以为
FeignClient
指定value表明需要访问的serviceId

feign + ribbon + eureka

springcloud(第七篇)springcloud ribbon with eureka中讲解了ribbon+eureka,其中使用
RestTemplate
进行调用,也可以通过

feign
调用

package com.lkl.springcloud.feign;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
import org.springframework.cloud.netflix.feign.EnableFeignClients;
import org.springframework.cloud.netflix.feign.FeignClient;
import org.springframework.cloud.netflix.ribbon.RibbonClient;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import static org.springframework.web.bind.annotation.RequestMethod.GET;

/**
* Created by liaokailin on 16/5/9.
*/
@SpringBootApplication
@EnableDiscoveryClient
@RestController
@RibbonClient("hello")
@EnableFeignClients
public class Application {

@Autowired
HelloClient client;

@RequestMapping("/")
public String hello() {
return client.hello();
}

public static void main(String[] args) {
SpringApplication.run(Application.class, args);
}

@FeignClient("simple")
interface HelloClient {
@RequestMapping(value = "/", method = GET)
String hello();
}

}


使用
@FeignClient("simple")
指定要访问的
service id
由于
hello()
对应的mapping为
@RequestMapping(value = "/", method = GET)
那么该方法实际调用url为

http://simple/
,因此在执行

@RequestMapping("/")
public String hello() {
return client.hello();
}


调用的为
SimpleApplication.java


@RequestMapping("/")
public String hello() {
return "Hello";
}


ok ~ it’s work ! more about is here
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: