首页 > 其他分享 >【Fegin技术专题】「原生态」打开Fegin之RPC技术的开端,你会使用原生态的Fegin吗?(高级用法)

【Fegin技术专题】「原生态」打开Fegin之RPC技术的开端,你会使用原生态的Fegin吗?(高级用法)

时间:2023-08-11 13:12:13浏览次数:38  
标签:Feign 原生态 String Fegin builder RPC new class 请求

推荐超值课程:点击获取

对于Httpclient请求机制进行设置操作处理。

@Body注解申明一个请求体模板,模板中可以带有参数,与方法中@Param注解申明的参数相匹配,使用方法如下:

interface LoginClient {

 void login( String user,  String password);
}
...

client.login("denominator", "secret");

复制代码

Feign支持给请求的api设置或者请求的客户端设置请求头,如下:


interface BaseApi {

  void put( String, V value);
}
复制代码

void post( String token);
复制代码

设置key和value都是动态的请求头

可以使用 @HeaderMap 注解,如下:


void post( Map headerMap);
复制代码

给Target设置请求头

有时我们需要在一个API实现中根据不同的endpoint来传入不同的Header,这个时候我们可以使用自定义的RequestInterceptor 或 Target来实现.

通过自定义的 RequestInterceptor 来实现请查看 Request Interceptors

下面是一个通过自定义Target来实现给每个Target设置安全校验信息Header的例子:

static class DynamicAuthTokenTarget implements Target {
 public DynamicAuthTokenTarget(Class clazz,
                UrlAndTokenProvider provider,
                ThreadLocal requestIdProvider);
 ...

 public Request apply(RequestTemplate input) {
  TokenIdAndPublicURL urlAndToken = provider.get();
  if (input.url().indexOf("http") != 0) {
   input.insert(0, urlAndToken.publicURL);
  }
  input.header("X-Auth-Token", urlAndToken.tokenId);
  input.header("X-Request-ID", requestIdProvider.get());
  return input.request();
 }
}
...

Bank bank = Feign.builder()
    .target(new DynamicAuthTokenTarget(Bank.class, provider, requestIdProvider));
复制代码
  • 这种方法的实现依赖于给Feign 客户端设置的自定义的RequestInterceptor 或 Target。可以被用来给一个客户端的所有api请求设置请求头。比如说可是被用来在header中设置身份校验信息。这些方法是在线程执行api请求的时候才会执行,所以是允许在运行时根据上下文来动态设置header的。
  • 比如说可以根据线程本地存储(thread-local storage)来为不同的线程设置不同的请求头。

有些请求中的一些方法是通用的,但是可能会有不同的参数类型或者返回类型,这个时候可以这么用:


interface BaseAPI {

  String health();

  List all();
}

interface CustomAPI extends BaseAPI {

 String custom();
}

interface BaseApi {

 V get( String key);

 List list();

 void put( String key, V value);
}

interface FooApi extends BaseApi { }
interface BarApi extends BaseApi { }

复制代码

你可以通过设置一个 Logger 来记录http消息,如下:

GitHub github = Feign.builder()
decoder(new GsonDecoder())
           .logger(new Logger.JavaLogger().appendToFile("logs/http.log"))
           .logLevel(Logger.Level.FULL)
           .target(GitHub.class, https:
复制代码

当你希望修改所有的的请求的时候,你可以使用Request Interceptors。比如说,你作为一个中介,你可能需要为每个请求设置 X-Forwarded-For

static class ForwardedForInterceptor implements RequestInterceptor {
  public void apply(RequestTemplate template) {
    template.header("X-Forwarded-For", "origin.host.com");
  }
}
...

Bank bank = Feign.builder()
         .decoder(accountDecoder)
         .requestInterceptor(new ForwardedForInterceptor())
         .target(Bank.class, https:
复制代码

或者,你可能需要实现Basic Auth,这里有一个内置的基础校验拦截器

BasicAuthRequestInterceptor
Bank bank = Feign.builder()
         .decoder(accountDecoder)
         .requestInterceptor(new BasicAuthRequestInterceptor(username, password))
         .target(Bank.class, https:
复制代码

@Param 注解给模板中的参数设值的时候,默认的是使用的对象的 toString() 方法的值,通过声明 自定义的Param.Expander,用户可以控制其行为,比如说格式化 Date 类型的值:


Result list( Date date);
复制代码

动态查询参数支持,通过使用 @QueryMap 可以允许动态传入请求参数,如下:


V find( Map queryMap);
复制代码

原生Feign只能一次解析一个接口,生成对应的请求代理对象,如果一个包里有多个调用接口就要多次解析非常麻烦。

自定义注解:在扫描接口的过程中,可以通过一个自定义注解,来区分Feign接口并且指定调用的服务Url


public class FeignClientRegister implements BeanFactoryPostProcessor{

    public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) {
        List classes = scan(scanPath);
        if(classes==null){
            return ;
        }
        Feign.Builder builder = getFeignBuilder();
        if(classes.size()>0){
            for (String claz : classes) {
                Class targetClass = null;
                try {
                    targetClass = Class.forName(claz);
                    String url=targetClass.getAnnotation(FeignApi.class).serviceUrl();
                    if(url.indexOf("http://")!=0){
                        url="http://"+url;
                    }
                    Object target = builder.target(targetClass, url);
                    beanFactory.registerSingleton(targetClass.getName(), target);
                } catch (Exception e) {
                    throw new RuntimeException(e.getMessage());
                }
            }
        }
    }
    public Feign.Builder getFeignBuilder(){
        Feign.Builder builder = Feign.builder()
                .encoder(new JacksonEncoder())
                .decoder(new JacksonDecoder())
                .options(new Request.Options(1000, 3500))
                .retryer(new Retryer.Default(5000, 5000, 3));
        return builder;
    }
    public List scan(String path){
        ScanResult result = new FastClasspathScanner(path).matchClassesWithAnnotation(FeignApi.class, (Class aClass) -> {
        }).scan();
        if(result!=null){
            return result.getNamesOfAllInterfaceClasses();
        }
        return  null;
    }
}
复制代码

分享资源

资源分享
扫码关注发送:资源 获取以上资源
字节技术

标签:Feign,原生态,String,Fegin,builder,RPC,new,class,请求
From: https://www.cnblogs.com/3shu/p/17622727.html

相关文章

  • 【Fegin技术专题】「原生态」从源码层面让你认识Feign工作流程和运作机制
    推荐超值课程:点击获取Feign简介介绍什么是feign:一款基于注解和动态代理的声明式restfulhttp客户端。原理Feign发送请求实现原理微服务启动类上标记@EnableFeignClients注解,然后Feign接口上标记@FeignClient注解。@FeignClient注解有几个参数需要配置,这里不再赘述,都很简单......
  • 【Archaius技术专题】「Netflix原生态」动态化配置服务之微服务配置组件变色龙
    推荐超值课程:点击获取前提介绍如果要设计开发一套微服务基础架构,参数化配置是一个非常重要的点,而Netflix也开源了一个叫变色龙Archaius的配置中心客户端,而且Archaius可以说是比其他客户端具备更多生产级特性,也更灵活。*在NetflixOSS微服务技术栈中,几乎所有的其它组件(例如Zuul......
  • .Net Core gRpc调用
    目录简介创建gRPC创建服务端创建控制台测试创建自定义服务服务器流式处理方法custom.protoCustomGreeterService.csgRpcRequest.cs客户端流式处理方法custom.protoCustomGreeterService.csgRpcRequest.cs双向流式处理方法custom.protoCustomGreeterService.csgRpcRequest.cs.Net......
  • 【Fegin技术专题】「原生态」打开Fegin之RPC技术的开端,你会使用原生态的Fegin吗?(上)
    推荐超值课程:点击获取前提介绍Feign是SpringCloud中服务消费端的调用框架,通常与ribbon,hystrix等组合使用。由于遗留原因,某些项目中,整个系统并不是SpringCloud项目,甚至不是Spring项目,而使用者关注的重点仅仅是简化http调用代码的编写。*如果采用httpclient或者okhttp这样相对......
  • 【Fegin技术专题】「原生态」打开Fegin之RPC技术的开端,你会使用原生态的Fegin吗?(中)
    推荐超值课程:点击获取你可以使用Jersey和CXF这些来写一个Rest或SOAP服务的java客服端。你也可以直接使用ApacheHttpClient来实现。但是Feign的目的是尽量的减少资源和代码来实现和HTTPAPI的连接。*通过自定义的编码解码器以及错误处理,你可以编写任何基于......
  • gRPC Test
    目录简单使用ghzgithub:https://github.com/bojand/ghzghz官方文档:https://ghz.sh/简单使用下载后解压,将目录配置到path上,方便命令调用:ghz--insecure--protoxxx\Hello.proto--callpackage_name.service_name.rpc_method_name-d"{\"name\":\"a\"}"localho......
  • 如何通过gRPC传输文件
    在gRPC中,可以通过将文件分割成多个小块,然后使用流式RPC将这些小块发送到服务器来传输文件。以下是一个简单的示例,展示了如何在gRPC中实现文件传输。首先,我们需要定义一个服务来处理文件传输。在.proto文件中,我们可以定义一个UploadFile服务,它接收一个流式的Chunk消息,并返回一个Up......
  • gRPC的测试
    gRPC(Googleremoteprocedurecall)远程过程调用,使不同服务在不同机器上互相调用就像调本地一样方便但调用方和服务方对应开发不是一个人,出现问题,没法确认是哪方的问题,因此,可以使用BloomRPC工具测试rpc服务是否正常 1、测试工具:BloomRPC,下载地址 https://github.com/uw-labs/......
  • Python中实现远程调用(RPC、RMI)简单例子
    远程调用使得调用远程服务器的对象、方法的方式就和调用本地对象、方法的方式差不多,因为我们通过网络编程把这些都隐藏起来了。远程调用是分布式系统的基础。远程调用一般分为两种,远程过程调用(RPC)和远程方法调用(RMI)。RPCRPC属于函数级别的远程调用,其多是通过HTTP传输数据,数据形式有......
  • docker 中使用 pywpsrpc
    一般如果使用带桌面环境的docker,比如dorowu/ubuntu-desktop-lxde-vnc,然后安装wps后,使用https://github.com/timxx/pywpsrpc是没啥问题的,需要注意的是wps第一次打开后,需要同意EULA,然后按照https://github.com/timxx/pywpsrpc/issues/44#issuecomment-1032304847中提到的......