Feign的简单实践

public class UrlService {
    public static final String SERVER_URL = "http://localhost:8080/";
}

Hello World

public interface HelloClient {
    @RequestLine("GET /hello")
    String sayHello();
}
HelloClient hello = Feign.builder()
        .target(HelloClient.class, UrlService.SERVER_URL);

编码器和解码器 encoder decoder

public interface PersonClient {

    @RequestLine("GET /person/{personId}")
    Person findById(@Param("personId") Integer personId);

    @RequestLine("POST /person/create")
    @Headers("Content-Type: application/json")
    String createPerson(Person person);
}
PersonClient personService = Feign.builder()
    .decoder(new GsonDecoder())
    .encoder(new GsonEncoder())
    .target(PersonClient.class, UrlService.SERVER_URL);
  • 自定义编码器
import feign.codec.Decoder;

public class PersonDecoder implements Decoder {
    public Object decode(Response response, Type type) throws IOException, DecodeException, FeignException {
        // ...
    }
}
PersonClient personService = Feign.builder()
    //.decoder(new GsonDecoder())
    .decoder(new PersonDecoder())
    .target(PersonClient.class, UrlService.SERVER_URL);

客户端 client

feign默认使用HttpClient客户端发送请求。

可以使用其他客户端

PersonClient personClient = Feign.builder()
        .decoder(new GsonDecoder())
        .client(new OkHttpClient())
        .target(PersonClient.class, UrlService.SERVER_URL);

也可以自定义客户端

import feign.Client;
import feign.Request;
import feign.Response;
import org.apache.http.HttpResponse;
import org.apache.http.client.methods.HttpRequestBase;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.util.EntityUtils;

import java.io.IOException;
import java.net.URI;
import java.util.Collection;
import java.util.HashMap;

public class MyFeignClient implements Client {

    /**
     * 将Feign的Request实例,转换为HttpClient的HttpRequestBase,再使用CloseableHttpClient来执行请求;
     * 得到响应的HttpResponse实例后,再转换为Feign的Reponse实例返回。
     */
    @Override
    public Response execute(Request request, Request.Options options) throws IOException {
        try {
            // 创建一个默认的客户端
            CloseableHttpClient httpclient = HttpClients.createDefault();
            // 获取调用的HTTP方法
            final String method = request.httpMethod().name();

            // 创建一个HttpClient的HttpRequest
            HttpRequestBase httpRequest = new HttpRequestBase() {
                @Override
                public String getMethod() {
                    return method;
                }
            };

            // 设置请求地址
            httpRequest.setURI(new URI(request.url()));
            // 执行请求,获取响应
            HttpResponse httpResponse = httpclient.execute(httpRequest);
            // 获取响应的主体内容
            byte[] body = EntityUtils.toByteArray(httpResponse.getEntity());
            // 将HttpClient的响应对象转换为Feign的Response
            Response response = Response.builder()
                    .body(body)
                    .headers(new HashMap<String, Collection<String>>())
                    .status(httpResponse.getStatusLine().getStatusCode())
                    .request(request)
                    .build();
            return response;
        } catch (Exception e) {
            throw new IOException(e);
        }
    }
}

PersonClient personClient = Feign.builder()
        .decoder(new GsonDecoder())
        .client(new MyFeignClient())
        .target(PersonClient.class, UrlService.SERVER_URL);

注解翻译器 contract

import javax.ws.rs.GET;
import javax.ws.rs.Path;

public interface JaxRsClient {
    @GET
    @Path("/hello")
    String rsHello();
}
JaxRsClient rsClient = Feign.builder()
        .contract(new JAXRSContract())
        .target(JaxRsClient.class, UrlService.SERVER_URL);

自定义注解翻译器

@Target(METHOD)
@Retention(RUNTIME)
public @interface MyUrl {

    // 定义url与method属性
    String url();

    String method();
}
import feign.Contract;
import feign.MethodMetadata;
import feign.Request;
import morning.cat.annotation.MyUrl;

import java.lang.annotation.Annotation;
import java.lang.reflect.Method;

/**
 * 一个Contract实际上承担的是一个翻译的作用,将第三方(或者自定义)注解的作用告诉Feign。
 * 在Spring Cloud中,也实现了Spring的Contract,可以在接口中使用@RequestMapping注解,读者在学习Spring Cloud整合Feign时,见到使用@RequestMapping修饰的接口,就可以明白其中的原理。
 */
public class MyContract extends Contract.BaseContract {

    @Override
    protected void processAnnotationOnClass(MethodMetadata data, Class<?> clz) {

    }

    /**
     * 用于处理方法级的注解
     */
    @Override
    protected void processAnnotationOnMethod(MethodMetadata data,
                                             Annotation annotation, Method method) {
        // 是MyUrl注解才进行处理
        if (MyUrl.class.isInstance(annotation)) {
            // 获取注解的实例
            MyUrl myUrlAnn = method.getAnnotation(MyUrl.class);
            // 获取配置的HTTP方法
            String httpMethod = myUrlAnn.method();
            // 获取服务的url
            String url = myUrlAnn.url();
            // 将值设置到模板中
            data.template().method(Request.HttpMethod.valueOf(httpMethod));
            data.template().uri(url);
        }
    }

    @Override
    protected boolean processAnnotationsOnParameter(MethodMetadata data,
                                                    Annotation[] annotations, int paramIndex) {
        return false;
    }
}
MyUrlClient client = Feign.builder()
    .contract(new MyContract())
    .target(MyUrlClient.class, UrlService.SERVER_URL);

依赖

<dependency>
            <groupId>io.github.openfeign</groupId>
            <artifactId>feign-core</artifactId>
            <version>${feign.version}</version>
        </dependency>

        <dependency>
            <groupId>io.github.openfeign</groupId>
            <artifactId>feign-gson</artifactId>
            <version>${feign.version}</version>
        </dependency>

        <!-- Feign对JAXRS的支持 -->
        <dependency>
            <groupId>io.github.openfeign</groupId>
            <artifactId>feign-jaxrs</artifactId>
            <version>${feign.version}</version>
        </dependency>

        <!-- https://mvnrepository.com/artifact/io.github.openfeign/feign-okhttp -->
        <dependency>
            <groupId>io.github.openfeign</groupId>
            <artifactId>feign-okhttp</artifactId>
            <version>${feign.version}</version>
        </dependency>

        <!-- https://mvnrepository.com/artifact/io.github.openfeign/feign-httpclient -->
        <dependency>
            <groupId>io.github.openfeign</groupId>
            <artifactId>feign-httpclient</artifactId>
            <version>${feign.version}</version>
        </dependency>


        <!-- JAXRS -->
        <dependency>
            <groupId>javax.ws.rs</groupId>
            <artifactId>jsr311-api</artifactId>
            <version>1.1.1</version>
        </dependency>

        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <version>1.18.8</version>
            <scope>provided</scope>
        </dependency>


        <dependency>
            <groupId>org.apache.httpcomponents</groupId>
            <artifactId>httpclient</artifactId>
            <version>4.5.2</version>
        </dependency>
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值