千家信息网

如何使用Feign动态设置header

发表于:2026-11-04 作者:千家信息网编辑
千家信息网最后更新 2026年11月04日,今天小编给大家分享一下如何使用Feign动态设置header的相关知识点,内容详细,逻辑清晰,相信大部分人都还太了解这方面的知识,所以分享这篇文章给大家参考一下,希望大家阅读完这篇文章后有所收获,下面
千家信息网最后更新 2026年11月04日如何使用Feign动态设置header

今天小编给大家分享一下如何使用Feign动态设置header的相关知识点,内容详细,逻辑清晰,相信大部分人都还太了解这方面的知识,所以分享这篇文章给大家参考一下,希望大家阅读完这篇文章后有所收获,下面我们一起来了解一下吧。

Feign动态设置header和原理

项目中用到了Feign做远程调用, 有部分场景需要动态配置header

开始的做法是通过 @RequestHeader 设置参数来实现动态的header配置

例如

@GetMapping(value = "/test", consumes = {MediaType.APPLICATION_JSON_UTF8_VALUE})    String access(@RequestHeader("Auth") String auth, @RequestBody Expression expression);

这种方式虽然可以达到header的动态配置, 但是当参数过多时会降低接口可用性, 所以想通过传递bean的方式来设置header

先说解决办法

public class HeaderInterceptor implements RequestInterceptor {    @Override    public void apply(RequestTemplate requestTemplate) {        byte[] bytes = requestTemplate.requestBody().asBytes();        Identity identity = JSONObject.parseObject(bytes, Identity.class);        requestTemplate.header("Auth", identity.getSecret());    }} /** * configuration指定Interceptor**/@FeignClient(name = "test", url = "127.0.0.1:8300", configuration = HeaderInterceptor.class)public interface GolangTestHandle2 {    @GetMapping(value = "/handler", consumes = {MediaType.APPLICATION_JSON_UTF8_VALUE})    String handle(Identity identity);}

自定义Interceptor实现RequestInterceptor接口, 回调方法apply提供了RequestTemplate对象, 对象内部封装了request的所有信息, 最后通过configuration指定接口, 之后就随便你怎么玩了(例如通过body获取接口参数并动态设置header)

值得注意的一点是HeaderInterceptor如果注入到Springboot容器的话会全局生效, 就是说及时没有指定configuration也会对全局feign接口生效, 为什么呢? 这里简单说明一下

首先Feign为每个feign class创建springcontext上下文

spring通过调用getObject获取feign工厂实例

    @Override    public Object getObject() throws Exception {        return getTarget();    }

内部调用FeignClientFatoryBean.getTarget()方法

 T getTarget() {        //获取feign上下文        FeignContext context = this.applicationContext.getBean(FeignContext.class);        //构建feign Builder        Feign.Builder builder = feign(context);        ...    }

根据feign(FeignContext context)构建Builder

protected Feign.Builder feign(FeignContext context) {        FeignLoggerFactory loggerFactory = get(context, FeignLoggerFactory.class);        Logger logger = loggerFactory.create(this.type);        // @formatter:off        Feign.Builder builder = get(context, Feign.Builder.class)                // required values                .logger(logger)                //默认springEncoder                .encoder(get(context, Encoder.class))                //默认OptionalDecoder                .decoder(get(context, Decoder.class))                //默认SpringMvcContrat                .contract(get(context, Contract.class));        // @formatter:on        //配置该feign的context        configureFeign(context, builder);        return builder;    }

在构建过程中通过FeignClientFactoryBean.configureUsingConfiguration为feign class注册基本的配置项, 其中也包括了Interceptor的注册

    protected void configureUsingConfiguration(FeignContext context,            Feign.Builder builder) {        Logger.Level level = getOptional(context, Logger.Level.class);        if (level != null) {            builder.logLevel(level);        }        Retryer retryer = getOptional(context, Retryer.class);        if (retryer != null) {            builder.retryer(retryer);        }        ErrorDecoder errorDecoder = getOptional(context, ErrorDecoder.class);        if (errorDecoder != null) {            builder.errorDecoder(errorDecoder);        }        Request.Options options = getOptional(context, Request.Options.class);        if (options != null) {            builder.options(options);        }        //从feign context获取interceptors        Map requestInterceptors = context                .getInstances(this.contextId, RequestInterceptor.class);        if (requestInterceptors != null) {            builder.requestInterceptors(requestInterceptors.values());        }        if (this.decode404) {            builder.decode404();        }    }

contextId为具体的feign class id, RequestInterceptor为具体的接口, 即是说通过context.getInstances获取所有RequestInterceptor实例并注册到builder中.

    public  Map getInstances(String name, Class type) {        AnnotationConfigApplicationContext context = getContext(name);        //使用beanNamesForTypeIncludingAncestors        if (BeanFactoryUtils.beanNamesForTypeIncludingAncestors(context,                type).length > 0) {            return BeanFactoryUtils.beansOfTypeIncludingAncestors(context, type);        }        return null;    }

获取工厂中的实例使用的是beanNamesForTypeIncludingAncestors方法, 该方法不仅会从feign的factory中查找, 也会通过父级别spring工厂查找相应实例(类似于springmvc的工厂)

也是因为该方法, 即使你没有在FeignClient中配置configuration, 但是你的Interceptor通过@Component等方法注入容器的话也会全局生效的, 所以如果指向让你的Interceptor部分生效不让它注入到Spring容器就好

设置Feign的header信息(两种形式)

在使用微服务SpringCloud全家桶组件Fegin的时候,我们在进行远程服务之间调用的同时,为了防止客户端劫持信息,我们需要将一些敏感信息添加到我们的Fegin头部(Header)当中,今天朋友问起,总结一下:那么工作中常见的方式有两种

1.在方法参数前面添加@RequestHeader注解

@PostMapping(value = "/getPersonDetail") public ServerResponse getPersonDetail(@RequestBody Map map,@RequestHeader(name = "id") String id);

使用@RequestHeader(name = "id")可以传递动态header属性

2.实现RequestInterceptor接口

设置Header(所有的Fegin请求)

import org.springframework.context.annotation.Configuration; import org.springframework.web.context.request.RequestContextHolder; import org.springframework.web.context.request.ServletRequestAttributes; import feign.RequestInterceptor; import feign.RequestTemplate; @Configuration public class FeignConfiguration implements RequestInterceptor {            @Override            public void apply(RequestTemplate template) {                      ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();                       HttpServletRequest request = attributes.getRequest();                        Enumeration headerNames = request.getHeaderNames();                        if (headerNames != null) {                                    while (headerNames.hasMoreElements()) {                                             String name = headerNames.nextElement();                                              String values = request.getHeader(name);                                             template.header(name, values);                                    }                            }            } }  @Component@FeignClient(value = "abc",fallback = abcServiceHystric.class ,configuration = FeignConfiguration.class) public interface AbcService { }

以上就是"如何使用Feign动态设置header"这篇文章的所有内容,感谢各位的阅读!相信大家阅读完这篇文章都有很大的收获,小编每天都会为大家更新不同的知识,如果还想学习更多的知识,请关注行业资讯频道。

动态 接口 方法 配置 信息 参数 实例 工厂 知识 篇文章 全局 容器 方式 上下 上下文 内容 对象 就是 部分 服务 数据库的安全要保护哪些东西 数据库安全各自的含义是什么 生产安全数据库录入 数据库的安全性及管理 数据库安全策略包含哪些 海淀数据库安全审计系统 建立农村房屋安全信息数据库 易用的数据库客户端支持安全管理 连接数据库失败ssl安全错误 数据库的锁怎样保障安全 互联网科技股 科技互联网企业 科技企业和互联网企业 互联网科技集团 云电互联网科技 互联网金融科技平台 四川狮子座互联网科技 中盈科技互联网信息有限公司 互联网为啥属于高科技 彤创互联网科技有限公司 世界互联网领先科技成果获奖 科技赋能视角下互联网保险发展 中国互联网有什么科技 互联网领先科技宣传片 互联网安防科技感 萌小萌互联网科技河南有限公司 美国五大互联网科技公司市值多少 玉溪新华互联网科技怎么选 互联网科技博主张洲 小牛互联网科技有限公司地址 广东万易互联网科技有限公司惠州分公司 互联网科技的英文 天津摩尔互联网科技 互联网科技logo设计 佰商互联网科技有限公司 中国航天科技大学国际工业互联网 企晟互联网信息科技有限公司 张家口科技产业互联网平台 科技互联网专业务虚会材料 上海旺乐尼互联网科技有限公司
0