本文为博主原创,转载请注明出处:

  spring cloud 服务组件之间通过feign 的方式请求,会携带很少的基础类型的消息头参数,比如Content-Type等,但不会携带自定义或指定的请求头参数,

在实际的开发过程中,需要对从网关或其他服务组件使用feign请求时,携带原始请求的请求头,并做一些基础校验和业务校验等。

  1.如果要在服务使用feign请求过程中,携带请求的原始请求头信息时,需要是请求处于同一个线程,这样才能在使用feign请求时,才能获取到当前请求的

原始请求头。在使用feignClient请求时,默认是会新建线程,去执行服务请求,如果新建线程,则会解析不到原始请求的请求头。需要对hystrix 进行一下的配置,

才能保证处于同一个线程当中。

hystrix默认使用多线程管理请求连接池,从主线程到发送基于hystrix的feign请求线程已不在同一个线程内。可通过设置策略区分是否为同一个线程。

  strategy: SEMAPHORE 基于信号量,前后会保持同一个线程。strategy: THREAD 基于异步线程,前后为不同的线程

hystrix:
command:
default:
execution:
timeout:
enabled: true
isolation:
strategy: SEMAPHORE
thread:
timeoutInMilliseconds: 60000

添加以上配置,可以对feignClient 进行消息头的配置,

  2.由于feign 请求底层是通过 RestTemplate 进行请求,Feign 支持请求拦截器,在发送请求前,可以对发送的模板进行操作,例如设置请求头等属性,

自定请求拦截器需要实现 feign.RequestInterceptor 接口,该接口的方法 apply 有参数 template ,该参数类型为 RequestTemplate,我们可以根据实际情况对请求信息进行调整,

对消息头的封装,可以使用拦截器进行一下的封装:

package com.imooc.homepage.config;
import feign.RequestInterceptor;
import feign.RequestTemplate;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes; import javax.servlet.http.HttpServletRequest;
import java.util.Enumeration; @Configuration
public class FeignConfiguration implements RequestInterceptor{
@Override
public void apply(RequestTemplate template) {
ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder
.getRequestAttributes();
HttpServletRequest request = attributes.getRequest();
// 对消息头进行配置
Enumeration<String> headerNames = request.getHeaderNames();
if (headerNames != null) {
while (headerNames.hasMoreElements()) {
String name = headerNames.nextElement();
String values = request.getHeader(name);
template.header(name, values);
}
}
// 对请求体进行配置
Enumeration<String> bodyNames = request.getParameterNames();
StringBuffer body =new StringBuffer();
if (bodyNames != null) {
while (bodyNames.hasMoreElements()) {
String name = bodyNames.nextElement();
String values = request.getParameter(name);
body.append(name).append("=").append(values).append("&");
}
}
if(body.length()!=0) {
body.deleteCharAt(body.length()-1);
template.body(body.toString());
}
} }

3.对FeignClient添加以上配置,进行请求:

@FeignClient(value = "client-homepage-course", fallback = CourseClientHystrix.class,configuration = FeignConfiguration.class)
public interface CourseClient { @RequestMapping(value = "/homepage-course/get/courses", method = RequestMethod.POST)
List<CourseInfo> getCourseInfos(@RequestBody CourseInfosRequest request);
}

  在服务中配置 FeignConfiguration 时,上面的代码示例是通过 RequestContextHolder.getRequestAttributes() 解析到当前请求头的参数,

RequestContextHolder是基于ThreadLocal实现的,所以需要保证请求是一直处于同一个线程当中,hystrix强大在于是支持此扩展操作的。

  另一种解决方案:由于所解析的模块没有添加spring-web相关的依赖配置,无法使用 RequestContextHolder ,使用 过滤器过滤出当前

线程中的请求头,并保存到ThreadLocal 中,在 FeignConfiguration 中解析 保存在ThreadLocal中的消息头参数,然后设置消息头给RestTemplate.

spring cloud 通过feign请求设置请求头的更多相关文章

  1. spring cloud 之 Feign 使用HTTP请求远程服务

    一.Feign 简介 在spring Cloud Netflix栈中,各个微服务都是以HTTP接口的形式暴露自身服务的,因此在调用远程服务时就必须使用HTTP客户端.我们可以使用JDK原生的URLCo ...

  2. spring cloud关于feign client的调用对象列表参数、设置header参数、多环境动态参数试配

    spring cloud关于feign client的调用 1.有些场景接口参数需要传对象列表参数 2.有些场景接口设置设置权限等约定header参数 3.有些场景虽然用的是feign调用,但并不会走 ...

  3. Spring Cloud 整合 Feign 的原理

    前言 在 上篇 介绍了 Feign 的核心实现原理,在文末也提到了会再介绍其和 Spring Cloud 的整合原理,Spring 具有很强的扩展性,会把一些常用的解决方案通过 starter 的方式 ...

  4. spring cloud 使用feign 遇到问题

    spring cloud 使用feign 项目的搭建 在这里就不写了,本文主要讲解在使用过程中遇到的问题以及解决办法 1:示例 @RequestMapping(value = "/gener ...

  5. spring cloud(四) feign

    spring cloud 使用feign进行服务间调用 1. 新建boot工程 pom引入依赖 <dependency> <groupId>org.springframewor ...

  6. 解决Spring Cloud中Feign第一次请求失败的问题

    在Spring Cloud中,Feign和Ribbon在整合了Hystrix后,可能会出现首次调用失败的问题 com.netflix.hystrix.exception.HystrixTimeoutE ...

  7. Spring Cloud中Feign如何统一设置验证token

    代码地址:https://github.com/hbbliyong/springcloud.git 原理是通过每个微服务请求之前都从认证服务获取认证之后的token,然后将token放入到请求头中带过 ...

  8. spring cloud 通过 ribbon 实现客户端请求的负载均衡(入门级)

    项目结构 环境: idea:2020.1 版 jdk:8 maven:3.6.2 1. 搭建项目 ( 1 )父工程:spring_cloud_demo_parent pom 文件 <?xml v ...

  9. spring cloud 通过zuul网关去请求的时候报404的几个原因。

    spring cloud 中 zuul 网关的那些坑: 1.检查你的服务是否正常启动. 2.检查你的服务是否正常注册到注册中心. 3.zuul网关的路由规则是会把你注册在注册中心的serviceId ...

  10. Spring Cloud之Feign客户端超时时间配置

    关于雪崩效应: 默认情况下tomcat只有一个线程去处理客户端发送的所有请求.高并发情况下,如果客户端请求都在同一接口,tomcat的所有线程池去处理,导致其他接口服务访问不了,等待. Tomcat有 ...

随机推荐

  1. 8、switch语句

    1.switch语句:"开关" switch是一个条件语句,它计算表达式并将其与可能匹配的列表进行比较,并根据匹配执行代码块.它可以被认为是一种惯用的方式来写多个if else子句 ...

  2. MySQL运维6-Mycat垂直分库

    一.垂直分库场景 场景:在业务系统中,涉及一下表结构,但是由于用户与订单每天都会产生大量的数据,单台服务器的数据存储以及处理能力是有限的,可以对数据库表进行拆分,原有数据库如下 说明1:整个业务系统中 ...

  3. Python给exe添加以管理员运行的属性

    需求 有些应用每次启动都需要用管理员权限运行,比如Python注入dll时,编辑器或cmd就需要以管理员权限运行,不然注入就会失败. 这篇文章用编程怎么修改配置实现打开某个软件都是使用管理员运行,就不 ...

  4. 【C#】【IO】【实例】统计多个文件夹下的图片

    因工作需要繁琐的进行同一目录多个文件夹下的图片统计,便使用代码来解决. 需求:统计的是多少个文件夹包含了图片,并非是统计有多少张图. 我们先用Python来创建一个现场环境(巩固巩固py知识): 1 ...

  5. 学透java自增(++)自减(--)运算符

    基本介绍 自增(++)和自减(--)运算符是对变量在原始值的基础上进行加1或减1的操作. 它们都有前缀和后缀两种形式. 前缀就是++在前面,后缀就是++在后面 前缀先自增(减),后缀后自增(减) 前缀 ...

  6. AutoGPT实战

    1.概述 人工智能(AI)的能力持续在全球范围内引起轰动,并对我们日常生活和职业生涯带来重大变革.随着像ChatGPT这样的先进生成型AI模型以及从GPT-3到GPT-4的加速,我们在高级推理.理解更 ...

  7. ElasticSearch之cat data frame analytics API

    命令样例如下: curl -X GET "https://localhost:9200/_cat/ml/data_frame/analytics?v=true&pretty" ...

  8. 【经典问题】mysql和redis数据一致性问题

    前言 MySQL和Redis数据一致性算是个很经典的问题,在之前也看到过很多相关的文章,最近心血来潮,想把一致性问题的解决方案和存在问题都总结一下. 不推荐方案 1 先更新MySQL,再更新Redis ...

  9. Python——第五章:Zipfile模块

    Zipfile模块 zipfile 模块是 Python 中用于处理 ZIP 文件的标准库模块.它提供了创建.读取和写入 ZIP 文件的功能. zipfile 模块在写入文件时,如果要将文件写入子目录 ...

  10. 毕业季 | 程序员初入职场必备软件开发神器,华为云Astro带你开启新篇章

    摘要:5分钟写出应用,10分钟开发大屏,新手程序员必学技能之华为云Astro,快来get. 本文分享自华为云社区<毕业季 | 程序员初入职场必备软件开发神器,华为云Astro带你开启新篇章> ...