springcloud通过feign请求设置请求头
本⽂为博主原创,转载请注明出处:
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.fig;
import feign.RequestInterceptor;
import feign.RequestTemplate;
import t.annotation.Configuration;
import org.t.request.RequestContextHolder;
import org.t.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 = Request();
// 对消息头进⾏配置
Enumeration<String> headerNames = HeaderNames();
if (headerNames != null) {
while (headerNames.hasMoreElements()) {
String name = Element();
String values = Header(name);
template.header(name, values);
}
}
// 对请求体进⾏配置
Enumeration<String> bodyNames = ParameterNames();
StringBuffer body =new StringBuffer();
if (bodyNames != null) {
while (bodyNames.hasMoreElements()) {
String name = Element();
String values = Parameter(name);
body.append(name).append("=").append(values).append("&");
}
}
if(body.length()!=0) {
body.deleteCharAt(body.length()-1);
template.String());
}
}
}
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 时,上⾯的代码⽰例是通过 RequestAttributes() 解析到当前请求头的参数,
RequestContextHolder是基于ThreadLocal实现的,所以需要保证请求是⼀直处于同⼀个线程当中,hystrix强⼤在于是⽀持此扩展操作的。 另⼀种解决⽅案:由于所解析的模块没有添加spring-web相关的
依赖配置,⽆法使⽤ RequestContextHolder ,使⽤过滤器过滤出当前线程中的请求头,并保存到ThreadLocal 中,在 FeignConfiguration 中解析保存在ThreadLocal中的消息头参数,然后设置消息头给RestTemplate.
spring framework组件
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。
发表评论